Merge remote-tracking branch 'citadel/master' into typing_indicators
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
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
density = FALSE
|
||||
stat = DEAD
|
||||
canmove = FALSE
|
||||
|
||||
var/mob/living/new_character //for instant transfer once the round is set up
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -71,6 +71,9 @@
|
||||
|
||||
//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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,9 +11,10 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
layer = GHOST_LAYER
|
||||
stat = DEAD
|
||||
density = FALSE
|
||||
canmove = 0
|
||||
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)
|
||||
@@ -289,9 +292,10 @@ 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)
|
||||
return
|
||||
@@ -324,9 +328,10 @@ 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
|
||||
|
||||
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")
|
||||
@@ -648,6 +653,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)
|
||||
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
|
||||
|
||||
@@ -39,12 +39,8 @@
|
||||
container = null
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha))
|
||||
canmove = 1
|
||||
else
|
||||
canmove = 0
|
||||
return canmove
|
||||
/mob/living/brain/update_mobility()
|
||||
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
|
||||
|
||||
@@ -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,12 +21,12 @@ In all, this is a lot like the monkey code. /N
|
||||
return
|
||||
switch(M.a_intent)
|
||||
if (INTENT_HELP)
|
||||
if(!recoveringstam)
|
||||
resting = 0
|
||||
AdjustStun(-60)
|
||||
AdjustKnockdown(-60)
|
||||
AdjustUnconscious(-60)
|
||||
AdjustSleeping(-100)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
set_resting(FALSE, TRUE, FALSE)
|
||||
AdjustAllImmobility(-60, FALSE)
|
||||
AdjustUnconscious(-60, FALSE)
|
||||
AdjustSleeping(-100, FALSE)
|
||||
update_mobility()
|
||||
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
|
||||
if(INTENT_DISARM, INTENT_HARM)
|
||||
if(health > 0)
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
/mob/living/carbon/alien/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) //alien immune to tox damage
|
||||
return FALSE
|
||||
|
||||
/* CIT CHANGE - Pffffffffffffhahahahahhaha-- No.
|
||||
//aliens are immune to stamina damage.
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_health = 1)
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_health = 1)
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#define MAX_ALIEN_LEAP_DIST 7
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A)
|
||||
if(!canmove || leaping)
|
||||
if(!CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND | MOBILITY_MOVE) || leaping)
|
||||
return
|
||||
|
||||
if(pounce_cooldown > world.time)
|
||||
@@ -65,21 +65,21 @@
|
||||
var/mob/living/L = hit_atom
|
||||
if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
else
|
||||
Knockdown(40, 1, 1)
|
||||
DefaultCombatKnockdown(40, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
else if(hit_atom.density && !hit_atom.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [hit_atom]!</span>", "<span class ='alertalien'>[src] smashes into [hit_atom]!</span>")
|
||||
Knockdown(40, 1, 1)
|
||||
Paralyze(40, TRUE, TRUE)
|
||||
|
||||
if(leaping)
|
||||
leaping = 0
|
||||
update_icons()
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/float(on)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
. = ..()
|
||||
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
update_icons()
|
||||
status_flags |= CANPUSH
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
..(I, cuff_break = INSTANT_CUFFBREAK)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/resist_grab(moving_resist)
|
||||
if(pulledby.grab_state)
|
||||
/mob/living/carbon/alien/humanoid/do_resist_grab(moving_resist, forced, silent = FALSE)
|
||||
if(pulledby.grab_state && !silent)
|
||||
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
|
||||
pulledby.stop_pulling()
|
||||
. = 0
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
|
||||
if(leaping)
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
else
|
||||
icon_state = "alien[caste]_dead"
|
||||
|
||||
else if((stat == UNCONSCIOUS && !asleep) || stat == SOFT_CRIT || IsKnockdown())
|
||||
else if((stat == UNCONSCIOUS && !asleep) || stat == SOFT_CRIT || IsParalyzed())
|
||||
icon_state = "alien[caste]_unconscious"
|
||||
else if(leap_on_click)
|
||||
icon_state = "alien[caste]_pounce"
|
||||
|
||||
else if(lying || resting || asleep)
|
||||
else if(lying || !CHECK_MOBILITY(src, MOBILITY_STAND) || asleep)
|
||||
icon_state = "alien[caste]_sleep"
|
||||
else if(mob_size == MOB_SIZE_LARGE)
|
||||
icon_state = "alien[caste]"
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || health <= crit_threshold)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
update_canmove()
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
update_mobility()
|
||||
else
|
||||
if(stat == UNCONSCIOUS)
|
||||
stat = CONSCIOUS
|
||||
if(!recoveringstam)
|
||||
resting = 0
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
set_resting(FALSE, TRUE)
|
||||
adjust_blindness(-1)
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
update_damage_hud()
|
||||
update_health_hud()
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
icon_state = "larva[state]_dead"
|
||||
else if(handcuffed || legcuffed) //This should be an overlay. Who made this an icon_state?
|
||||
icon_state = "larva[state]_cuff"
|
||||
else if(stat == UNCONSCIOUS || lying || resting)
|
||||
else if(stat == UNCONSCIOUS || !CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
icon_state = "larva[state]_sleep"
|
||||
else if(IsStun())
|
||||
else if(IsStun() || IsParalyzed())
|
||||
icon_state = "larva[state]_stun"
|
||||
else
|
||||
icon_state = "larva[state]"
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
else if(ishuman(owner)) //Humans, being more fragile, are more overwhelmed by the mental backlash.
|
||||
to_chat(owner, "<span class='danger'>You feel a splitting pain in your head, and are struck with a wave of nausea. You cannot hear the hivemind anymore!</span>")
|
||||
owner.emote("scream")
|
||||
owner.Knockdown(100)
|
||||
owner.DefaultCombatKnockdown(100)
|
||||
|
||||
owner.jitteriness += 30
|
||||
owner.confused += 30
|
||||
|
||||
@@ -89,8 +89,8 @@
|
||||
var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc)
|
||||
ghost.transfer_ckey(new_xeno, FALSE)
|
||||
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
|
||||
new_xeno.canmove = 0 //so we don't move during the bursting animation
|
||||
new_xeno.notransform = 1
|
||||
new_xeno.Paralyze(6)
|
||||
new_xeno.notransform = TRUE
|
||||
new_xeno.invisibility = INVISIBILITY_MAXIMUM
|
||||
|
||||
sleep(6)
|
||||
@@ -99,8 +99,8 @@
|
||||
return
|
||||
|
||||
if(new_xeno)
|
||||
new_xeno.canmove = 1
|
||||
new_xeno.notransform = 0
|
||||
new_xeno.SetParalyzed(0)
|
||||
new_xeno.notransform = FALSE
|
||||
new_xeno.invisibility = 0
|
||||
|
||||
var/mob/living/carbon/old_owner = owner
|
||||
|
||||
@@ -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
|
||||
@@ -103,7 +104,7 @@
|
||||
hurt = FALSE
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
if(hurt)
|
||||
Knockdown(20)
|
||||
DefaultCombatKnockdown(20)
|
||||
take_bodypart_damage(10)
|
||||
if(iscarbon(hit_atom) && hit_atom != src)
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
@@ -112,8 +113,8 @@
|
||||
if(hurt)
|
||||
victim.take_bodypart_damage(10)
|
||||
take_bodypart_damage(10)
|
||||
victim.Knockdown(20)
|
||||
Knockdown(20)
|
||||
victim.DefaultCombatKnockdown(20)
|
||||
DefaultCombatKnockdown(20)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>",\
|
||||
"<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,1)
|
||||
@@ -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
|
||||
@@ -281,19 +282,23 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/resist_buckle()
|
||||
. = FALSE
|
||||
if(restrained())
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
// too soon.
|
||||
if(last_special > world.time)
|
||||
return
|
||||
var/buckle_cd = 600
|
||||
if(handcuffed)
|
||||
var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED)
|
||||
buckle_cd = O.breakouttime
|
||||
changeNext_move(min(CLICK_CD_BREAKOUT, buckle_cd))
|
||||
last_special = world.time + min(CLICK_CD_BREAKOUT, buckle_cd)
|
||||
visible_message("<span class='warning'>[src] attempts to unbuckle [p_them()]self!</span>", \
|
||||
"<span class='notice'>You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)</span>")
|
||||
if(do_after(src, buckle_cd, 0, target = src))
|
||||
if(do_after(src, buckle_cd, 0, target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
if(!buckled)
|
||||
return
|
||||
buckled.user_unbuckle_mob(src,src)
|
||||
buckled.user_unbuckle_mob(src, src)
|
||||
else
|
||||
if(src && buckled)
|
||||
to_chat(src, "<span class='warning'>You fail to unbuckle yourself!</span>")
|
||||
@@ -301,21 +306,26 @@
|
||||
buckled.user_unbuckle_mob(src,src)
|
||||
|
||||
/mob/living/carbon/resist_fire()
|
||||
if(last_special > world.time)
|
||||
return
|
||||
fire_stacks -= 5
|
||||
Knockdown(60, TRUE, TRUE)
|
||||
DefaultCombatKnockdown(60, TRUE, TRUE)
|
||||
spin(32,2)
|
||||
visible_message("<span class='danger'>[src] rolls on the floor, trying to put [p_them()]self out!</span>", \
|
||||
"<span class='notice'>You stop, drop, and roll!</span>")
|
||||
last_special = world.time + 30
|
||||
sleep(30)
|
||||
if(fire_stacks <= 0)
|
||||
visible_message("<span class='danger'>[src] has successfully extinguished [p_them()]self!</span>", \
|
||||
"<span class='notice'>You extinguish yourself.</span>")
|
||||
ExtinguishMob()
|
||||
return
|
||||
|
||||
/mob/living/carbon/resist_restraints()
|
||||
/mob/living/carbon/resist_restraints(ignore_delay = FALSE)
|
||||
var/obj/item/I = null
|
||||
var/type = 0
|
||||
if(!ignore_delay && (last_special > world.time))
|
||||
to_chat(src, "<span class='warning'>You don't have the energy to resist your restraints that fast!</span>")
|
||||
return
|
||||
if(handcuffed)
|
||||
I = handcuffed
|
||||
type = 1
|
||||
@@ -324,14 +334,13 @@
|
||||
type = 2
|
||||
if(I)
|
||||
if(type == 1)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
changeNext_move(min(CLICK_CD_BREAKOUT, I.breakouttime))
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(type == 2)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
changeNext_move(min(CLICK_CD_RANGE, I.breakouttime))
|
||||
last_special = world.time + CLICK_CD_RANGE
|
||||
cuff_resist(I)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0)
|
||||
if(I.item_flags & BEING_REMOVED)
|
||||
to_chat(src, "<span class='warning'>You're already attempting to remove [I]!</span>")
|
||||
@@ -341,7 +350,7 @@
|
||||
if(!cuff_break)
|
||||
visible_message("<span class='warning'>[src] attempts to remove [I]!</span>")
|
||||
to_chat(src, "<span class='notice'>You attempt to remove [I]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)</span>")
|
||||
if(do_after(src, breakouttime, 0, target = src))
|
||||
if(do_after(src, breakouttime, 0, target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
clear_cuffs(I, cuff_break)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You fail to remove [I]!</span>")
|
||||
@@ -388,6 +397,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)
|
||||
@@ -403,16 +413,16 @@
|
||||
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
|
||||
@@ -438,7 +448,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)
|
||||
@@ -488,7 +498,7 @@
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
||||
if(stun)
|
||||
Knockdown(200)
|
||||
DefaultCombatKnockdown(200)
|
||||
return 1
|
||||
|
||||
if(is_mouth_covered()) //make this add a blood/vomit overlay later it'll be hilarious
|
||||
@@ -572,9 +582,9 @@
|
||||
if(stam > DAMAGE_PRECISION)
|
||||
var/total_health = (health - stam)
|
||||
if(total_health <= crit_threshold && !stat)
|
||||
if(!IsKnockdown())
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
|
||||
Knockdown(100)
|
||||
KnockToFloor(TRUE)
|
||||
update_health_hud()
|
||||
|
||||
/mob/living/carbon/update_sight()
|
||||
@@ -622,6 +632,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
|
||||
@@ -803,18 +820,17 @@
|
||||
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)
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
update_damage_hud()
|
||||
update_health_hud()
|
||||
med_hud_set_status()
|
||||
@@ -993,8 +1009,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()
|
||||
@@ -1010,3 +1025,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()
|
||||
|
||||
@@ -52,7 +52,12 @@
|
||||
. = ..()
|
||||
if(!HAS_TRAIT(src, TRAIT_AUTO_CATCH_ITEM) && !skip_throw_mode_check && !in_throw_mode)
|
||||
return
|
||||
if(get_active_held_item() || restrained())
|
||||
if(incapacitated())
|
||||
return
|
||||
if (get_active_held_item())
|
||||
if (HAS_TRAIT_FROM(src, TRAIT_AUTO_CATCH_ITEM,RISING_BASS_TRAIT))
|
||||
visible_message("<span class='warning'>[src] chops [I] out of the air!</span>")
|
||||
return TRUE
|
||||
return
|
||||
I.attack_hand(src)
|
||||
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
|
||||
@@ -66,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)
|
||||
@@ -73,13 +79,11 @@
|
||||
/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.resting)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!combatmode)
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
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))
|
||||
@@ -99,7 +103,8 @@
|
||||
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)
|
||||
|
||||
@@ -188,7 +193,7 @@
|
||||
|
||||
do_sparks(5, TRUE, src)
|
||||
var/power = M.powerlevel + rand(0,3)
|
||||
Knockdown(power*20)
|
||||
DefaultCombatKnockdown(power*20)
|
||||
if(stuttering < power)
|
||||
stuttering = power
|
||||
if (prob(stunprob) && M.powerlevel >= 8)
|
||||
@@ -233,19 +238,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)
|
||||
@@ -257,16 +262,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)
|
||||
Knockdown(60)
|
||||
if(override)
|
||||
return override
|
||||
else
|
||||
return shock_damage
|
||||
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
|
||||
DefaultCombatKnockdown(60)
|
||||
return shock_damage
|
||||
|
||||
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
||||
if(on_fire)
|
||||
@@ -282,13 +284,13 @@
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
|
||||
|
||||
else if(check_zone(M.zone_selected) == "mouth") // I ADDED BOOP-EH-DEH-NOSEH - Jon
|
||||
else if(M.zone_selected == BODY_ZONE_PRECISE_MOUTH) // I ADDED BOOP-EH-DEH-NOSEH - Jon
|
||||
M.visible_message( \
|
||||
"<span class='notice'>[M] boops [src]'s nose.</span>", \
|
||||
"<span class='notice'>You boop [src] on the nose.</span>", )
|
||||
playsound(src, 'sound/items/Nose_boop.ogg', 50, 0)
|
||||
|
||||
else if(check_zone(M.zone_selected) == "head")
|
||||
else if(check_zone(M.zone_selected) == BODY_ZONE_HEAD)
|
||||
var/datum/species/S
|
||||
if(ishuman(src))
|
||||
S = dna.species
|
||||
@@ -322,7 +324,7 @@
|
||||
else
|
||||
return
|
||||
|
||||
else if(check_zone(M.zone_selected) == "r_arm" || check_zone(M.zone_selected) == "l_arm")
|
||||
else if(check_zone(M.zone_selected) == BODY_ZONE_R_ARM || check_zone(M.zone_selected) == BODY_ZONE_L_ARM)
|
||||
M.visible_message( \
|
||||
"<span class='notice'>[M] shakes [src]'s hand.</span>", \
|
||||
"<span class='notice'>You shake [src]'s hand.</span>", )
|
||||
@@ -341,16 +343,14 @@
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M)
|
||||
|
||||
AdjustStun(-60)
|
||||
AdjustKnockdown(-60)
|
||||
AdjustUnconscious(-60)
|
||||
AdjustSleeping(-100)
|
||||
if(recoveringstam)
|
||||
AdjustAllImmobility(-60, FALSE)
|
||||
AdjustUnconscious(-60, FALSE)
|
||||
AdjustSleeping(-100, FALSE)
|
||||
if(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
adjustStaminaLoss(-15)
|
||||
else if(resting)
|
||||
resting = 0
|
||||
update_canmove()
|
||||
|
||||
else
|
||||
set_resting(FALSE, FALSE)
|
||||
update_mobility()
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
|
||||
@@ -414,7 +414,7 @@
|
||||
var/effect_amount = intensity - ear_safety
|
||||
if(effect_amount > 0)
|
||||
if(stun_pwr)
|
||||
Knockdown(stun_pwr*effect_amount)
|
||||
DefaultCombatKnockdown(stun_pwr*effect_amount)
|
||||
|
||||
if(istype(ears) && (deafen_pwr || damage_pwr))
|
||||
var/ear_damage = damage_pwr * effect_amount
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
. = ..()
|
||||
. += grab_state * 3 //can't go fast while grabbing something.
|
||||
|
||||
if(!get_leg_ignore()) //ignore the fact we lack legs
|
||||
var/leg_amount = get_num_legs()
|
||||
. += 6 - 3*leg_amount //the fewer the legs, the slower the mob
|
||||
if(!leg_amount)
|
||||
. += 6 - 3*get_num_arms() //crawling is harder with fewer arms
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
if(stat == SOFT_CRIT)
|
||||
. += SOFTCRIT_ADD_SLOWDOWN
|
||||
|
||||
/mob/living/carbon/slip(knockdown_amount, obj/O, lube)
|
||||
if(movement_type & FLYING && !(lube & FLYING_DOESNT_HELP))
|
||||
return FALSE
|
||||
@@ -43,3 +29,10 @@
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
if(m_intent == MOVE_INTENT_RUN)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
|
||||
/mob/living/carbon/can_move_under_living(mob/living/other)
|
||||
. = ..()
|
||||
if(!.) //we failed earlier don't need to fail again
|
||||
return
|
||||
if(!other.lying && lying) //they're up, we're down.
|
||||
return 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 ..()
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
message = "moans!"
|
||||
message_mime = "appears to moan!"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
stat_allowed = SOFT_CRIT
|
||||
|
||||
/datum/emote/living/carbon/roll
|
||||
key = "roll"
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
if(digitalcamo)
|
||||
. += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner."
|
||||
|
||||
if(combatmode)
|
||||
. += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]"
|
||||
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()
|
||||
if (!isnull(trait_exam))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -491,7 +498,7 @@
|
||||
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
|
||||
|
||||
/mob/living/carbon/human/proc/canUseHUD()
|
||||
return !(src.stat || IsKnockdown() || IsStun() || src.restrained())
|
||||
return CHECK_MOBILITY(src, MOBILITY_UI)
|
||||
|
||||
/mob/living/carbon/human/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
|
||||
. = 1 // Default to returning true.
|
||||
@@ -614,13 +621,14 @@
|
||||
|
||||
//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"
|
||||
socks = "Nude"
|
||||
update_body()
|
||||
update_hair()
|
||||
update_genitals()
|
||||
@@ -724,8 +732,8 @@
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
|
||||
cut_overlay(MA)
|
||||
|
||||
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
if(incapacitated() || lying )
|
||||
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE, check_resting = TRUE)
|
||||
if(incapacitated() || (check_resting && !CHECK_MOBILITY(src, MOBILITY_STAND)))
|
||||
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
|
||||
return FALSE
|
||||
if(!Adjacent(M) && (M.loc != src))
|
||||
@@ -836,7 +844,7 @@
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
||||
if(stun)
|
||||
Knockdown(200)
|
||||
DefaultCombatKnockdown(200)
|
||||
return 1
|
||||
..()
|
||||
|
||||
@@ -870,16 +878,26 @@
|
||||
return (istype(target) && target.stat == CONSCIOUS)
|
||||
|
||||
/mob/living/carbon/human/proc/can_be_firemanned(mob/living/carbon/target)
|
||||
return (ishuman(target) && target.lying)
|
||||
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.resting = FALSE
|
||||
target.set_resting(FALSE, TRUE)
|
||||
buckle_mob(target, TRUE, TRUE, 90, 1, 0)
|
||||
return
|
||||
visible_message("<span class='warning'>[src] fails to fireman carry [target]!")
|
||||
@@ -892,7 +910,7 @@
|
||||
/mob/living/carbon/human/proc/piggyback(mob/living/carbon/target)
|
||||
if(can_piggyback(target))
|
||||
visible_message("<span class='notice'>[target] starts to climb onto [src]...</span>")
|
||||
if(do_after(target, 15, target = src))
|
||||
if(do_after(target, 15, target = src, required_mobility_flags = MOBILITY_STAND))
|
||||
if(can_piggyback(target))
|
||||
if(target.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
|
||||
target.visible_message("<span class='warning'>[target] can't hang onto [src]!</span>")
|
||||
@@ -948,6 +966,22 @@
|
||||
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
|
||||
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
. = ..()
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
return
|
||||
var/stambufferinfluence = (bufferedstam*(100/stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
|
||||
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 = FLYING, blacklisted_movetypes = FLOATING)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
|
||||
/mob/living/carbon/human/do_after_coefficent()
|
||||
. = ..()
|
||||
. *= physiology.do_after_speed
|
||||
|
||||
@@ -45,26 +45,11 @@
|
||||
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/dodgemessage = pick("dodges under the projectile!","dodges to the right of the projectile!","jumps over the projectile!")
|
||||
visible_message("<span class='danger'>[src] [dodgemessage]</span>", "<span class='userdanger'>You dodge the projectile!</span>")
|
||||
return BULLET_ACT_BLOCK
|
||||
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)
|
||||
@@ -174,7 +159,7 @@
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else if(!M.client || prob(5)) // only natural monkeys get to stun reliably, (they only do it occasionaly)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Knockdown(100)
|
||||
DefaultCombatKnockdown(100)
|
||||
log_combat(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
@@ -223,9 +208,9 @@
|
||||
else
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(!lying) //CITADEL EDIT
|
||||
Knockdown(100, TRUE, FALSE, 30, 25)
|
||||
DefaultCombatKnockdown(100, TRUE, FALSE, 30, 25)
|
||||
else
|
||||
Knockdown(100)
|
||||
DefaultCombatKnockdown(100)
|
||||
log_combat(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
@@ -292,10 +277,10 @@
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 35) // durand and other heavy mechas
|
||||
Knockdown(50)
|
||||
DefaultCombatKnockdown(50)
|
||||
src.throw_at(throw_target, rand(1,5), 7)
|
||||
else if(M.force >= 20 && !IsKnockdown()) // lightweight mechas like gygax
|
||||
Knockdown(30)
|
||||
else if(M.force >= 20 && CHECK_MOBILITY(src, MOBILITY_STAND)) // lightweight mechas like gygax
|
||||
DefaultCombatKnockdown(30)
|
||||
src.throw_at(throw_target, rand(1,3), 7)
|
||||
update |= temp.receive_damage(dmg, 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
@@ -392,8 +377,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
|
||||
@@ -408,20 +393,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,9 @@
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
/// Enable stamina combat
|
||||
combat_flags = COMBAT_FLAGS_DEFAULT
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
var/hair_style = "Bald"
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/mob/living/carbon/human/resist_a_rest(automatic = FALSE, ignoretimer = FALSE)
|
||||
if(!resting || stat || (combat_flags & COMBAT_FLAG_RESISTING_REST))
|
||||
return FALSE
|
||||
if(ignoretimer)
|
||||
set_resting(FALSE, FALSE)
|
||||
return TRUE
|
||||
if(!lying) //if they're in a chair or something they don't need to force themselves off the ground.
|
||||
set_resting(FALSE, FALSE)
|
||||
return TRUE
|
||||
else if(!CHECK_MOBILITY(src, MOBILITY_RESIST))
|
||||
if(!automatic)
|
||||
to_chat(src, "<span class='warning'>You are unable to stand up right now.</span>")
|
||||
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(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to get up!")
|
||||
return FALSE
|
||||
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
|
||||
totaldelay += health_deficiency
|
||||
var/standupwarning = "[src] and everyone around them should probably yell at the dev team"
|
||||
switch(health_deficiency)
|
||||
if(-INFINITY to 10)
|
||||
standupwarning = "[src] stands right up!"
|
||||
if(10 to 35)
|
||||
standupwarning = "[src] tries to stand up."
|
||||
if(35 to 60)
|
||||
standupwarning = "[src] slowly pushes [p_them()]self upright."
|
||||
if(60 to 80)
|
||||
standupwarning = "[src] weakly attempts to stand up."
|
||||
if(80 to INFINITY)
|
||||
standupwarning = "[src] struggles to stand up."
|
||||
var/usernotice = automatic ? "<span class='notice'>You are now getting up. (Auto)</span>" : "<span class='notice'>You are now getting up.</span>"
|
||||
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)
|
||||
|
||||
combat_flags &= ~COMBAT_FLAG_RESISTING_REST
|
||||
return TRUE
|
||||
else
|
||||
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())
|
||||
playsound(src, "bodyfall", 20, 1)
|
||||
return FALSE
|
||||
@@ -9,8 +9,15 @@
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
if(dna && dna.species)
|
||||
. += dna.species.movement_delay(src)
|
||||
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
|
||||
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
|
||||
@@ -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)
|
||||
|
||||
@@ -145,6 +145,12 @@
|
||||
|
||||
return not_handled //For future deeper overrides
|
||||
|
||||
/mob/living/carbon/human/equipped_speed_mods()
|
||||
. = ..()
|
||||
for(var/sloties in get_all_slots() - list(l_store, r_store, s_store))
|
||||
var/obj/item/thing = sloties
|
||||
. += thing?.slowdown
|
||||
|
||||
/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE)
|
||||
var/index = get_held_index_of_item(I)
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
|
||||
@@ -316,6 +316,7 @@
|
||||
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")
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -69,8 +69,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
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
|
||||
|
||||
// species-only traits. Can be found in DNA.dm
|
||||
var/list/species_traits = list()
|
||||
@@ -104,7 +106,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.
|
||||
|
||||
/// Our default override for typing indicator state
|
||||
var/typing_indicator_state
|
||||
@@ -358,6 +360,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
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)
|
||||
@@ -390,7 +400,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)
|
||||
@@ -444,7 +454,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
|
||||
@@ -578,7 +588,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
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)
|
||||
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)
|
||||
@@ -739,7 +749,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)
|
||||
@@ -818,9 +828,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"
|
||||
@@ -1022,6 +1030,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.apply_overlay(BODY_TAUR_LAYER) // CITADEL EDIT
|
||||
|
||||
|
||||
/*
|
||||
* Equip the outfit required for life. Replaces items currently worn.
|
||||
*/
|
||||
/datum/species/proc/give_important_for_life(mob/living/carbon/human/human_to_equip)
|
||||
if(!outfit_important_for_life)
|
||||
return
|
||||
outfit_important_for_life= new()
|
||||
outfit_important_for_life.equip(human_to_equip)
|
||||
|
||||
//This exists so sprite accessories can still be per-layer without having to include that layer's
|
||||
//number in their sprite name, which causes issues when those numbers change.
|
||||
/datum/species/proc/mutant_bodyparts_layertext(layer)
|
||||
@@ -1289,12 +1306,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.overeatduration < 100)
|
||||
to_chat(H, "<span class='notice'>You feel fit again!</span>")
|
||||
REMOVE_TRAIT(H, TRAIT_FAT, OBESITY)
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_FAT)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
else
|
||||
if(H.overeatduration >= 100)
|
||||
to_chat(H, "<span class='danger'>You suddenly feel blubbery!</span>")
|
||||
ADD_TRAIT(H, TRAIT_FAT, OBESITY)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_FAT, multiplicative_slowdown = 1.5)
|
||||
H.update_inv_w_uniform()
|
||||
H.update_inv_wear_suit()
|
||||
|
||||
@@ -1345,6 +1364,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
to_chat(H, "<span class='notice'>You no longer feel vigorous.</span>")
|
||||
H.metabolism_efficiency = 1
|
||||
|
||||
//Hunger slowdown for if mood isn't enabled
|
||||
if(CONFIG_GET(flag/disable_human_mood))
|
||||
if(!HAS_TRAIT(H, TRAIT_NOHUNGER))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if(hungry >= 70)
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (hungry / 50))
|
||||
else
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_HUNGRY)
|
||||
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
@@ -1367,9 +1395,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return TRUE
|
||||
|
||||
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
|
||||
if(!H.IsKnockdown())
|
||||
if(CHECK_MOBILITY(H, MOBILITY_STAND))
|
||||
H.emote("collapse")
|
||||
H.Knockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
|
||||
H.DefaultCombatKnockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
|
||||
to_chat(H, "<span class='danger'>You feel weak.</span>")
|
||||
|
||||
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
|
||||
@@ -1378,7 +1406,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()
|
||||
|
||||
@@ -1394,59 +1422,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.hair_style = "Bald"
|
||||
H.update_hair()
|
||||
|
||||
////////////////
|
||||
// MOVE SPEED //
|
||||
////////////////
|
||||
|
||||
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
|
||||
. = 0 //We start at 0.
|
||||
var/flight = 0 //Check for flight and flying items
|
||||
var/gravity = 0
|
||||
if(H.movement_type & FLYING)
|
||||
flight = 1
|
||||
|
||||
gravity = H.has_gravity()
|
||||
|
||||
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
if(!HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN) && gravity)
|
||||
if(H.wear_suit)
|
||||
. += H.wear_suit.slowdown
|
||||
if(H.shoes)
|
||||
. += H.shoes.slowdown
|
||||
if(H.back)
|
||||
. += H.back.slowdown
|
||||
for(var/obj/item/I in H.held_items)
|
||||
if(I.item_flags & SLOWS_WHILE_IN_HAND)
|
||||
. += I.slowdown
|
||||
var/stambufferinfluence = (H.bufferedstam*(100/H.stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
|
||||
var/health_deficiency = ((100 + stambufferinfluence) - H.health + (H.getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss on movement speed and makes stamina buffer influence movedelay
|
||||
if(health_deficiency >= 40)
|
||||
if(flight)
|
||||
. += ((health_deficiency-39) / 75) // CIT CHANGE - adds -39 to health deficiency penalty to make the transition to low health movement a little less jarring
|
||||
else
|
||||
. += ((health_deficiency-39) / 25) // CIT CHANGE - ditto
|
||||
if(CONFIG_GET(flag/disable_human_mood))
|
||||
var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80
|
||||
if((hungry >= 70) && !flight) //Being hungry will still allow you to use a flightsuit/wings.
|
||||
. += hungry / 50
|
||||
|
||||
//Moving in high gravity is very slow (Flying too)
|
||||
if(gravity > STANDARD_GRAVITY)
|
||||
var/grav_force = min(gravity - STANDARD_GRAVITY,3)
|
||||
. += 1 + grav_force
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_FAT))
|
||||
. += (1.5 - flight)
|
||||
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
|
||||
return .
|
||||
|
||||
//////////////////
|
||||
// ATTACK PROCS //
|
||||
//////////////////
|
||||
|
||||
//////////////////
|
||||
// ATTACK PROCS //
|
||||
//////////////////
|
||||
@@ -1478,15 +1453,11 @@ 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())
|
||||
@@ -1515,11 +1486,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
|
||||
|
||||
//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)
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && damage < user.dna.species.punchstunthreshold)
|
||||
damage = user.dna.species.punchstunthreshold - 1
|
||||
if(user.resting)
|
||||
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
|
||||
|
||||
@@ -1568,12 +1539,12 @@ 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
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
|
||||
return 0
|
||||
else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
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)
|
||||
@@ -1633,11 +1604,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(user.resting) //CITADEL CHANGE
|
||||
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
|
||||
@@ -1714,14 +1685,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.resting)
|
||||
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)
|
||||
@@ -1747,7 +1716,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)
|
||||
|
||||
@@ -1831,20 +1800,25 @@ 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.resting)
|
||||
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
|
||||
if(CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
to_chat(user, "<span class='notice'>You can only force yourself up if you're on the ground.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] forces [p_them()]self up to [p_their()] feet!</span>", "<span class='notice'>You force yourself up to your feet!</span>")
|
||||
user.resting = 0
|
||||
user.update_canmove()
|
||||
user.set_resting(FALSE, TRUE)
|
||||
user.adjustStaminaLossBuffered(user.stambuffer) //Rewards good stamina management by making it easier to instantly get up from resting
|
||||
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())
|
||||
@@ -1852,7 +1826,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return FALSE
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
return TRUE
|
||||
if(user.resting)
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
return FALSE
|
||||
else
|
||||
if(user == target)
|
||||
@@ -1865,7 +1839,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.w_uniform.add_fingerprint(user)
|
||||
SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected)
|
||||
|
||||
if(!target.resting)
|
||||
if(CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
target.adjustStaminaLoss(5)
|
||||
|
||||
if(target.is_shove_knockdown_blocked())
|
||||
@@ -1879,7 +1853,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
//Thank you based whoneedsspace
|
||||
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
|
||||
if(target_collateral_human && !target_collateral_human.resting)
|
||||
if(target_collateral_human && CHECK_MOBILITY(target_collateral_human, MOBILITY_STAND))
|
||||
shove_blocked = TRUE
|
||||
else
|
||||
target_collateral_human = null
|
||||
@@ -1890,15 +1864,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/append_message = ""
|
||||
if(shove_blocked && !target.buckled)
|
||||
var/directional_blocked = !target.Adjacent(target_shove_turf)
|
||||
var/targetatrest = target.resting
|
||||
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
|
||||
if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
|
||||
"<span class='danger'>You shove [target.name], knocking them down!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "knocking them down")
|
||||
else if(target_collateral_human && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
|
||||
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_HUMAN)
|
||||
target_collateral_human.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
append_message += ", into [target_collateral_human.name]"
|
||||
@@ -2061,6 +2035,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "hot", /datum/mood_event/hot)
|
||||
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
|
||||
|
||||
var/burn_damage
|
||||
var/firemodifier = H.fire_stacks / 50
|
||||
if (H.on_fire)
|
||||
@@ -2076,6 +2052,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
|
||||
//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))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
|
||||
@@ -2085,6 +2063,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN)
|
||||
|
||||
else
|
||||
H.remove_movespeed_modifier(MOVESPEED_ID_COLD)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
|
||||
|
||||
@@ -52,21 +52,20 @@
|
||||
return 0
|
||||
|
||||
/datum/species/angel/proc/CanFly(mob/living/carbon/human/H)
|
||||
if(H.stat || H.IsStun() || H.IsKnockdown())
|
||||
return 0
|
||||
if(!CHECK_MOBILITY(H, MOBILITY_MOVE))
|
||||
return FALSE
|
||||
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)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too
|
||||
to_chat(H, "Your suit blocks your wings from extending!")
|
||||
return 0
|
||||
return FALSE
|
||||
var/turf/T = get_turf(H)
|
||||
if(!T)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
if(environment && !(environment.return_pressure() > 30))
|
||||
to_chat(H, "<span class='warning'>The atmosphere is too thin for you to fly!</span>")
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/flight
|
||||
name = "Toggle Flight"
|
||||
@@ -81,12 +80,12 @@
|
||||
if(H.movement_type & FLYING)
|
||||
to_chat(H, "<span class='notice'>You settle gently back onto the ground...</span>")
|
||||
A.ToggleFlight(H,0)
|
||||
H.update_canmove()
|
||||
H.update_mobility()
|
||||
else
|
||||
to_chat(H, "<span class='notice'>You beat your wings and begin to hover gently above the ground...</span>")
|
||||
H.resting = 0
|
||||
H.set_resting(FALSE, TRUE)
|
||||
A.ToggleFlight(H,1)
|
||||
H.update_canmove()
|
||||
H.update_mobility()
|
||||
|
||||
/datum/species/angel/proc/flyslip(mob/living/carbon/human/H)
|
||||
var/obj/buckled_obj
|
||||
|
||||
@@ -13,7 +13,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)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
H.vomit(0, FALSE, FALSE, 2, TRUE)
|
||||
var/obj/effect/decal/cleanable/vomit/V = locate() in pos
|
||||
if(V)
|
||||
H.reagents.trans_id_to(V, chem, chem.volume)
|
||||
H.reagents.trans_id_to(V, chem.type, chem.volume)
|
||||
playsound(pos, 'sound/effects/splat.ogg', 50, 1)
|
||||
H.visible_message("<span class='danger'>[H] vomits on the floor!</span>", \
|
||||
"<span class='userdanger'>You throw up on the floor!</span>")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
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")
|
||||
@@ -55,7 +55,7 @@
|
||||
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")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
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)
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
button_icon_state = "slimeheal"
|
||||
icon_icon = 'icons/mob/actions/actions_slime.dmi'
|
||||
background_icon_state = "bg_alien"
|
||||
required_mobility_flags = NONE
|
||||
|
||||
/datum/action/innate/regenerate_limbs/IsAvailable()
|
||||
if(..())
|
||||
@@ -602,10 +603,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)
|
||||
@@ -614,8 +616,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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much
|
||||
disliked_food = FRUIT
|
||||
liked_food = VEGETABLES
|
||||
outfit_important_for_life = /datum/outfit/plasmaman
|
||||
|
||||
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
|
||||
var/datum/gas_mixture/environment = H.loc.return_air()
|
||||
|
||||
@@ -58,12 +58,12 @@
|
||||
if(/obj/item/projectile/energy/floramut)
|
||||
if(prob(15))
|
||||
H.rad_act(rand(30,80))
|
||||
H.Knockdown(100)
|
||||
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))
|
||||
|
||||
@@ -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,53 @@
|
||||
/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","mam_tail", "mam_snouts","legs", "mam_body_markings", "taur")
|
||||
default_features = 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 ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/synthliz/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
|
||||
/datum/species/synthliz/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/synthliz/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
@@ -3,7 +3,7 @@
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg)
|
||||
/mob/living/carbon/human/DefaultCombatKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ There are several things that need to be remembered:
|
||||
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)
|
||||
|
||||
@@ -648,12 +648,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(("taur" in dna.species.mutant_bodyparts) && (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)
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
|
||||
if(prob(0.05 * miasma_partialpressure))
|
||||
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3)
|
||||
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(TRUE, 2,3)
|
||||
miasma_disease.name = "Unknown"
|
||||
ForceContractDisease(miasma_disease, TRUE, TRUE)
|
||||
|
||||
@@ -427,7 +427,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 +449,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 +507,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(resting ? (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)
|
||||
|
||||
@@ -521,7 +520,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
bufferedstam = max(bufferedstam - drainrate, 0)
|
||||
//END OF CIT CHANGES
|
||||
|
||||
var/restingpwr = 1 + 4 * resting
|
||||
var/restingpwr = 1 + 4 * !CHECK_MOBILITY(src, MOBILITY_STAND)
|
||||
|
||||
//Dizziness
|
||||
if(dizziness)
|
||||
|
||||
@@ -50,17 +50,11 @@
|
||||
|
||||
// taken from /mob/living/carbon/human/interactive/
|
||||
/mob/living/carbon/monkey/proc/IsDeadOrIncap(checkDead = TRUE)
|
||||
if(!canmove)
|
||||
return 1
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_MOVE))
|
||||
return TRUE
|
||||
if(health <= 0 && checkDead)
|
||||
return 1
|
||||
if(IsUnconscious())
|
||||
return 1
|
||||
if(IsStun() || IsKnockdown())
|
||||
return 1
|
||||
if(stat)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/monkey/proc/battle_screech()
|
||||
if(next_battle_screech < world.time)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
if(!client)
|
||||
if(stat == CONSCIOUS)
|
||||
if(on_fire || buckled || restrained() || (resting && canmove)) //CIT CHANGE - makes it so monkeys attempt to resist if they're resting)
|
||||
if(on_fire || buckled || restrained() || (!CHECK_MOBILITY(src, MOBILITY_STAND) && CHECK_MOBILITY(src, MOBILITY_MOVE))) //CIT CHANGE - makes it so monkeys attempt to resist if they're resting)
|
||||
if(!resisting && prob(MONKEY_RESIST_PROB))
|
||||
resisting = TRUE
|
||||
walk_to(src,0)
|
||||
@@ -21,7 +21,7 @@
|
||||
else if(resisting)
|
||||
resisting = FALSE
|
||||
else if((mode == MONKEY_IDLE && !pickupTarget && !prob(MONKEY_SHENANIGAN_PROB)) || !handle_combat())
|
||||
if(prob(25) && canmove && isturf(loc) && !pulledby)
|
||||
if(prob(25) && CHECK_MOBILITY(src, MOBILITY_MOVE) && isturf(loc) && !pulledby)
|
||||
step(src, pick(GLOB.cardinals))
|
||||
else if(prob(1))
|
||||
emote(pick("scratch","jump","roll","tail"))
|
||||
@@ -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(!IsKnockdown())
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
emote("collapse")
|
||||
Knockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
|
||||
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))
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
/mob/living/carbon/monkey/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "monkey", null, null, null, SLOT_HEAD)
|
||||
AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Destroy()
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
if(!IsUnconscious())
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if (prob(25))
|
||||
Knockdown(40)
|
||||
DefaultCombatKnockdown(40)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
log_combat(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
@@ -126,7 +126,7 @@
|
||||
var/obj/item/I = null
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(prob(95))
|
||||
Knockdown(20)
|
||||
DefaultCombatKnockdown(20)
|
||||
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
if(EFFECT_STUN)
|
||||
Stun(effect * hit_percent)
|
||||
if(EFFECT_KNOCKDOWN)
|
||||
Knockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
|
||||
DefaultCombatKnockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
|
||||
if(EFFECT_UNCONSCIOUS)
|
||||
Unconscious(effect * hit_percent)
|
||||
if(EFFECT_IRRADIATE)
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
update_action_buttons_icon()
|
||||
update_damage_hud()
|
||||
update_health_hud()
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
if(!gibbed && !QDELETED(src))
|
||||
|
||||
@@ -273,7 +273,7 @@
|
||||
if(H.get_num_arms() == 0)
|
||||
if(H.get_num_legs() != 0)
|
||||
message_param = "tries to point at %t with a leg, <span class='userdanger'>falling down</span> in the process!"
|
||||
H.Knockdown(20)
|
||||
H.DefaultCombatKnockdown(20)
|
||||
else
|
||||
message_param = "<span class='userdanger'>bumps [user.p_their()] head on the ground</span> trying to motion towards %t."
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
|
||||
@@ -377,7 +377,7 @@
|
||||
. = ..()
|
||||
if(. && isliving(user))
|
||||
var/mob/living/L = user
|
||||
L.Knockdown(200)
|
||||
L.DefaultCombatKnockdown(200)
|
||||
|
||||
/datum/emote/living/sway
|
||||
key = "sway"
|
||||
@@ -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)
|
||||
|
||||
+101
-182
@@ -48,7 +48,7 @@
|
||||
/mob/living/proc/ZImpactDamage(turf/T, levels)
|
||||
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>")
|
||||
adjustBruteLoss((levels * 5) ** 1.5)
|
||||
Knockdown(levels * 50)
|
||||
DefaultCombatKnockdown(levels * 50)
|
||||
|
||||
|
||||
/mob/living/proc/OpenCraftingMenu()
|
||||
@@ -88,7 +88,7 @@
|
||||
var/they_can_move = TRUE
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
they_can_move = L.canmove //L.mobility_flags & MOBILITY_MOVE
|
||||
they_can_move = CHECK_MOBILITY(L, MOBILITY_MOVE)
|
||||
//Also spread diseases
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
@@ -115,25 +115,25 @@
|
||||
return 1
|
||||
|
||||
//CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks without a short delay
|
||||
if(resting && !L.resting)
|
||||
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) || !resting)
|
||||
attemptingcrawl = FALSE
|
||||
if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
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
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
var/current_dir
|
||||
if(isliving(AM))
|
||||
current_dir = AM.dir
|
||||
if(step(AM, t))
|
||||
if(step(AM, t) && Process_Spacemove(t))
|
||||
step(src, t)
|
||||
if(current_dir)
|
||||
AM.setDir(current_dir)
|
||||
@@ -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, ignore_grab)
|
||||
if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here
|
||||
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE)
|
||||
if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)))
|
||||
return TRUE
|
||||
|
||||
/mob/living/canUseStorage()
|
||||
@@ -428,7 +427,6 @@
|
||||
else
|
||||
if(alert(src, "You sure you want to sleep for a while?", "Sleep", "Yes", "No") == "Yes")
|
||||
SetSleeping(400) //Short nap
|
||||
update_canmove()
|
||||
|
||||
/mob/proc/get_contents()
|
||||
|
||||
@@ -491,9 +489,10 @@
|
||||
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_canmove()
|
||||
update_mobility()
|
||||
update_sight()
|
||||
clear_alert("not_enough_oxy")
|
||||
reload_fullscreen()
|
||||
@@ -512,8 +511,7 @@
|
||||
setStaminaLoss(0, 0)
|
||||
SetUnconscious(0, FALSE)
|
||||
set_disgust(0)
|
||||
SetStun(0, FALSE)
|
||||
SetKnockdown(0, FALSE)
|
||||
SetAllImmobility(0, FALSE)
|
||||
SetSleeping(0, FALSE)
|
||||
radiation = 0
|
||||
nutrition = NUTRITION_LEVEL_FED + 50
|
||||
@@ -528,7 +526,7 @@
|
||||
ExtinguishMob()
|
||||
fire_stacks = 0
|
||||
confused = 0
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
//Heal all organs
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
@@ -552,30 +550,6 @@
|
||||
var/obj/item/item = i
|
||||
SEND_SIGNAL(item, COMSIG_ITEM_WEARERCROSSED, AM)
|
||||
|
||||
/mob/living/Move(atom/newloc, direct)
|
||||
if (buckled && buckled.loc != newloc) //not updating position
|
||||
if (!buckled.anchored)
|
||||
return buckled.Move(newloc, direct)
|
||||
else
|
||||
return 0
|
||||
|
||||
var/old_direction = dir
|
||||
var/turf/T = loc
|
||||
|
||||
if(pulling)
|
||||
update_pull_movespeed()
|
||||
|
||||
. = ..()
|
||||
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(active_storage && !(CanReach(active_storage.parent,view_only = TRUE)))
|
||||
active_storage.close(src)
|
||||
|
||||
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
|
||||
makeTrail(newloc, T, old_direction)
|
||||
|
||||
/mob/living/proc/makeTrail(turf/target_turf, turf/start, direction)
|
||||
if(!has_gravity())
|
||||
return
|
||||
@@ -648,66 +622,97 @@
|
||||
..(pressure_difference, direction, pressure_resistance_prob_delta)
|
||||
|
||||
/mob/living/can_resist()
|
||||
return !((next_move > world.time) || incapacitated(ignore_restraints = TRUE))
|
||||
return !((next_move > world.time) || !CHECK_MOBILITY(src, MOBILITY_RESIST))
|
||||
|
||||
/// Resist verb for attempting to get out of whatever is restraining your motion. Gives you resist clickdelay if do_resist() returns true.
|
||||
/mob/living/verb/resist()
|
||||
set name = "Resist"
|
||||
set category = "IC"
|
||||
|
||||
if(!can_resist())
|
||||
return
|
||||
changeNext_move(CLICK_CD_RESIST)
|
||||
|
||||
if(do_resist())
|
||||
changeNext_move(CLICK_CD_RESIST)
|
||||
|
||||
/// The actual proc for resisting. Return TRUE to give clickdelay.
|
||||
/mob/living/proc/do_resist()
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src)
|
||||
//resisting grabs (as if it helps anyone...)
|
||||
if(!restrained(ignore_grab = 1) && pulledby)
|
||||
visible_message("<span class='danger'>[src] resists against [pulledby]'s grip!</span>")
|
||||
log_combat(src, pulledby, "resisted grab")
|
||||
resist_grab()
|
||||
return
|
||||
// only works if you're not cuffed.
|
||||
if(!restrained(ignore_grab = TRUE) && pulledby)
|
||||
var/old_gs = pulledby.grab_state
|
||||
attempt_resist_grab(FALSE)
|
||||
// Return as we should only resist one thing at a time. Give clickdelay if the grab wasn't passive.
|
||||
return old_gs? TRUE : FALSE
|
||||
|
||||
//unbuckling yourself
|
||||
// unbuckling yourself. stops the chain if you try it.
|
||||
if(buckled && last_special <= world.time)
|
||||
resist_buckle()
|
||||
log_combat(src, buckled, "resisted buckle")
|
||||
return resist_buckle()
|
||||
|
||||
// CIT CHANGE - climbing out of a gut
|
||||
if(attempt_vr(src,"vore_process_resist",args)) return TRUE
|
||||
// CIT CHANGE - climbing out of a gut.
|
||||
if(attempt_vr(src,"vore_process_resist",args))
|
||||
//Sure, give clickdelay for anti spam. shouldn't be combat voring anyways.
|
||||
return TRUE
|
||||
|
||||
//Breaking out of a container (Locker, sleeper, cryo...)
|
||||
else if(isobj(loc))
|
||||
if(isobj(loc))
|
||||
var/obj/C = loc
|
||||
C.container_resist(src)
|
||||
// This shouldn't give clickdelays sometime (e.g. going out of a mech/unwelded and unlocked locker/disposals bin/etc) but there's so many overrides that I am not going to bother right now.
|
||||
return TRUE
|
||||
|
||||
else if(canmove)
|
||||
if(CHECK_MOBILITY(src, MOBILITY_MOVE))
|
||||
if(on_fire)
|
||||
resist_fire() //stop, drop, and roll
|
||||
return
|
||||
if(resting) //cit change - allows resisting out of resting
|
||||
resist_a_rest() // ditto
|
||||
return
|
||||
if(resist_embedded()) //Citadel Change for embedded removal memes
|
||||
return
|
||||
if(last_special <= world.time)
|
||||
resist_restraints() //trying to remove cuffs.
|
||||
return
|
||||
// Give clickdelay
|
||||
return TRUE
|
||||
if(resting) //cit change - allows resisting out of resting
|
||||
resist_a_rest() // ditto
|
||||
// DO NOT GIVE CLCIKDELAY - resist_a_rest() handles spam prevention. Somewhat.
|
||||
return FALSE
|
||||
if(last_special <= world.time)
|
||||
resist_restraints() //trying to remove cuffs.
|
||||
// DO NOT GIVE CLICKDELAY - last_special handles this.
|
||||
return FALSE
|
||||
if(CHECK_MOBILITY(src, MOBILITY_USE) && resist_embedded()) //Citadel Change for embedded removal memes - requires being able to use items.
|
||||
// DO NOT GIVE DEFAULT CLICKDELAY - This is a combat action.
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
return FALSE
|
||||
|
||||
/// Proc to resist a grab. moving_resist is TRUE if this began by someone attempting to move. Return FALSE if still grabbed/failed to break out. Use this instead of resist_grab() directly.
|
||||
/mob/proc/attempt_resist_grab(moving_resist, forced, log = TRUE)
|
||||
if(!pulledby) //not being grabbed
|
||||
return TRUE
|
||||
var/old_gs = pulledby.grab_state //how strong the grab is
|
||||
var/old_pulled = pulledby
|
||||
var/success = do_resist_grab(moving_resist, forced)
|
||||
if(log)
|
||||
log_combat(src, old_pulled, "[success? "successfully broke free of" : "failed to resist"] a grab of strength [old_gs][moving_resist? " (moving)":""][forced? " (forced)":""]")
|
||||
return success
|
||||
|
||||
/mob/proc/resist_grab(moving_resist)
|
||||
return 1 //returning 0 means we successfully broke free
|
||||
/*!
|
||||
* Proc that actually does the grab resisting. Return TRUE if successful. Does not check that a grab exists! Use attempt_resist_grab() instead of this in general!
|
||||
* Forced is if something other than the user mashing movement keys/pressing resist button did it, silent is if it makes messages (like "attempted to resist" and "broken free").
|
||||
* Forced does NOT force success!
|
||||
*/
|
||||
/mob/proc/do_resist_grab(moving_resist, forced, silent = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/resist_grab(moving_resist)
|
||||
. = 1
|
||||
/mob/living/do_resist_grab(moving_resist, forced, silent = FALSE)
|
||||
. = ..()
|
||||
if(pulledby.grab_state)
|
||||
if(!resting && prob(30/pulledby.grab_state))
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND) && prob(30/pulledby.grab_state))
|
||||
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
|
||||
log_combat(pulledby, src, "broke grab")
|
||||
pulledby.stop_pulling()
|
||||
return 0
|
||||
if(moving_resist && client) //we resisted by trying to move
|
||||
return TRUE
|
||||
else if(moving_resist && client) //we resisted by trying to move // this is a horrible system and whoever thought using client instead of mob is okay is not an okay person
|
||||
client.move_delay = world.time + 20
|
||||
visible_message("<span class='danger'>[src] resists against [pulledby]'s grip!</span>")
|
||||
else
|
||||
pulledby.stop_pulling()
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/resist_buckle()
|
||||
buckled.user_unbuckle_mob(src,src)
|
||||
@@ -722,6 +727,7 @@
|
||||
return name
|
||||
|
||||
/mob/living/update_gravity(has_gravity,override = 0)
|
||||
. = ..()
|
||||
if(!SSticker.HasRoundStarted())
|
||||
return
|
||||
if(has_gravity)
|
||||
@@ -788,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)
|
||||
@@ -1048,7 +1061,7 @@
|
||||
"[C] trips over [src] and falls!", \
|
||||
"[C] topples over [src]!", \
|
||||
"[C] leaps out of [src]'s way!")]</span>")
|
||||
C.Knockdown(40)
|
||||
C.DefaultCombatKnockdown(40)
|
||||
|
||||
/mob/living/ConveyorMove()
|
||||
if((movement_type & FLYING) && !stat)
|
||||
@@ -1058,61 +1071,6 @@
|
||||
/mob/living/can_be_pulled()
|
||||
return ..() && !(buckled && buckled.buckle_prevents_pull)
|
||||
|
||||
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
|
||||
//Robots, animals and brains have their own version so don't worry about them
|
||||
/mob/living/proc/update_canmove()
|
||||
var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (HAS_TRAIT(src, TRAIT_DEATHCOMA))
|
||||
var/move_and_fall = stat == SOFT_CRIT && !pulledby
|
||||
var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
|
||||
var/buckle_lying = !(buckled && !buckled.buckle_lying)
|
||||
var/has_legs = get_num_legs()
|
||||
var/has_arms = get_num_arms()
|
||||
var/ignore_legs = get_leg_ignore()
|
||||
var/pinned = resting && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE // Cit change - adds pinning for aggressive-grabbing people on the ground
|
||||
if(ko || move_and_fall || IsStun() || chokehold) // Cit change - makes resting not force you to drop everything
|
||||
drop_all_held_items()
|
||||
unset_machine()
|
||||
if(pulling)
|
||||
stop_pulling()
|
||||
else if(resting) //CIT CHANGE - makes resting make you stop pulling and interacting with machines
|
||||
unset_machine() //CIT CHANGE - Ditto!
|
||||
if(pulling) //CIT CHANGE - Ditto.
|
||||
stop_pulling() //CIT CHANGE - Ditto...
|
||||
else if(has_legs || ignore_legs)
|
||||
lying = 0
|
||||
if (pulledby && isliving(pulledby))
|
||||
var/mob/living/L = pulledby
|
||||
L.update_pull_movespeed()
|
||||
if(buckled)
|
||||
lying = 90*buckle_lying
|
||||
else if(!lying)
|
||||
if(resting)
|
||||
lying = pick(90, 270) // Cit change - makes resting not force you to drop your held items
|
||||
if(has_gravity()) // Cit change - Ditto
|
||||
playsound(src, "bodyfall", 50, 1) // Cit change - Ditto!
|
||||
else if(ko || move_and_fall || (!has_legs && !ignore_legs) || chokehold)
|
||||
fall(forced = 1)
|
||||
canmove = !(ko || recoveringstam || pinned || IsStun() || IsFrozen() || chokehold || buckled || (!has_legs && !ignore_legs && !has_arms)) //Cit change - makes it plausible to move while resting, adds pinning and stamina crit
|
||||
density = !lying
|
||||
if(resting)
|
||||
ENABLE_BITFIELD(movement_type, CRAWLING)
|
||||
else
|
||||
DISABLE_BITFIELD(movement_type, CRAWLING)
|
||||
if(lying)
|
||||
if(layer == initial(layer)) //to avoid special cases like hiding larvas.
|
||||
layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
|
||||
else
|
||||
if(layer == LYING_MOB_LAYER)
|
||||
layer = initial(layer)
|
||||
update_transform()
|
||||
if(!lying && lying_prev)
|
||||
if(client)
|
||||
client.move_delay = world.time + movement_delay()
|
||||
lying_prev = lying
|
||||
if(canmove && !intentionalresting && iscarbon(src) && client && client.prefs && client.prefs.autostand)//CIT CHANGE - adds autostanding as a preference
|
||||
addtimer(CALLBACK(src, .proc/resist_a_rest, TRUE), 0) //CIT CHANGE - ditto
|
||||
return canmove
|
||||
|
||||
/mob/living/proc/AddAbility(obj/effect/proc_holder/A)
|
||||
abilities.Add(A)
|
||||
A.on_gain(src)
|
||||
@@ -1140,42 +1098,6 @@
|
||||
return LINGHIVE_LINK
|
||||
return LINGHIVE_NONE
|
||||
|
||||
/mob/living/forceMove(atom/destination)
|
||||
stop_pulling()
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src, force = TRUE)
|
||||
if(has_buckled_mobs())
|
||||
unbuckle_all_mobs(force = TRUE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(client)
|
||||
reset_perspective()
|
||||
update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall.
|
||||
|
||||
/mob/living/proc/update_z(new_z) // 1+ to register, null to unregister
|
||||
if(isnull(new_z) && audiovisual_redirect)
|
||||
return
|
||||
if (registered_z != new_z)
|
||||
if (registered_z)
|
||||
SSmobs.clients_by_zlevel[registered_z] -= src
|
||||
if (client || audiovisual_redirect)
|
||||
if (new_z)
|
||||
SSmobs.clients_by_zlevel[new_z] += src
|
||||
for (var/I in length(SSidlenpcpool.idle_mobs_by_zlevel[new_z]) to 1 step -1) //Backwards loop because we're removing (guarantees optimal rather than worst-case performance), it's fine to use .len here but doesn't compile on 511
|
||||
var/mob/living/simple_animal/SA = SSidlenpcpool.idle_mobs_by_zlevel[new_z][I]
|
||||
if (SA)
|
||||
SA.toggle_ai(AI_ON) // Guarantees responsiveness for when appearing right next to mobs
|
||||
else
|
||||
SSidlenpcpool.idle_mobs_by_zlevel[new_z] -= SA
|
||||
|
||||
registered_z = new_z
|
||||
else
|
||||
registered_z = null
|
||||
|
||||
/mob/living/onTransitZ(old_z,new_z)
|
||||
..()
|
||||
update_z(new_z)
|
||||
|
||||
/mob/living/MouseDrop(mob/over)
|
||||
. = ..()
|
||||
var/mob/living/user = usr
|
||||
@@ -1222,14 +1144,6 @@
|
||||
GLOB.dead_mob_list += src
|
||||
. = ..()
|
||||
switch(var_name)
|
||||
if("knockdown")
|
||||
SetKnockdown(var_value)
|
||||
if("stun")
|
||||
SetStun(var_value)
|
||||
if("unconscious")
|
||||
SetUnconscious(var_value)
|
||||
if("sleeping")
|
||||
SetSleeping(var_value)
|
||||
if("eye_blind")
|
||||
set_blindness(var_value)
|
||||
if("eye_damage")
|
||||
@@ -1261,21 +1175,26 @@
|
||||
SetSleeping(clamp_unconscious_to)
|
||||
if(AmountUnconscious() > clamp_unconscious_to)
|
||||
SetUnconscious(clamp_unconscious_to)
|
||||
if(AmountStun() > clamp_immobility_to)
|
||||
SetStun(clamp_immobility_to)
|
||||
if(AmountKnockdown() > clamp_immobility_to)
|
||||
SetKnockdown(clamp_immobility_to)
|
||||
HealAllImmobilityUpTo(clamp_immobility_to)
|
||||
adjustStaminaLoss(min(0, -stamina_boost))
|
||||
adjustStaminaLossBuffered(min(0, -stamina_buffer_boost))
|
||||
if(scale_stamina_loss_recovery)
|
||||
adjustStaminaLoss(min(-((getStaminaLoss() - stamina_loss_recovery_bypass) * scale_stamina_loss_recovery), 0))
|
||||
if(put_on_feet)
|
||||
resting = FALSE
|
||||
lying = FALSE
|
||||
set_resting(FALSE, TRUE, FALSE)
|
||||
if(reset_misc)
|
||||
stuttering = 0
|
||||
updatehealth()
|
||||
update_stamina()
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
if(healing_chems)
|
||||
reagents.add_reagent_list(healing_chems)
|
||||
|
||||
/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
|
||||
|
||||
@@ -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_state()
|
||||
|
||||
/// 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>")
|
||||
@@ -250,7 +250,7 @@
|
||||
return 0
|
||||
if(user.voremode && user.grab_state == GRAB_AGGRESSIVE)
|
||||
return 0
|
||||
user.grab_state++
|
||||
user.setGrabState(user.grab_state + 1)
|
||||
switch(user.grab_state)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
var/add_log = ""
|
||||
@@ -261,21 +261,21 @@
|
||||
else
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
|
||||
"<span class='userdanger'>[user] has grabbed you aggressively!</span>")
|
||||
drop_all_held_items()
|
||||
update_mobility()
|
||||
stop_pulling()
|
||||
log_combat(user, src, "grabbed", addition="aggressive grab[add_log]")
|
||||
if(GRAB_NECK)
|
||||
log_combat(user, src, "grabbed", addition="neck grab")
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
|
||||
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
|
||||
update_canmove() //we fall down
|
||||
update_mobility() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
if(GRAB_KILL)
|
||||
log_combat(user, src, "strangled", addition="kill grab")
|
||||
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
|
||||
"<span class='userdanger'>[user] is strangling you!</span>")
|
||||
update_canmove() //we fall down
|
||||
update_mobility() //we fall down
|
||||
if(!buckled && !density)
|
||||
Move(user.loc)
|
||||
return 1
|
||||
@@ -427,14 +427,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>", \
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
var/staminaloss = 0 //Stamina damage, or exhaustion. You recover it slowly naturally, and are knocked down if it gets too high. Holodeck and hallucinations deal this.
|
||||
var/crit_threshold = HEALTH_THRESHOLD_CRIT // when the mob goes from "normal" to crit
|
||||
|
||||
var/mobility_flags = MOBILITY_FLAGS_DEFAULT
|
||||
|
||||
var/confused = 0 //Makes the mob move in random directions.
|
||||
|
||||
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
|
||||
@@ -114,4 +116,26 @@
|
||||
|
||||
var/drag_slowdown = TRUE //Whether the mob is slowed down when dragging another prone mob
|
||||
|
||||
var/rotate_on_lying = FALSE
|
||||
var/rotate_on_lying = FALSE
|
||||
|
||||
/// 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
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/// IN THE FUTURE, WE WILL PROBABLY REFACTOR TO LESSEN THE NEED FOR UPDATE_MOBILITY, BUT FOR NOW.. WE CAN START DOING THIS.
|
||||
/// FOR BLOCKING MOVEMENT, USE TRAIT_MOBILITY_NOMOVE AS MUCH AS POSSIBLE. IT WILL MAKE REFACTORS IN THE FUTURE EASIER.
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOMOVE), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility)
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility)
|
||||
|
||||
//Stuff like mobility flag updates, resting updates, etc.
|
||||
|
||||
//Force-set resting variable, without needing to resist/etc.
|
||||
/mob/living/proc/set_resting(new_resting, silent = FALSE, updating = TRUE)
|
||||
if(new_resting != resting)
|
||||
resting = new_resting
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='notice'>You are now [resting? "resting" : "getting up"].</span>")
|
||||
update_resting(updating)
|
||||
|
||||
/mob/living/proc/update_resting(update_mobility = TRUE)
|
||||
if(update_mobility)
|
||||
update_mobility()
|
||||
|
||||
//Force mob to rest, does NOT do stamina damage.
|
||||
//It's really not recommended to use this proc to give feedback, hence why silent is defaulting to true.
|
||||
/mob/living/proc/KnockToFloor(disarm_items = FALSE, silent = TRUE, updating = TRUE)
|
||||
if(!silent && !resting)
|
||||
to_chat(src, "<span class='warning'>You are knocked to the floor!</span>")
|
||||
set_resting(TRUE, TRUE, updating)
|
||||
if(disarm_items)
|
||||
drop_all_held_items()
|
||||
|
||||
/mob/living/proc/lay_down()
|
||||
set name = "Rest"
|
||||
set category = "IC"
|
||||
if(client?.prefs?.autostand)
|
||||
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()
|
||||
else
|
||||
if(!resting)
|
||||
set_resting(TRUE, FALSE)
|
||||
to_chat(src, "<span class='notice'>You are now laying down.</span>")
|
||||
else
|
||||
resist_a_rest()
|
||||
|
||||
/mob/living/proc/resist_a_rest(automatic = FALSE, ignoretimer = FALSE) //Lets mobs resist out of resting. Major QOL change with combat reworks.
|
||||
set_resting(FALSE, TRUE)
|
||||
return TRUE
|
||||
|
||||
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
|
||||
//Robots, animals and brains have their own version so don't worry about them
|
||||
/mob/living/proc/update_mobility()
|
||||
var/stat_softcrit = stat == SOFT_CRIT
|
||||
var/stat_conscious = (stat == CONSCIOUS) || stat_softcrit
|
||||
|
||||
var/conscious = !IsUnconscious() && stat_conscious && !HAS_TRAIT(src, TRAIT_DEATHCOMA)
|
||||
|
||||
var/has_arms = get_num_arms()
|
||||
var/has_legs = get_num_legs()
|
||||
var/ignore_legs = get_leg_ignore()
|
||||
var/stun = IsStun()
|
||||
var/paralyze = IsParalyzed()
|
||||
var/knockdown = IsKnockdown()
|
||||
var/daze = IsDazed()
|
||||
var/immobilize = IsImmobilized()
|
||||
|
||||
var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
|
||||
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 && !(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
|
||||
else
|
||||
mobility_flags &= ~MOBILITY_MOVE
|
||||
|
||||
if(canresist)
|
||||
mobility_flags |= MOBILITY_RESIST
|
||||
else
|
||||
mobility_flags &= ~MOBILITY_RESIST
|
||||
|
||||
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
|
||||
if(buckled)
|
||||
if(buckled.buckle_lying != -1)
|
||||
should_be_lying = buckled.buckle_lying
|
||||
|
||||
if(should_be_lying)
|
||||
mobility_flags &= ~MOBILITY_STAND
|
||||
if(!lying) //force them on the ground
|
||||
lying = pick(90, 270)
|
||||
if(has_gravity() && !buckled)
|
||||
playsound(src, "bodyfall", 20, 1)
|
||||
else
|
||||
mobility_flags |= MOBILITY_STAND
|
||||
lying = 0
|
||||
|
||||
if(should_be_lying || restrained || incapacitated())
|
||||
mobility_flags &= ~(MOBILITY_UI|MOBILITY_PULL)
|
||||
else
|
||||
mobility_flags |= MOBILITY_UI|MOBILITY_PULL
|
||||
|
||||
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
|
||||
mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE | MOBILITY_HOLD)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_MOBILITY_NOMOVE))
|
||||
DISABLE_BITFIELD(mobility_flags, MOBILITY_MOVE)
|
||||
if(HAS_TRAIT(src, TRAIT_MOBILITY_NOPICKUP))
|
||||
DISABLE_BITFIELD(mobility_flags, MOBILITY_PICKUP)
|
||||
if(HAS_TRAIT(src, TRAIT_MOBILITY_NOUSE))
|
||||
DISABLE_BITFIELD(mobility_flags, MOBILITY_USE)
|
||||
|
||||
if(daze)
|
||||
DISABLE_BITFIELD(mobility_flags, MOBILITY_USE)
|
||||
|
||||
//Handle update-effects.
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_HOLD))
|
||||
drop_all_held_items()
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_PULL))
|
||||
if(pulling)
|
||||
stop_pulling()
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_UI))
|
||||
unset_machine()
|
||||
|
||||
if(isliving(pulledby))
|
||||
var/mob/living/L = pulledby
|
||||
L.update_pull_movespeed()
|
||||
|
||||
//Handle lying down, voluntary or involuntary
|
||||
density = !lying
|
||||
if(lying)
|
||||
set_resting(TRUE, TRUE, FALSE)
|
||||
if(layer == initial(layer)) //to avoid special cases like hiding larvas.
|
||||
layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs
|
||||
else
|
||||
if(layer == LYING_MOB_LAYER)
|
||||
layer = initial(layer)
|
||||
update_transform()
|
||||
lying_prev = lying
|
||||
|
||||
//Handle citadel autoresist
|
||||
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
|
||||
if(!get_leg_ignore())
|
||||
var/limbless_slowdown = 0
|
||||
// These checks for <2 should be swapped out for something else if we ever end up with a species with more than 2
|
||||
if(has_legs < 2)
|
||||
limbless_slowdown += 6 - (has_legs * 3)
|
||||
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)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
|
||||
|
||||
return mobility_flags
|
||||
@@ -3,6 +3,10 @@
|
||||
update_turf_movespeed(loc)
|
||||
//Hide typing indicator if we move.
|
||||
clear_typing_indicator()
|
||||
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))
|
||||
@@ -14,10 +18,14 @@
|
||||
return (!density || lying)
|
||||
if(buckled == mover)
|
||||
return TRUE
|
||||
if(ismob(mover))
|
||||
if (mover in buckled_mobs)
|
||||
if(!ismob(mover))
|
||||
if(mover.throwing?.thrower == src)
|
||||
return TRUE
|
||||
return (!mover.density || !density || lying || (mover.throwing && mover.throwing.thrower == src && !ismob(mover)))
|
||||
if(ismob(mover))
|
||||
if(mover in buckled_mobs)
|
||||
return TRUE
|
||||
var/mob/living/L = mover //typecast first, check isliving and only check this if living using short circuit
|
||||
return (!density || (isliving(mover)? L.can_move_under_living(src) : !mover.density))
|
||||
|
||||
/mob/living/toggle_move_intent()
|
||||
. = ..()
|
||||
@@ -25,8 +33,20 @@
|
||||
|
||||
/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
|
||||
|
||||
/mob/living/proc/update_move_intent_slowdown()
|
||||
var/mod = 0
|
||||
if(m_intent == MOVE_INTENT_WALK)
|
||||
@@ -52,4 +72,69 @@
|
||||
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
|
||||
|
||||
/mob/living/canZMove(dir, turf/target)
|
||||
return can_zTravel(target, dir) && (movement_type & FLYING)
|
||||
return can_zTravel(target, dir) && (movement_type & FLYING)
|
||||
|
||||
/mob/living/Move(atom/newloc, direct)
|
||||
if (buckled && buckled.loc != newloc) //not updating position
|
||||
if (!buckled.anchored)
|
||||
return buckled.Move(newloc, direct)
|
||||
else
|
||||
return 0
|
||||
|
||||
var/old_direction = dir
|
||||
var/turf/T = loc
|
||||
|
||||
if(pulling)
|
||||
update_pull_movespeed()
|
||||
|
||||
. = ..()
|
||||
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if(active_storage && !(CanReach(active_storage.parent,view_only = TRUE)))
|
||||
active_storage.close(src)
|
||||
|
||||
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
|
||||
makeTrail(newloc, T, old_direction)
|
||||
|
||||
/mob/living/forceMove(atom/destination)
|
||||
stop_pulling()
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src, force = TRUE)
|
||||
if(has_buckled_mobs())
|
||||
unbuckle_all_mobs(force = TRUE)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(client)
|
||||
reset_perspective()
|
||||
update_mobility() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall.
|
||||
|
||||
/mob/living/proc/update_z(new_z) // 1+ to register, null to unregister
|
||||
if(isnull(new_z) && audiovisual_redirect)
|
||||
return
|
||||
if (registered_z != new_z)
|
||||
if (registered_z)
|
||||
SSmobs.clients_by_zlevel[registered_z] -= src
|
||||
if (client || audiovisual_redirect)
|
||||
if (new_z)
|
||||
SSmobs.clients_by_zlevel[new_z] += src
|
||||
for (var/I in length(SSidlenpcpool.idle_mobs_by_zlevel[new_z]) to 1 step -1) //Backwards loop because we're removing (guarantees optimal rather than worst-case performance), it's fine to use .len here but doesn't compile on 511
|
||||
var/mob/living/simple_animal/SA = SSidlenpcpool.idle_mobs_by_zlevel[new_z][I]
|
||||
if (SA)
|
||||
SA.toggle_ai(AI_ON) // Guarantees responsiveness for when appearing right next to mobs
|
||||
else
|
||||
SSidlenpcpool.idle_mobs_by_zlevel[new_z] -= SA
|
||||
|
||||
registered_z = new_z
|
||||
else
|
||||
registered_z = null
|
||||
|
||||
/mob/living/onTransitZ(old_z,new_z)
|
||||
..()
|
||||
update_z(new_z)
|
||||
|
||||
/mob/living/canface()
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_MOVE))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -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_state()
|
||||
|
||||
/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()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
icon_state = "ai"
|
||||
move_resist = MOVE_FORCE_OVERPOWERING
|
||||
density = TRUE
|
||||
canmove = FALSE
|
||||
mobility_flags = ALL
|
||||
status_flags = CANSTUN|CANPUSH
|
||||
a_intent = INTENT_HARM //so we always get pushed instead of trying to swap
|
||||
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS
|
||||
@@ -324,8 +324,10 @@
|
||||
to_chat(src, "<b>You are now [is_anchored ? "" : "un"]anchored.</b>")
|
||||
// the message in the [] will change depending whether or not the AI is anchored
|
||||
|
||||
/mob/living/silicon/ai/update_canmove() //If the AI dies, mobs won't go through it anymore
|
||||
return 0
|
||||
// AIs are immobile
|
||||
/mob/living/silicon/ai/update_mobility()
|
||||
mobility_flags = ALL
|
||||
return ALL
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_cancel_call()
|
||||
set category = "Malfunction"
|
||||
@@ -987,7 +989,7 @@
|
||||
deployed_shell.undeploy()
|
||||
diag_hud_set_deployed()
|
||||
|
||||
/mob/living/silicon/ai/resist()
|
||||
/mob/living/silicon/ai/do_resist()
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/spawned/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
|
||||
@@ -1002,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
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
cameraFollow = null
|
||||
|
||||
move_resist = MOVE_FORCE_NORMAL
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
if(eyeobj)
|
||||
eyeobj.setLoc(get_turf(src))
|
||||
set_eyeobj_visible(FALSE)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
canmove = 0
|
||||
update_mobility()
|
||||
update_sight()
|
||||
clear_fullscreens()
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -80,7 +79,7 @@
|
||||
var/radio_short_cooldown = 3 MINUTES
|
||||
var/radio_short_timerid
|
||||
|
||||
canmove = FALSE
|
||||
mobility_flags = NONE
|
||||
var/silent = FALSE
|
||||
var/brightness_power = 5
|
||||
|
||||
@@ -101,7 +100,6 @@
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pai_list += src
|
||||
make_laws()
|
||||
canmove = 0
|
||||
if(!istype(P)) //when manually spawning a pai, we create a card to put it into.
|
||||
var/newcardloc = P
|
||||
P = new /obj/item/paicard(newcardloc)
|
||||
@@ -143,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()
|
||||
@@ -303,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.")
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
if(. & EMP_PROTECT_SELF)
|
||||
return
|
||||
take_holo_damage(50/severity)
|
||||
Knockdown(400/severity)
|
||||
DefaultCombatKnockdown(400/severity)
|
||||
silent = max(silent, (PAI_EMP_SILENCE_DURATION) / SSmobs.wait / severity)
|
||||
if(holoform)
|
||||
fold_in(force = TRUE)
|
||||
@@ -23,10 +23,10 @@
|
||||
qdel(src)
|
||||
if(2)
|
||||
fold_in(force = 1)
|
||||
Knockdown(400)
|
||||
DefaultCombatKnockdown(400)
|
||||
if(3)
|
||||
fold_in(force = 1)
|
||||
Knockdown(200)
|
||||
DefaultCombatKnockdown(200)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user)
|
||||
@@ -98,7 +98,7 @@
|
||||
take_holo_damage(amount * 0.25)
|
||||
|
||||
/mob/living/silicon/pai/adjustOrganLoss(slot, amount, maximum = 500) //I kept this in, unlike tg
|
||||
Knockdown(amount * 0.2)
|
||||
DefaultCombatKnockdown(amount * 0.2)
|
||||
|
||||
/mob/living/silicon/pai/getBruteLoss()
|
||||
return emittermaxhealth - emitterhealth
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
return FALSE
|
||||
|
||||
emitter_next_use = world.time + emittercd
|
||||
canmove = TRUE
|
||||
density = TRUE
|
||||
if(istype(card.loc, /obj/item/pda))
|
||||
var/obj/item/pda/P = card.loc
|
||||
@@ -37,6 +36,7 @@
|
||||
C.push_data()
|
||||
forceMove(get_turf(card))
|
||||
card.forceMove(src)
|
||||
update_mobility()
|
||||
if(client)
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
client.eye = src
|
||||
@@ -63,12 +63,11 @@
|
||||
var/turf/T = drop_location()
|
||||
card.forceMove(T)
|
||||
forceMove(card)
|
||||
canmove = FALSE
|
||||
density = FALSE
|
||||
set_light(0)
|
||||
holoform = FALSE
|
||||
if(resting)
|
||||
lay_down()
|
||||
set_resting(FALSE, TRUE, FALSE)
|
||||
update_mobility()
|
||||
|
||||
/mob/living/silicon/pai/proc/choose_chassis()
|
||||
if(!isturf(loc) && loc != card)
|
||||
@@ -77,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
|
||||
@@ -96,12 +96,10 @@
|
||||
dynamic_chassis = choice
|
||||
resist_a_rest(FALSE, TRUE)
|
||||
update_icon()
|
||||
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', SLOT_HEAD)
|
||||
else
|
||||
current_mob_holder?.Detach(src)
|
||||
current_mob_holder = null
|
||||
return
|
||||
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()
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
locked = FALSE //unlock cover
|
||||
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
if(!QDELETED(builtInCamera) && builtInCamera.status)
|
||||
builtInCamera.toggle_cam(src,0)
|
||||
update_headlamp(1) //So borg lights are disabled when killed.
|
||||
|
||||
@@ -91,12 +91,3 @@
|
||||
add_overlay(fire_overlay)
|
||||
else
|
||||
cut_overlay(fire_overlay)
|
||||
|
||||
/mob/living/silicon/robot/update_canmove()
|
||||
if(stat || buckled || lockcharge || resting) //CITADEL EDIT resting dogborg-os
|
||||
canmove = 0
|
||||
else
|
||||
canmove = 1
|
||||
update_transform()
|
||||
update_action_buttons_icon()
|
||||
return canmove
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
|
||||
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
|
||||
var/lockcharge //Boolean of whether the borg is locked down or not
|
||||
var/locked_down //Boolean of whether the borg is locked down or not
|
||||
|
||||
var/toner = 0
|
||||
var/tonermax = 40
|
||||
@@ -493,7 +493,7 @@
|
||||
update_icons()
|
||||
|
||||
else if(istype(W, /obj/item/wrench) && opened && !cell) //Deconstruction. The flashes break from the fall, to prevent this from being a ghetto reset module.
|
||||
if(!lockcharge)
|
||||
if(!locked_down)
|
||||
to_chat(user, "<span class='boldannounce'>[src]'s bolts spark! Maybe you should lock them down first!</span>")
|
||||
spark_system.start()
|
||||
return
|
||||
@@ -655,65 +655,6 @@
|
||||
/mob/living/silicon/robot/regenerate_icons()
|
||||
return update_icons()
|
||||
|
||||
/mob/living/silicon/robot/update_icons()
|
||||
cut_overlays()
|
||||
icon_state = module.cyborg_base_icon
|
||||
//Citadel changes start here - Allows modules to use different icon files, and allows modules to specify a pixel offset
|
||||
icon = (module.cyborg_icon_override ? module.cyborg_icon_override : initial(icon))
|
||||
if(laser)
|
||||
add_overlay("laser")//Is this even used??? - Yes borg/inventory.dm
|
||||
if(disabler)
|
||||
add_overlay("disabler")//ditto
|
||||
|
||||
if(sleeper_g && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_g[sleeper_nv ? "_nv" : ""]")
|
||||
if(sleeper_r && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_r[sleeper_nv ? "_nv" : ""]")
|
||||
if(stat == DEAD && module.has_snowflake_deadsprite)
|
||||
icon_state = "[module.cyborg_base_icon]-wreck"
|
||||
|
||||
if(module.cyborg_pixel_offset)
|
||||
pixel_x = module.cyborg_pixel_offset
|
||||
//End of citadel changes
|
||||
|
||||
if(module.cyborg_base_icon == "robot")
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
pixel_x = initial(pixel_x)
|
||||
if(stat != DEAD && !(IsUnconscious() || IsStun() || IsKnockdown() || low_power_mode)) //Not dead, not stunned.
|
||||
if(!eye_lights)
|
||||
eye_lights = new()
|
||||
if(lamp_intensity > 2)
|
||||
eye_lights.icon_state = "[module.special_light_key ? "[module.special_light_key]":"[module.cyborg_base_icon]"]_l"
|
||||
else
|
||||
eye_lights.icon_state = "[module.special_light_key ? "[module.special_light_key]":"[module.cyborg_base_icon]"]_e[is_servant_of_ratvar(src) ? "_r" : ""]"
|
||||
eye_lights.icon = icon
|
||||
add_overlay(eye_lights)
|
||||
|
||||
if(opened)
|
||||
if(wiresexposed)
|
||||
add_overlay("ov-opencover +w")
|
||||
else if(cell)
|
||||
add_overlay("ov-opencover +c")
|
||||
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')
|
||||
head_overlay.pixel_y += hat_offset
|
||||
add_overlay(head_overlay)
|
||||
update_fire()
|
||||
|
||||
if(client && stat != DEAD && module.dogborg == TRUE)
|
||||
if(resting)
|
||||
if(sitting)
|
||||
icon_state = "[module.cyborg_base_icon]-sit"
|
||||
if(bellyup)
|
||||
icon_state = "[module.cyborg_base_icon]-bellyup"
|
||||
else if(!sitting && !bellyup)
|
||||
icon_state = "[module.cyborg_base_icon]-rest"
|
||||
cut_overlays()
|
||||
else
|
||||
icon_state = "[module.cyborg_base_icon]"
|
||||
|
||||
/mob/living/silicon/robot/proc/self_destruct()
|
||||
if(emagged)
|
||||
if(mmi)
|
||||
@@ -728,8 +669,6 @@
|
||||
connected_ai.connected_robots -= src
|
||||
src.connected_ai = null
|
||||
lawupdate = 0
|
||||
lockcharge = 0
|
||||
canmove = 1
|
||||
scrambledcodes = 1
|
||||
//Disconnect it's camera so it's not so easily tracked.
|
||||
if(!QDELETED(builtInCamera))
|
||||
@@ -738,6 +677,7 @@
|
||||
// Instead of being listed as "deactivated". The downside is that I'm going
|
||||
// to have to check if every camera is null or not before doing anything, to prevent runtime errors.
|
||||
// I could change the network to null but I don't know what would happen, and it seems too hacky for me.
|
||||
update_mobility()
|
||||
|
||||
/mob/living/silicon/robot/mode()
|
||||
set name = "Activate Held Object"
|
||||
@@ -759,8 +699,8 @@
|
||||
throw_alert("locked", /obj/screen/alert/locked)
|
||||
else
|
||||
clear_alert("locked")
|
||||
lockcharge = state
|
||||
update_canmove()
|
||||
locked_down = state
|
||||
update_mobility()
|
||||
|
||||
/mob/living/silicon/robot/proc/SetEmagged(new_state)
|
||||
emagged = new_state
|
||||
@@ -949,7 +889,7 @@
|
||||
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Remote telemetry lost with [name].</span><br>")
|
||||
|
||||
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
if(stat || lockcharge || low_power_mode)
|
||||
if(stat || locked_down || low_power_mode)
|
||||
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
|
||||
return FALSE
|
||||
if(be_close && !in_range(M, src))
|
||||
@@ -1025,17 +965,18 @@
|
||||
if(health <= -maxHealth) //die only once
|
||||
death()
|
||||
return
|
||||
if(IsUnconscious() || IsStun() || IsKnockdown() || getOxyLoss() > maxHealth*0.5)
|
||||
if(IsUnconscious() || IsStun() || IsParalyzed() || getOxyLoss() > maxHealth*0.5)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
update_canmove()
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
update_mobility()
|
||||
update_headlamp()
|
||||
else
|
||||
if(stat == UNCONSCIOUS)
|
||||
stat = CONSCIOUS
|
||||
adjust_blindness(-1)
|
||||
update_canmove()
|
||||
update_mobility()
|
||||
update_headlamp()
|
||||
diag_hud_set_status()
|
||||
diag_hud_set_health()
|
||||
@@ -1175,6 +1116,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(!..())
|
||||
@@ -1269,20 +1211,6 @@
|
||||
for(var/i in connected_ai.aicamera.stored)
|
||||
aicamera.stored[i] = TRUE
|
||||
|
||||
/mob/living/silicon/robot/lay_down()
|
||||
..()
|
||||
update_canmove()
|
||||
|
||||
/mob/living/silicon/robot/update_canmove()
|
||||
..()
|
||||
if(client && stat != DEAD && dogborg == FALSE)
|
||||
if(resting)
|
||||
cut_overlays()
|
||||
icon_state = "[module.cyborg_base_icon]-rest"
|
||||
else
|
||||
icon_state = "[module.cyborg_base_icon]"
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/proc/rest_style()
|
||||
set name = "Switch Rest Style"
|
||||
set category = "Robot Commands"
|
||||
@@ -1310,4 +1238,4 @@
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
ai_roster()
|
||||
ai_roster()
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"<span class='userdanger'>[M] has disabled [src]'s active module!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
|
||||
else
|
||||
Stun(40)
|
||||
Paralyze(40)
|
||||
step(src,get_dir(M,src))
|
||||
log_combat(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has forced back [src]!</span>", \
|
||||
@@ -86,9 +86,9 @@
|
||||
return
|
||||
switch(severity)
|
||||
if(1)
|
||||
Stun(160)
|
||||
Paralyze(160)
|
||||
if(2)
|
||||
Stun(60)
|
||||
Paralyze(60)
|
||||
|
||||
|
||||
/mob/living/silicon/robot/emag_act(mob/user)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/mob/living/silicon/robot/update_mobility()
|
||||
var/newflags = NONE
|
||||
if(!stat)
|
||||
if(!resting)
|
||||
newflags |= (MOBILITY_STAND | MOBILITY_RESIST)
|
||||
if(!locked_down)
|
||||
newflags |= MOBILITY_MOVE
|
||||
newflags |= MOBILITY_PULL
|
||||
if(!locked_down)
|
||||
newflags |= MOBILITY_FLAGS_ANY_INTERACTION
|
||||
mobility_flags = newflags
|
||||
update_transform()
|
||||
update_action_buttons_icon()
|
||||
update_icons()
|
||||
return mobility_flags
|
||||
@@ -97,8 +97,8 @@
|
||||
var/obj/item/stack/S = I
|
||||
|
||||
if(is_type_in_list(S, list(/obj/item/stack/sheet/metal, /obj/item/stack/rods, /obj/item/stack/tile/plasteel)))
|
||||
if(S.custom_materials?.len && S.custom_materials[getmaterialref(/datum/material/iron)])
|
||||
S.cost = S.custom_materials[getmaterialref(/datum/material/iron)] * 0.25
|
||||
if(S.custom_materials?.len && S.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)])
|
||||
S.cost = S.custom_materials[SSmaterials.GetMaterialRef(/datum/material/iron)] * 0.25
|
||||
S.source = get_or_create_estorage(/datum/robot_energy_storage/metal)
|
||||
|
||||
else if(istype(S, /obj/item/stack/sheet/glass))
|
||||
@@ -257,7 +257,7 @@
|
||||
|
||||
/obj/item/robot_module/proc/do_transform_delay()
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/prev_lockcharge = R.lockcharge
|
||||
var/prev_locked_down = R.locked_down
|
||||
sleep(1)
|
||||
flick("[cyborg_base_icon]_transform", R)
|
||||
R.notransform = TRUE
|
||||
@@ -267,7 +267,7 @@
|
||||
for(var/i in 1 to 4)
|
||||
playsound(R, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, 1, -1)
|
||||
sleep(7)
|
||||
if(!prev_lockcharge)
|
||||
if(!prev_locked_down)
|
||||
R.SetLockdown(0)
|
||||
R.setDir(SOUTH)
|
||||
R.anchored = FALSE
|
||||
@@ -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)
|
||||
@@ -0,0 +1,59 @@
|
||||
/// this is bad code
|
||||
/mob/living/silicon/robot/update_icons()
|
||||
cut_overlays()
|
||||
icon_state = module.cyborg_base_icon
|
||||
//Citadel changes start here - Allows modules to use different icon files, and allows modules to specify a pixel offset
|
||||
icon = (module.cyborg_icon_override ? module.cyborg_icon_override : initial(icon))
|
||||
if(laser)
|
||||
add_overlay("laser")//Is this even used??? - Yes borg/inventory.dm
|
||||
if(disabler)
|
||||
add_overlay("disabler")//ditto
|
||||
|
||||
if(sleeper_g && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_g[sleeper_nv ? "_nv" : ""]")
|
||||
if(sleeper_r && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_r[sleeper_nv ? "_nv" : ""]")
|
||||
if(stat == DEAD && module.has_snowflake_deadsprite)
|
||||
icon_state = "[module.cyborg_base_icon]-wreck"
|
||||
|
||||
if(module.cyborg_pixel_offset)
|
||||
pixel_x = module.cyborg_pixel_offset
|
||||
//End of citadel changes
|
||||
|
||||
if(module.cyborg_base_icon == "robot")
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
pixel_x = initial(pixel_x)
|
||||
if(stat != DEAD && !(IsUnconscious() ||IsStun() || IsKnockdown() || IsParalyzed() || low_power_mode)) //Not dead, not stunned.
|
||||
if(!eye_lights)
|
||||
eye_lights = new()
|
||||
if(lamp_intensity > 2)
|
||||
eye_lights.icon_state = "[module.special_light_key ? "[module.special_light_key]":"[module.cyborg_base_icon]"]_l"
|
||||
else
|
||||
eye_lights.icon_state = "[module.special_light_key ? "[module.special_light_key]":"[module.cyborg_base_icon]"]_e[is_servant_of_ratvar(src) ? "_r" : ""]"
|
||||
eye_lights.icon = icon
|
||||
add_overlay(eye_lights)
|
||||
|
||||
if(opened)
|
||||
if(wiresexposed)
|
||||
add_overlay("ov-opencover +w")
|
||||
else if(cell)
|
||||
add_overlay("ov-opencover +c")
|
||||
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')
|
||||
head_overlay.pixel_y += hat_offset
|
||||
add_overlay(head_overlay)
|
||||
update_fire()
|
||||
|
||||
if(client && stat != DEAD && module.dogborg == TRUE)
|
||||
if(resting)
|
||||
if(sitting)
|
||||
icon_state = "[module.cyborg_base_icon]-sit"
|
||||
if(bellyup)
|
||||
icon_state = "[module.cyborg_base_icon]-bellyup"
|
||||
else if(!sitting && !bellyup)
|
||||
icon_state = "[module.cyborg_base_icon]-rest"
|
||||
cut_overlays()
|
||||
else
|
||||
icon_state = "[module.cyborg_base_icon]"
|
||||
@@ -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
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(prob(damage))
|
||||
for(var/mob/living/N in buckled_mobs)
|
||||
N.Knockdown(20)
|
||||
N.DefaultCombatKnockdown(20)
|
||||
unbuckle_mob(N)
|
||||
N.visible_message("<span class='boldwarning'>[N] is knocked off of [src] by [M]!</span>")
|
||||
switch(M.melee_damage_type)
|
||||
@@ -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)
|
||||
@@ -106,7 +106,7 @@
|
||||
for(var/mob/living/M in buckled_mobs)
|
||||
if(prob(severity*50))
|
||||
unbuckle_mob(M)
|
||||
M.Knockdown(40)
|
||||
M.DefaultCombatKnockdown(40)
|
||||
M.visible_message("<span class='boldwarning'>[M] is thrown off of [src]!</span>")
|
||||
flash_act(affect_silicon = 1)
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
for(var/mob/living/M in buckled_mobs)
|
||||
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src]!</span>")
|
||||
unbuckle_mob(M)
|
||||
M.Knockdown(40)
|
||||
M.DefaultCombatKnockdown(40)
|
||||
if(P.stun || P.knockdown)
|
||||
for(var/mob/living/M in buckled_mobs)
|
||||
unbuckle_mob(M)
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
/mob/living/simple_animal/astral/death()
|
||||
icon_state = "shade_dead"
|
||||
Stun(1000)
|
||||
canmove = 0
|
||||
friendly = "deads at"
|
||||
pseudo_death = TRUE
|
||||
incorporeal_move = 0
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
if(stat)
|
||||
return FALSE
|
||||
on = TRUE
|
||||
canmove = TRUE
|
||||
update_mobility()
|
||||
set_light(initial(light_range))
|
||||
update_icon()
|
||||
diag_hud_set_botstat()
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/proc/turn_off()
|
||||
on = FALSE
|
||||
canmove = FALSE
|
||||
update_mobility()
|
||||
set_light(0)
|
||||
bot_reset() //Resets an AI's call, should it exist.
|
||||
update_icon()
|
||||
@@ -160,11 +160,11 @@
|
||||
path_hud.add_to_hud(src)
|
||||
path_hud.add_hud_to(src)
|
||||
|
||||
/mob/living/simple_animal/bot/update_canmove()
|
||||
/mob/living/simple_animal/bot/update_mobility()
|
||||
. = ..()
|
||||
if(!on)
|
||||
. = 0
|
||||
canmove = .
|
||||
. = NONE
|
||||
mobility_flags = .
|
||||
|
||||
/mob/living/simple_animal/bot/Destroy()
|
||||
if(path_hud)
|
||||
|
||||
@@ -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
|
||||
@@ -525,7 +525,7 @@ Auto Patrol[]"},
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(C.canmove || arrest_type) // CIT CHANGE - makes sentient ed209s check for canmove rather than !isstun.
|
||||
if(CHECK_MOBILITY(C, MOBILITY_STAND|MOBILITY_MOVE|MOBILITY_USE) || arrest_type) // CIT CHANGE - makes sentient ed209s check for canmove rather than !isstun.
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
@@ -543,7 +543,7 @@ Auto Patrol[]"},
|
||||
spawn(2)
|
||||
icon_state = "[lasercolor]ed209[on]"
|
||||
var/threat = 5
|
||||
C.Knockdown(100)
|
||||
C.DefaultCombatKnockdown(100)
|
||||
C.stuttering = 5
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
if(!..())
|
||||
return
|
||||
|
||||
if(IsStun())
|
||||
if(IsStun() || IsParalyzed())
|
||||
old_target_fire = target_fire
|
||||
target_fire = null
|
||||
mode = BOT_IDLE
|
||||
@@ -287,7 +287,7 @@
|
||||
if(!on)
|
||||
icon_state = "firebot0"
|
||||
return
|
||||
if(IsStun())
|
||||
if(IsStun() || IsParalyzed())
|
||||
icon_state = "firebots1"
|
||||
else if(stationary_mode) //Bot has yellow light to indicate stationary mode.
|
||||
icon_state = "firebots1"
|
||||
|
||||
@@ -196,7 +196,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
C.stuttering = 20
|
||||
C.adjustEarDamage(0, 5) //far less damage than the H.O.N.K.
|
||||
C.Jitter(50)
|
||||
C.Knockdown(60)
|
||||
C.DefaultCombatKnockdown(60)
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(client) //prevent spam from players..
|
||||
spam_flag = TRUE
|
||||
@@ -215,7 +215,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
"<span class='userdanger'>[src] has honked you!</span>")
|
||||
else
|
||||
C.stuttering = 20
|
||||
C.Knockdown(80)
|
||||
C.DefaultCombatKnockdown(80)
|
||||
addtimer(CALLBACK(src, .proc/spam_flag_false), cooldowntime)
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ Maintenance panel panel is [open ? "opened" : "closed"]"},
|
||||
"[C] trips over [src] and falls!", \
|
||||
"[C] topples over [src]!", \
|
||||
"[C] leaps out of [src]'s way!")]</span>")
|
||||
C.Knockdown(10)
|
||||
C.DefaultCombatKnockdown(10)
|
||||
playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 1, -1)
|
||||
if(!client)
|
||||
speak("Honk!")
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
skin = new_skin
|
||||
update_icon()
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/update_canmove()
|
||||
/mob/living/simple_animal/bot/medbot/update_mobility()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -662,7 +662,7 @@
|
||||
if(!paicard)
|
||||
log_combat(src, L, "knocked down")
|
||||
visible_message("<span class='danger'>[src] knocks over [L]!</span>")
|
||||
L.Knockdown(160)
|
||||
L.DefaultCombatKnockdown(160)
|
||||
return ..()
|
||||
|
||||
// called from mob/living/carbon/human/Crossed()
|
||||
@@ -747,8 +747,8 @@
|
||||
else
|
||||
return null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/resist()
|
||||
..()
|
||||
/mob/living/simple_animal/bot/mulebot/do_resist()
|
||||
. = ..()
|
||||
if(load)
|
||||
unload()
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ Auto Patrol: []"},
|
||||
return
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(C.canmove || arrest_type) // CIT CHANGE - makes sentient secbots check for canmove rather than !isstun.
|
||||
if(CHECK_MOBILITY(C, MOBILITY_MOVE|MOBILITY_USE|MOBILITY_STAND) || arrest_type) // CIT CHANGE - makes sentient secbots check for canmove rather than !isstun.
|
||||
stun_attack(A)
|
||||
else if(C.canBeHandcuffed() && !C.handcuffed)
|
||||
cuff(A)
|
||||
@@ -254,11 +254,11 @@ Auto Patrol: []"},
|
||||
var/threat = 5
|
||||
if(ishuman(C))
|
||||
C.stuttering = 5
|
||||
C.Knockdown(100)
|
||||
C.DefaultCombatKnockdown(100)
|
||||
var/mob/living/carbon/human/H = C
|
||||
threat = H.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
else
|
||||
C.Knockdown(100)
|
||||
C.DefaultCombatKnockdown(100)
|
||||
C.stuttering = 5
|
||||
threat = C.assess_threat(judgement_criteria, weaponcheck=CALLBACK(src, .proc/check_for_weapons))
|
||||
|
||||
@@ -312,7 +312,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 +339,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.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user