This commit is contained in:
Ghommie
2020-03-12 20:31:14 +01:00
958 changed files with 221881 additions and 212761 deletions
-11
View File
@@ -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,7 @@
if(!pref_species)
var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
features = random_features()
features = random_features(pref_species?.id)
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
+5 -2
View File
@@ -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,7 +292,7 @@ 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
var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
+16 -9
View File
@@ -14,20 +14,20 @@
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()
. = ..()
if(brainmob && brainmob.stat != DEAD)
add_overlay("mmi_alive")
. += "mmi_alive"
else
add_overlay("mmi_dead")
. += "mmi_dead"
/obj/item/mmi/Initialize()
. = ..()
@@ -68,6 +68,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 +89,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 +133,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
+2 -6
View File
@@ -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
+30 -29
View File
@@ -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,14 @@ 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)
@@ -22,11 +22,11 @@ In all, this is a lot like the monkey code. /N
switch(M.a_intent)
if (INTENT_HELP)
if(!recoveringstam)
resting = 0
AdjustStun(-60)
AdjustKnockdown(-60)
AdjustUnconscious(-60)
AdjustSleeping(-100)
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
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
+39 -21
View File
@@ -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)
@@ -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
@@ -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,7 +820,8 @@
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(!eye_blind)
blind_eyes(1)
if(combatmode)
toggle_combat_mode(TRUE, TRUE)
else
@@ -814,7 +832,7 @@
else
stat = CONSCIOUS
adjust_blindness(-1)
update_canmove()
update_mobility()
update_damage_hud()
update_health_hud()
med_hud_set_status()
@@ -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)
@@ -77,7 +83,7 @@
var/mob/living/carbon/tempcarb = user
if(!tempcarb.combatmode)
totitemdamage *= 0.5
if(user.resting)
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
totitemdamage *= 0.5
if(!combatmode)
totitemdamage *= 1.5
@@ -188,7 +194,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 +239,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 +263,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 +285,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 +325,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 +344,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)
AdjustAllImmobility(-60, FALSE)
AdjustUnconscious(-60, FALSE)
AdjustSleeping(-100, FALSE)
if(recoveringstam)
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 +415,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
+1
View File
@@ -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"
+1 -1
View File
@@ -91,7 +91,7 @@
. += "[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."]"
. += "[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!
+25 -9
View File
@@ -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()
@@ -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)
@@ -491,7 +491,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.
@@ -724,8 +724,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 +836,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,7 +870,7 @@
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))
@@ -879,7 +879,7 @@
if(do_after(src, 30, 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 +892,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 +948,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)
@@ -0,0 +1,48 @@
/mob/living/carbon/human/resist_a_rest(automatic = FALSE, ignoretimer = FALSE)
if(!resting || stat || attemptingstandup)
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(getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(src, "<span class='warning'>You're too exhausted to get up!")
return FALSE
attemptingstandup = TRUE
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)
attemptingstandup = FALSE
return TRUE
else
attemptingstandup = FALSE
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,8 @@
/mob/living/carbon/human/movement_delay()
. = ..()
if(dna && dna.species)
. += dna.species.movement_delay(src)
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))
@@ -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")
+55 -73
View File
@@ -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.
///////////
// PROCS //
@@ -355,6 +357,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)
@@ -815,9 +825,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"
@@ -1019,6 +1027,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)
@@ -1286,12 +1303,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()
@@ -1342,6 +1361,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)
@@ -1364,9 +1392,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))
@@ -1375,7 +1403,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()
@@ -1391,59 +1419,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 //
//////////////////
@@ -1514,7 +1489,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage
if(!target.combatmode && damage < user.dna.species.punchstunthreshold)
damage = user.dna.species.punchstunthreshold - 1
if(user.resting)
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
damage *= 0.5
if(!user.combatmode)
damage *= 0.25
@@ -1632,7 +1607,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return*/
if(!target.combatmode) // 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
randn += 25 //CITADEL CHANGE - Makes it harder to disarm outside of combat mode
@@ -1715,7 +1690,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/mob/living/carbon/tempcarb = user
if(!tempcarb.combatmode)
totitemdamage *= 0.5
if(user.resting)
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
totitemdamage *= 0.5
if(istype(H))
if(!H.combatmode)
@@ -1831,12 +1806,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
return
if(!user.resting)
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)
@@ -1849,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)
@@ -1862,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())
@@ -1876,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
@@ -1887,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]"
@@ -2058,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)
@@ -2073,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)
@@ -2082,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(..())
@@ -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
@@ -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 ..()
+2 -2
View File
@@ -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)
+6 -7
View File
@@ -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)
@@ -509,7 +508,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
/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
adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? (recoveringstam ? -7.5 : -6) : -3)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke
if(!recoveringstam && incomingstammult != 1)
incomingstammult = max(0.01, incomingstammult)
@@ -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(!recoveringstam)
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, "monkey", null, null, null, 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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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))
+3 -3
View File
@@ -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)
+2 -1
View File
@@ -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)
+90 -176
View File
@@ -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,7 +115,7 @@
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)
@@ -125,7 +125,7 @@
return TRUE
attemptingcrawl = TRUE
visible_message("<span class='notice'>[src] is attempting to crawl under [L].</span>", "<span class='notice'>You are now attempting to crawl under [L].</span>")
if(!do_after(src, CRAWLUNDER_DELAY, target = src) || !resting)
if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND))
attemptingcrawl = FALSE
return TRUE
var/src_passmob = (pass_flags & PASSMOB)
@@ -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
@@ -369,8 +369,8 @@
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() || recoveringstam || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)))
return TRUE
/mob/living/canUseStorage()
@@ -428,7 +428,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 +490,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 +512,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 +527,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 +551,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 +623,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 +728,7 @@
return name
/mob/living/update_gravity(has_gravity,override = 0)
. = ..()
if(!SSticker.HasRoundStarted())
return
if(has_gravity)
@@ -788,6 +795,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 +1062,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 +1072,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 +1099,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 +1145,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 +1176,20 @@
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)
+8 -8
View File
@@ -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>", \
+6 -1
View File
@@ -22,6 +22,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
@@ -112,4 +114,7 @@
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
+168
View File
@@ -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)
intentionalresting = !intentionalresting
to_chat(src, "<span class='notice'>You are now attempting to [intentionalresting ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].</span>")
if(intentionalresting && !resting)
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 && !recoveringstam
var/canresist = !stun && conscious && !stat_softcrit && !paralyze && has_limbs && !recoveringstam
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) && !recoveringstam
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 && !recoveringstam
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) && !intentionalresting && 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
+81 -4
View File
@@ -1,6 +1,10 @@
/mob/living/Moved()
. = ..()
update_turf_movespeed(loc)
if(is_shifted)
is_shifted = FALSE
pixel_x = get_standard_pixel_x_offset(lying)
pixel_y = get_standard_pixel_y_offset(lying)
/mob/living/CanPass(atom/movable/mover, turf/target)
if((mover.pass_flags & PASSMOB))
@@ -12,10 +16,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,6 +33,10 @@
update_move_intent_slowdown()
return ..()
/// 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)
@@ -50,4 +62,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 ..()
+31 -4
View File
@@ -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
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -2,7 +2,7 @@
if(stat == DEAD)
return
stat = DEAD
canmove = 0
update_mobility()
update_sight()
clear_fullscreens()
+11 -8
View File
@@ -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,10 +96,11 @@
dynamic_chassis = choice
resist_a_rest(FALSE, TRUE)
update_icon()
current_mob_holder?.Detach(src)
current_mob_holder = null
if(possible_chassis[old_chassis])
var/datum/element/mob_holder/M = SSdcs.GetElement(/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)
M.Detach(src)
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)
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
+12 -85
View File
@@ -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()
@@ -1269,20 +1210,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 +1237,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
@@ -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]"
@@ -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)
@@ -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))
@@ -103,7 +103,7 @@
/mob/living/simple_animal/hostile/construct/narsie_act()
return
/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return 0
/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
@@ -353,7 +353,7 @@
if(!LAZYLEN(parts))
if(undismembermerable_limbs) //they have limbs we can't remove, and no parts we can, attack!
return ..()
C.Knockdown(60)
C.DefaultCombatKnockdown(60)
visible_message("<span class='danger'>[src] knocks [C] down!</span>")
to_chat(src, "<span class='cultlarge'>\"Bring [C.p_them()] to me.\"</span>")
return FALSE
@@ -33,7 +33,7 @@
. = ..()
AddElement(/datum/element/wuv, "bzzs!")
/mob/living/simple_animal/pet/bumbles/update_canmove()
/mob/living/simple_animal/pet/bumbles/update_mobility()
. = ..()
if(client && stat != DEAD)
if (resting)
@@ -43,10 +43,10 @@
AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE)
AddElement(/datum/element/mob_holder, held_icon)
/mob/living/simple_animal/pet/cat/update_canmove()
..()
/mob/living/simple_animal/pet/cat/update_mobility()
. = ..()
if(client && stat != DEAD)
if (resting)
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
icon_state = "[icon_living]_rest"
collar_type = "[initial(collar_type)]_rest"
else
@@ -180,27 +180,24 @@
emote("me", EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
icon_state = "[icon_living]_rest"
collar_type = "[initial(collar_type)]_rest"
resting = 1
update_canmove()
set_resting(TRUE)
else if (prob(1))
emote("me", EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert."))
icon_state = "[icon_living]_sit"
collar_type = "[initial(collar_type)]_sit"
resting = 1
update_canmove()
set_resting(TRUE)
else if (prob(1))
if (resting)
emote("me", EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting."))
icon_state = "[icon_living]"
collar_type = "[initial(collar_type)]"
resting = 0
update_canmove()
set_resting(FALSE)
else
emote("me", EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
//MICE!
if((src.loc) && isturf(src.loc))
if(!stat && !resting && !buckled)
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
for(var/mob/living/simple_animal/mouse/M in view(1,src))
if(!M.stat && Adjacent(M))
emote("me", EMOTE_VISIBLE, "splats \the [M]!")
@@ -217,7 +214,7 @@
make_babies()
if(!stat && !resting && !buckled)
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
walk_to(src,0)
@@ -309,7 +306,6 @@
if (pseudo_death == TRUE) //secret cat chem
icon_state = "custom_cat_dead"
Stun(1000)
canmove = 0
friendly = "deads at"
return
else
@@ -26,7 +26,7 @@
..()
//CRAB movement
if(!ckey && !stat)
if(isturf(src.loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
if(isturf(loc) && !resting && !buckled) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
var/east_vs_west = pick(4,8)
@@ -425,7 +425,7 @@
..()
//Feeding, chasing food, FOOOOODDDD
if(!stat && !resting && !buckled)
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
turns_since_scan = 0
@@ -625,7 +625,7 @@
make_babies()
if(!stat && !resting && !buckled)
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
if(prob(1))
emote("me", EMOTE_VISIBLE, pick("dances around.","chases her tail."))
spawn(0)
@@ -635,8 +635,7 @@
/mob/living/simple_animal/pet/dog/pug/Life()
..()
if(!stat && !resting && !buckled)
if(!stat && CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) && !buckled)
if(prob(1))
emote("me", EMOTE_VISIBLE, pick("chases its tail."))
spawn(0)
@@ -105,7 +105,7 @@
. = ..()
if(can_be_held)
//icon/item state is defined in mob_holder/drone_worn_icon()
AddElement(/datum/element/mob_holder, null, 'icons/mob/head.dmi', 'icons/mob/inhands/clothing_righthand.dmi', 'icons/mob/inhands/clothing_lefthand.dmi', TRUE, /datum/element/mob_holder.proc/drone_worn_icon)
AddElement(/datum/element/mob_holder, null, 'icons/mob/head.dmi', 'icons/mob/inhands/clothing_righthand.dmi', 'icons/mob/inhands/clothing_lefthand.dmi', ITEM_SLOT_HEAD, /datum/element/mob_holder.proc/drone_worn_icon)
/mob/living/simple_animal/drone/med_hud_set_health()
var/image/holder = hud_list[DIAG_HUD]
@@ -277,7 +277,7 @@
// Why would bees pay attention to drones?
return 1
/mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
/mob/living/simple_animal/drone/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return 0 //So they don't die trying to fix wiring
/mob/living/simple_animal/drone/can_see_reagents()
@@ -204,37 +204,6 @@
else
icon_state = "[visualAppearence]_dead"
/mob/living/simple_animal/drone/cogscarab/Stun(amount, updating = 1, ignore_canstun = 0)
/mob/living/simple_animal/drone/cogscarab/update_mobility()
. = ..()
if(.)
update_icons()
/mob/living/simple_animal/drone/cogscarab/SetStun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(.)
update_icons()
/mob/living/simple_animal/drone/cogscarab/AdjustStun(amount, updating = 1, ignore_canstun = 0)
. = ..()
if(.)
update_icons()
/mob/living/simple_animal/drone/cogscarab/Knockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg)
. = ..()
if(.)
update_icons()
/mob/living/simple_animal/drone/cogscarab/SetKnockdown(amount, updating = 1, ignore_canknockdown = 0)
. = ..()
if(.)
update_icons()
/mob/living/simple_animal/drone/cogscarab/AdjustKnockdown(amount, updating = 1, ignore_canknockdown = 0)
. = ..()
if(.)
update_icons()
/mob/living/simple_animal/drone/cogscarab/update_canmove()
. = ..()
if(.)
update_icons()
update_icons()
@@ -160,7 +160,7 @@
M.visible_message("<span class='warning'>[M] tips over [src].</span>",
"<span class='notice'>You tip over [src].</span>")
to_chat(src, "<span class='userdanger'>You are tipped over by [M]!</span>")
Knockdown(60,ignore_canknockdown = TRUE)
DefaultCombatKnockdown(60,ignore_canknockdown = TRUE)
icon_state = icon_dead
spawn(rand(20,50))
if(!stat && M)
@@ -26,7 +26,7 @@
/mob/living/simple_animal/hostile/lizard/ComponentInitialize()
. = ..()
AddElement(/datum/element/mob_holder, "lizard", null, null, null, SLOT_HEAD) //you can hold lizards now.
AddElement(/datum/element/mob_holder, "lizard", null, null, null, ITEM_SLOT_HEAD) //you can hold lizards now.
/mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target?
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
@@ -633,8 +633,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
<br>
"}
/obj/item/paper/guides/antag/guardian/update_icon()
return
/obj/item/paper/guides/antag/guardian/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_blocker)
/obj/item/paper/guides/antag/guardian/wizard
name = "Guardian Guide"
@@ -99,9 +99,57 @@
to_chat(user, "<span class='info'>You strap the armor plating to [A] and sharpen [A.p_their()] claws with the nail filer. This was a great idea.</span>")
qdel(src)
mob/living/simple_animal/hostile/bear/butter //The mighty companion to Cak. Several functions used from it.
name = "Terrygold"
icon_state = "butterbear"
icon_living = "butterbear"
icon_dead = "butterbear_dead"
desc = "I can't believe its not a bear!"
faction = list("neutral", "russian")
obj_damage = 11
melee_damage_lower = 1
melee_damage_upper = 1
armour_penetration = 0
response_harm = "takes a bite out of"
attacked_sound = 'sound/items/eatfood.ogg'
deathmessage = "loses its false life and collapses!"
butcher_results = list(/obj/item/reagent_containers/food/snacks/butter = 6, /obj/item/reagent_containers/food/snacks/meat/slab = 3, /obj/item/organ/brain = 1, /obj/item/organ/heart = 1)
attack_sound = 'sound/weapons/slap.ogg'
attacktext = "slaps"
/mob/living/simple_animal/hostile/bear/butter/Life() //Heals butter bear really fast when he takes damage.
if(stat)
return
if(health < maxHealth)
heal_overall_damage(10) //Fast life regen, makes it hard for you to get eaten to death.
/mob/living/simple_animal/hostile/bear/butter/attack_hand(mob/living/L) //Borrowed code from Cak, feeds people if they hit you. More nutriment but less vitamin to represent BUTTER.
..()
if(L.a_intent == INTENT_HARM && L.reagents && !stat)
L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 1)
L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.1)
/mob/living/simple_animal/hostile/bear/butter/CheckParts(list/parts) //Borrowed code from Cak, allows the brain used to actually control the bear.
..()
var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents
if(!B || !B.brainmob || !B.brainmob.mind)
return
B.brainmob.mind.transfer_to(src)
to_chat(src, "<span class='big bold'>You are a butter bear!</span><b> You're a mostly harmless bear/butter hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \
so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \
free butter to the station!</b>")
var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Terrygold.", "Name Change")
if(new_name)
to_chat(src, "<span class='notice'>Your name is now <b>\"new_name\"</b>!</span>")
name = new_name
mob/living/simple_animal/hostile/bear/butter/AttackingTarget() //Makes some attacks by the butter bear slip those who dare cross its path.
if(isliving(target))
var/mob/living/L = target
if((L.mobility_flags & MOBILITY_STAND))
L.Knockdown(20)
playsound(loc, 'sound/misc/slip.ogg', 15)
L.visible_message("<span class='danger'>[L] slips on butter!</span>")
@@ -41,6 +41,6 @@
. = ..()
if(. && prob(12) && iscarbon(target))
var/mob/living/carbon/C = target
C.Knockdown(60)
C.DefaultCombatKnockdown(60)
C.visible_message("<span class='danger'>\The [src] knocks down \the [C]!</span>", \
"<span class='userdanger'>\The [src] knocks you down!</span>")
@@ -71,7 +71,7 @@
var/atom/throw_target = get_edge_target_turf(L, dir)
L.throw_at(throw_target, rand(1,2), 7, src)
else
L.Knockdown(20)
L.DefaultCombatKnockdown(20)
visible_message("<span class='danger'>[src] knocks [L] down!</span>")
/mob/living/simple_animal/hostile/gorilla/CanAttack(atom/the_target)
@@ -93,7 +93,7 @@
var/mob/living/L = AM
if(!istype(L, /mob/living/simple_animal/hostile/jungle/leaper))
playsound(src,'sound/effects/snap.ogg',50, 1, -1)
L.Knockdown(50)
L.DefaultCombatKnockdown(50)
if(iscarbon(L))
var/mob/living/carbon/C = L
C.reagents.add_reagent(/datum/reagent/toxin/leaper_venom, 5)

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