Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into ninjasarecum
# Conflicts: # code/modules/ninja/suit/suit.dm
This commit is contained in:
@@ -91,7 +91,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
|
||||
var/client/C = client
|
||||
to_chat(C, "<span class='notice'>Sending you to [pick].</span>")
|
||||
new /obj/screen/splash(C)
|
||||
new /atom/movable/screen/splash(C)
|
||||
|
||||
mob_transforming = TRUE
|
||||
sleep(29) //let the animation play
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
/mob/dead/new_player/Initialize()
|
||||
if(client && SSticker.state == GAME_STATE_STARTUP)
|
||||
var/obj/screen/splash/S = new(client, TRUE, TRUE)
|
||||
var/atom/movable/screen/splash/S = new(client, TRUE, TRUE)
|
||||
S.Fade(TRUE)
|
||||
|
||||
if(length(GLOB.newplayer_start))
|
||||
@@ -567,7 +567,7 @@
|
||||
if(job && !job.override_latejoin_spawn(character))
|
||||
SSjob.SendToLateJoin(character)
|
||||
if(!arrivals_docked)
|
||||
var/obj/screen/splash/Spl = new(character.client, TRUE)
|
||||
var/atom/movable/screen/splash/Spl = new(character.client, TRUE)
|
||||
Spl.Fade(TRUE)
|
||||
character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25)
|
||||
|
||||
|
||||
@@ -436,13 +436,27 @@
|
||||
|
||||
/datum/sprite_accessory/tails/human/shark
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
icon_state = "carp"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/shark
|
||||
name = "Shark"
|
||||
icon_state = "carp"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails/human/sharkalt
|
||||
name = "Shark (alt)"
|
||||
icon_state = "shark"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails_animated/human/sharkalt
|
||||
name = "Shark (alt)"
|
||||
icon_state = "shark"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
@@ -679,7 +693,7 @@
|
||||
icon_state = "crow"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails/mam_tail/cow
|
||||
/datum/sprite_accessory/tails/mam_tails/cow
|
||||
name = "Cow"
|
||||
icon_state = "cow"
|
||||
matrixed_sections = MATRIX_RED
|
||||
@@ -897,11 +911,21 @@
|
||||
|
||||
/datum/sprite_accessory/tails/mam_tails/shark
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
icon_state = "carp"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails_animated/mam_tails_animated/shark
|
||||
name = "Shark"
|
||||
icon_state = "carp"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails/mam_tails/sharkalt
|
||||
name = "Shark (alt)"
|
||||
icon_state = "shark"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
/datum/sprite_accessory/tails_animated/mam_tails_animated/sharkalt
|
||||
name = "Shark (alt)"
|
||||
icon_state = "shark"
|
||||
matrixed_sections = MATRIX_RED
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(message)
|
||||
to_chat(src, "<span class='ghostalert'>[message]</span>")
|
||||
if(source)
|
||||
var/obj/screen/alert/A = throw_alert("[REF(source)]_notify_cloning", /obj/screen/alert/notify_cloning)
|
||||
var/atom/movable/screen/alert/A = throw_alert("[REF(source)]_notify_cloning", /atom/movable/screen/alert/notify_cloning)
|
||||
if(A)
|
||||
if(client && client.prefs && client.prefs.UI_style)
|
||||
A.icon = ui_style2icon(client.prefs.UI_style)
|
||||
|
||||
@@ -39,29 +39,35 @@
|
||||
return
|
||||
|
||||
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_HUSK))) //cryosleep or husked people do not pump the blood.
|
||||
|
||||
//Blood regeneration if there is some space
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
if(integrating_blood > 0)
|
||||
var/blood_integrated = max(integrating_blood - 1, 0)
|
||||
var/blood_diff = integrating_blood - blood_integrated
|
||||
integrating_blood = blood_integrated
|
||||
if(blood_volume < BLOOD_VOLUME_MAXIMUM)
|
||||
blood_volume += blood_diff
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
var/nutrition_ratio = 0
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
nutrition_ratio = 0.2
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
nutrition_ratio = 0.4
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
nutrition_ratio = 0.6
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
nutrition_ratio = 0.8
|
||||
else
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
if(!HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
nutrition_ratio = 0.2
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
nutrition_ratio = 0.4
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
|
||||
nutrition_ratio = 0.6
|
||||
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
|
||||
nutrition_ratio = 0.8
|
||||
else
|
||||
nutrition_ratio = 1
|
||||
if(satiety > 80)
|
||||
nutrition_ratio *= 1.25
|
||||
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
|
||||
blood_volume = min(BLOOD_VOLUME_NORMAL, blood_volume + 0.5 * nutrition_ratio)
|
||||
|
||||
//Effects of bloodloss
|
||||
var/word = pick("dizzy","woozy","faint")
|
||||
switch(blood_volume)
|
||||
var/blood_effect_volume = blood_volume + integrating_blood
|
||||
switch(blood_effect_volume)
|
||||
if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS)
|
||||
if(prob(10))
|
||||
to_chat(src, "<span class='warning'>You feel terribly bloated.</span>")
|
||||
@@ -94,14 +100,22 @@
|
||||
bleed(temp_bleed)
|
||||
|
||||
//Makes a blood drop, leaking amt units of blood from the mob
|
||||
/mob/living/carbon/proc/bleed(amt)
|
||||
if(blood_volume)
|
||||
/mob/living/carbon/proc/bleed(amt, force)
|
||||
var/bled = FALSE //Have we bled amnt?
|
||||
if(blood_volume > amt || force && blood_volume)
|
||||
blood_volume = max(blood_volume - amt, 0)
|
||||
if(isturf(src.loc)) //Blood loss still happens in locker, floor stays clean
|
||||
if(amt >= 10)
|
||||
add_splatter_floor(src.loc)
|
||||
else
|
||||
add_splatter_floor(src.loc, 1)
|
||||
bled = TRUE
|
||||
if(integrating_blood > amt || force && integrating_blood)
|
||||
integrating_blood = max(integrating_blood - amt, 0)
|
||||
bled = TRUE
|
||||
if(!bled && !force) //If we are already cycling back through, don't do this again
|
||||
bleed(amt, TRUE) //we cycle back through to try to bleed SOMETHING, not neccesarily the required amount
|
||||
return
|
||||
if(isturf(src.loc)) //Blood loss still happens in locker, floor stays clean
|
||||
if(amt >= 10)
|
||||
add_splatter_floor(src.loc)
|
||||
else
|
||||
add_splatter_floor(src.loc, TRUE)
|
||||
|
||||
/mob/living/carbon/human/bleed(amt)
|
||||
amt *= physiology.bleed_mod
|
||||
@@ -114,6 +128,7 @@
|
||||
|
||||
/mob/living/proc/restore_blood()
|
||||
blood_volume = initial(blood_volume)
|
||||
integrating_blood = 0
|
||||
|
||||
/mob/living/carbon/restore_blood()
|
||||
blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio)
|
||||
@@ -368,10 +383,17 @@
|
||||
return
|
||||
blood_ratio = 1
|
||||
|
||||
/mob/living/proc/AdjustBloodVol(var/value)
|
||||
/mob/living/proc/AdjustBloodVol(value)
|
||||
if(blood_ratio == value)
|
||||
return
|
||||
blood_ratio = value
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
H.handle_blood()
|
||||
|
||||
/mob/living/proc/adjust_integration_blood(value, remove_actual_blood, force)
|
||||
if(integrating_blood + value < 0 && remove_actual_blood)
|
||||
blood_volume += value + integrating_blood
|
||||
blood_volume = max(blood_volume, 0)
|
||||
integrating_blood += value
|
||||
integrating_blood = clamp(integrating_blood, 0, force ? INFINITY : (BLOOD_VOLUME_MAXIMUM - (integrating_blood + blood_volume)))
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
|
||||
//Body temperature is too hot.
|
||||
throw_alert("alien_fire", /obj/screen/alert/alien_fire)
|
||||
throw_alert("alien_fire", /atom/movable/screen/alert/alien_fire)
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
meleeKnockdownPower = 75
|
||||
meleeSlashHumanPower = 20
|
||||
meleeSlashSAPower = 45
|
||||
var/obj/screen/leap_icon = null
|
||||
var/atom/movable/screen/leap_icon = null
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
|
||||
|
||||
//Partial pressure of the toxins in our breath
|
||||
var/Toxins_pp = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
|
||||
var/Toxins_pp = (breath.get_moles(GAS_PLASMA)/breath.total_moles())*breath_pressure
|
||||
|
||||
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
|
||||
adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
|
||||
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
|
||||
adjustPlasma(breath.get_moles(GAS_PLASMA)*250)
|
||||
throw_alert("alien_tox", /atom/movable/screen/alert/alien_tox)
|
||||
|
||||
toxins_used = breath.get_moles(/datum/gas/plasma)
|
||||
toxins_used = breath.get_moles(GAS_PLASMA)
|
||||
|
||||
else
|
||||
clear_alert("alien_tox")
|
||||
|
||||
//Breathe in toxins and out oxygen
|
||||
breath.adjust_moles(/datum/gas/plasma, -toxins_used)
|
||||
breath.adjust_moles(/datum/gas/oxygen, toxins_used)
|
||||
breath.adjust_moles(GAS_PLASMA, -toxins_used)
|
||||
breath.adjust_moles(GAS_O2, toxins_used)
|
||||
|
||||
//BREATH TEMPERATURE
|
||||
handle_breath_temperature(breath)
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
owner.adjustOxyLoss(-heal_amt)
|
||||
owner.adjustCloneLoss(-heal_amt)
|
||||
if(owner.blood_volume && (owner.blood_volume < BLOOD_VOLUME_NORMAL))
|
||||
owner.blood_volume += 5
|
||||
owner.adjust_integration_blood(5)
|
||||
else
|
||||
owner.adjustPlasma(plasma_rate * 0.1)
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
owner.stuttering += 30
|
||||
|
||||
recent_queen_death = 1
|
||||
owner.throw_alert("alien_noqueen", /obj/screen/alert/alien_vulnerable)
|
||||
owner.throw_alert("alien_noqueen", /atom/movable/screen/alert/alien_vulnerable)
|
||||
addtimer(CALLBACK(src, .proc/clear_queen_death), QUEEN_DEATH_DEBUFF_DURATION)
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
|
||||
// eye damage, eye_blind, eye_blurry, druggy, TRAIT_BLIND trait, and TRAIT_NEARSIGHT trait.
|
||||
|
||||
/mob/living/carbon/alien/DefaultCombatKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg)
|
||||
/mob/living/carbon/alien/DefaultCombatKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg, knocktofloor)
|
||||
return //no
|
||||
|
||||
/////////////////////////////////// STUN ////////////////////////////////////
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
var/oindex = active_hand_index
|
||||
active_hand_index = held_index
|
||||
if(hud_used)
|
||||
var/obj/screen/inventory/hand/H
|
||||
var/atom/movable/screen/inventory/hand/H
|
||||
H = hud_used.hand_slots["[oindex]"]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
@@ -158,7 +158,7 @@
|
||||
throw_mode_off()
|
||||
if(!target || !isturf(loc))
|
||||
return
|
||||
if(istype(target, /obj/screen))
|
||||
if(istype(target, /atom/movable/screen))
|
||||
return
|
||||
|
||||
//CIT CHANGES - makes it impossible to throw while in stamina softcrit
|
||||
@@ -358,10 +358,11 @@
|
||||
return
|
||||
I.item_flags |= BEING_REMOVED
|
||||
breakouttime = I.breakouttime
|
||||
var/datum/cuffbreak_checker/cuffbreak_checker = new(get_turf(src), istype(I, /obj/item/restraints)? I : null)
|
||||
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, required_mobility_flags = MOBILITY_RESIST))
|
||||
if(do_after_advanced(src, breakouttime, src, NONE, CALLBACK(cuffbreak_checker, /datum/cuffbreak_checker.proc/check_movement), required_mobility_flags = MOBILITY_RESIST))
|
||||
clear_cuffs(I, cuff_break)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You fail to remove [I]!</span>")
|
||||
@@ -370,15 +371,36 @@
|
||||
breakouttime = 50
|
||||
visible_message("<span class='warning'>[src] is trying to break [I]!</span>")
|
||||
to_chat(src, "<span class='notice'>You attempt to break [I]... (This will take around 5 seconds and you need to stand still.)</span>")
|
||||
if(do_after(src, breakouttime, 0, target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
if(do_after_advanced(src, breakouttime, src, NONE, CALLBACK(cuffbreak_checker, /datum/cuffbreak_checker.proc/check_movement), required_mobility_flags = MOBILITY_RESIST))
|
||||
clear_cuffs(I, cuff_break)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You fail to break [I]!</span>")
|
||||
|
||||
else if(cuff_break == INSTANT_CUFFBREAK)
|
||||
clear_cuffs(I, cuff_break)
|
||||
|
||||
QDEL_NULL(cuffbreak_checker)
|
||||
I.item_flags &= ~BEING_REMOVED
|
||||
|
||||
/datum/cuffbreak_checker
|
||||
var/turf/last
|
||||
var/obj/item/restraints/cuffs
|
||||
|
||||
/datum/cuffbreak_checker/New(turf/initial_turf, obj/item/restraints/R)
|
||||
last = initial_turf
|
||||
if(R)
|
||||
cuffs = R
|
||||
|
||||
/datum/cuffbreak_checker/proc/check_movement(atom/user, delay, atom/target, time_left, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool, list/passed_in)
|
||||
if(get_turf(user) != last)
|
||||
last = get_turf(user)
|
||||
passed_in[1] = 0.5
|
||||
if(cuffs && !cuffs.allow_breakout_movement)
|
||||
return DO_AFTER_STOP
|
||||
else
|
||||
passed_in[1] = 1
|
||||
return DO_AFTER_CONTINUE
|
||||
|
||||
/mob/living/carbon/proc/uncuff()
|
||||
if (handcuffed)
|
||||
var/obj/item/W = handcuffed
|
||||
@@ -459,10 +481,6 @@
|
||||
if(HAS_TRAIT(src, TRAIT_CLUMSY))
|
||||
modifier -= 40 //Clumsy people are more likely to hit themselves -Honk!
|
||||
|
||||
//CIT CHANGES START HERE
|
||||
else if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
modifier -= 50
|
||||
|
||||
if(modifier < 100)
|
||||
dropItemToGround(I)
|
||||
//END OF CIT CHANGES
|
||||
@@ -503,7 +521,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
|
||||
if((HAS_TRAIT(src, TRAIT_NOHUNGER) || HAS_TRAIT(src, TRAIT_TOXINLOVER)) && !force)
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER) && !force)
|
||||
return TRUE
|
||||
|
||||
if(nutrition < 100 && !blood && !force)
|
||||
@@ -681,7 +699,7 @@
|
||||
become_blind(EYES_COVERED)
|
||||
else if(tinttotal >= TINT_DARKENED)
|
||||
cure_blind(EYES_COVERED)
|
||||
overlay_fullscreen("tint", /obj/screen/fullscreen/impaired, 2)
|
||||
overlay_fullscreen("tint", /atom/movable/screen/fullscreen/impaired, 2)
|
||||
else
|
||||
cure_blind(EYES_COVERED)
|
||||
clear_fullscreen("tint", 0)
|
||||
@@ -757,10 +775,10 @@
|
||||
visionseverity = 9
|
||||
if(-INFINITY to -24)
|
||||
visionseverity = 10
|
||||
overlay_fullscreen("critvision", /obj/screen/fullscreen/crit/vision, visionseverity)
|
||||
overlay_fullscreen("critvision", /atom/movable/screen/fullscreen/crit/vision, visionseverity)
|
||||
else
|
||||
clear_fullscreen("critvision")
|
||||
overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
|
||||
overlay_fullscreen("crit", /atom/movable/screen/fullscreen/crit, severity)
|
||||
else
|
||||
clear_fullscreen("crit")
|
||||
clear_fullscreen("critvision")
|
||||
@@ -784,7 +802,7 @@
|
||||
severity = 6
|
||||
if(45 to INFINITY)
|
||||
severity = 7
|
||||
overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
|
||||
overlay_fullscreen("oxy", /atom/movable/screen/fullscreen/oxy, severity)
|
||||
else
|
||||
clear_fullscreen("oxy")
|
||||
|
||||
@@ -805,7 +823,7 @@
|
||||
severity = 5
|
||||
if(85 to INFINITY)
|
||||
severity = 6
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
|
||||
@@ -870,7 +888,7 @@
|
||||
if(handcuffed)
|
||||
drop_all_held_items()
|
||||
stop_pulling()
|
||||
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
|
||||
throw_alert("handcuffed", /atom/movable/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
|
||||
if(handcuffed.demoralize_criminals)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "handcuffed", /datum/mood_event/handcuffed)
|
||||
else
|
||||
@@ -949,7 +967,9 @@
|
||||
/mob/living/carbon/ExtinguishMob()
|
||||
for(var/X in get_equipped_items())
|
||||
var/obj/item/I = X
|
||||
I.acid_level = 0 //washes off the acid on our clothes
|
||||
var/datum/component/acid/acid = I.GetComponent(/datum/component/acid)
|
||||
if(acid)
|
||||
acid.level = 0
|
||||
I.extinguish() //extinguishes our clothes
|
||||
..()
|
||||
|
||||
@@ -1253,3 +1273,6 @@
|
||||
var/mob/living/carbon/C = usr
|
||||
if(I.can_give())
|
||||
C.give(src)
|
||||
|
||||
/mob/living/carbon/proc/functional_blood()
|
||||
return blood_volume + integrating_blood
|
||||
|
||||
@@ -361,7 +361,7 @@
|
||||
|
||||
return embeds
|
||||
|
||||
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash, override_protection = 0)
|
||||
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0)
|
||||
. = ..()
|
||||
|
||||
var/damage = override_protection ? intensity : intensity - get_eye_protection()
|
||||
|
||||
@@ -797,6 +797,7 @@
|
||||
dna.remove_mutation(HM.name)
|
||||
if(blood_volume < (BLOOD_VOLUME_NORMAL*blood_ratio))
|
||||
blood_volume = (BLOOD_VOLUME_NORMAL*blood_ratio)
|
||||
integrating_blood = 0
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
@@ -813,7 +814,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
|
||||
if(blood && dna?.species && (NOBLOOD in dna.species.species_traits) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
|
||||
if(blood && dna?.species && (NOBLOOD in dna.species.species_traits))
|
||||
if(message)
|
||||
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>")
|
||||
@@ -1027,10 +1028,10 @@
|
||||
return
|
||||
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment
|
||||
var/scaling = maxHealth / 100
|
||||
var/health_deficiency = ((maxHealth / scaling) - (health / scaling) + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
|
||||
var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), (getStaminaLoss()*0.75))
|
||||
if(health_deficiency >= 40)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency - 15) / 75)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency - 15) / 25)
|
||||
else
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
@@ -1073,9 +1074,9 @@
|
||||
if(HAS_TRAIT(src, TRAIT_TOXINLOVER))
|
||||
return "<font color='#00ffff'>"
|
||||
if(isplasmaman(src))
|
||||
return "<font color='#800080'"
|
||||
return "<font color='#800080'>"
|
||||
if(isgolem(src))
|
||||
return "<font color='#8b4513'"
|
||||
return "<font color='#8b4513'>"
|
||||
return "<font color='#18d855'>"
|
||||
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
return
|
||||
var/informed = FALSE
|
||||
if(isrobotic(src))
|
||||
apply_status_effect(/datum/status_effect/no_combat_mode/robotic_emp, severity / 20)
|
||||
apply_status_effect(/datum/status_effect/robotic_emp, severity / 20)
|
||||
severity *= 0.5
|
||||
var/do_not_stun = FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
block_parry_data = /datum/block_parry_data/unarmed/human
|
||||
default_block_parry_data = /datum/block_parry_data/unarmed/human
|
||||
causes_dirt_buildup_on_floor = TRUE
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
@@ -52,6 +51,9 @@
|
||||
var/obj/item/l_store = null
|
||||
var/obj/item/s_store = null
|
||||
|
||||
/// When an braindead player has their equipment fiddled with, we log that info here for when they come back so they know who took their ID while they were DC'd for 30 seconds
|
||||
var/list/afk_thefts
|
||||
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
|
||||
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
|
||||
@@ -143,7 +145,7 @@
|
||||
)
|
||||
|
||||
parry_efficiency_considered_successful = 0.01
|
||||
parry_efficiency_to_counterattack = 0.01
|
||||
parry_efficiency_to_counterattack = INFINITY // no counterattacks
|
||||
parry_max_attacks = INFINITY
|
||||
parry_failed_cooldown_duration = 1.5 SECONDS
|
||||
parry_failed_stagger_duration = 1 SECONDS
|
||||
|
||||
@@ -182,3 +182,8 @@
|
||||
destination.underwear = underwear
|
||||
destination.undershirt = undershirt
|
||||
destination.socks = socks
|
||||
|
||||
/mob/living/carbon/human/adjust_integration_blood(value, force)
|
||||
if(NOBLOOD in dna.species.species_traits) //Can't lose blood if your species doesn't have any
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -90,13 +90,31 @@
|
||||
//End bloody footprints
|
||||
|
||||
S.step_action()
|
||||
if(movement_type & GROUND)
|
||||
dirt_buildup()
|
||||
|
||||
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
|
||||
if(dna.species.space_move(src))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/dirt_buildup(strength)
|
||||
/mob/living/carbon/human/proc/dirt_buildup(strength = 1)
|
||||
if(!shoes || !(shoes.body_parts_covered & FEET))
|
||||
return // barefoot advantage
|
||||
return ..()
|
||||
var/turf/open/T = loc
|
||||
if(!istype(T) || !T.dirt_buildup_allowed)
|
||||
return
|
||||
var/area/A = T.loc
|
||||
if(!A.dirt_buildup_allowed)
|
||||
return
|
||||
var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
|
||||
strength *= multiplier
|
||||
var/obj/effect/decal/cleanable/dirt/D = locate() in T
|
||||
if(D)
|
||||
D.dirty(strength)
|
||||
else
|
||||
T.dirtyness += strength
|
||||
if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
|
||||
D = new /obj/effect/decal/cleanable/dirt(T)
|
||||
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
|
||||
T.dirtyness = 0 // reset.
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
ADD_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT)
|
||||
ADD_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT)
|
||||
H.update_disabled_bodyparts(silent = TRUE) //silently update arms to be paralysed
|
||||
@@ -99,7 +98,6 @@
|
||||
REMOVE_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT)
|
||||
REMOVE_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT)
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
if(HAS_TRAIT(src, TRAIT_NEARSIGHT))
|
||||
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
|
||||
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1)
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
|
||||
update_sight()
|
||||
if(!QDELETED(src))
|
||||
|
||||
@@ -89,15 +89,15 @@
|
||||
var/datum/species/S = dna.species
|
||||
|
||||
if(S.breathid == "o2")
|
||||
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
|
||||
throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
|
||||
else if(S.breathid == "tox")
|
||||
throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
|
||||
throw_alert("not_enough_tox", /atom/movable/screen/alert/not_enough_tox)
|
||||
else if(S.breathid == "co2")
|
||||
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
|
||||
throw_alert("not_enough_co2", /atom/movable/screen/alert/not_enough_co2)
|
||||
else if(S.breathid == "n2")
|
||||
throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)
|
||||
throw_alert("not_enough_nitro", /atom/movable/screen/alert/not_enough_nitro)
|
||||
else if(S.breathid == "ch3br")
|
||||
throw_alert("not_enough_ch3br", /obj/screen/alert/not_enough_ch3br)
|
||||
throw_alert("not_enough_ch3br", /atom/movable/screen/alert/not_enough_ch3br)
|
||||
|
||||
return FALSE
|
||||
else
|
||||
|
||||
@@ -2,3 +2,33 @@
|
||||
..()
|
||||
if(dna?.species?.has_field_of_vision && CONFIG_GET(flag/use_field_of_vision))
|
||||
LoadComponent(/datum/component/field_of_vision, field_of_vision_type)
|
||||
|
||||
if(!LAZYLEN(afk_thefts))
|
||||
return
|
||||
|
||||
var/list/print_msg = list()
|
||||
print_msg += "<span class='info'>*---------*</span>"
|
||||
print_msg += "<span class='userdanger'>As you snap back to consciousness, you recall people messing with your stuff...</span>"
|
||||
|
||||
afk_thefts = reverseRange(afk_thefts)
|
||||
|
||||
for(var/list/iter_theft as anything in afk_thefts)
|
||||
if(!islist(iter_theft) || LAZYLEN(iter_theft) != AFK_THEFT_TIME)
|
||||
stack_trace("[src] ([ckey]) returned to their body and had a null/malformed afk_theft entry. Contents: [json_encode(iter_theft)]")
|
||||
continue
|
||||
|
||||
var/thief_name = iter_theft[AFK_THEFT_NAME]
|
||||
var/theft_message = iter_theft[AFK_THEFT_MESSAGE]
|
||||
var/time_since = world.time - iter_theft[AFK_THEFT_TIME]
|
||||
|
||||
if(time_since > AFK_THEFT_FORGET_DETAILS_TIME)
|
||||
print_msg += "\t<span class='danger'><b>Someone [theft_message], but it was at least [DisplayTimeText(AFK_THEFT_FORGET_DETAILS_TIME)] ago.</b></span>"
|
||||
else
|
||||
print_msg += "\t<span class='danger'><b>[thief_name] [theft_message] roughly [DisplayTimeText(time_since, 10)] ago.</b></span>"
|
||||
|
||||
if(LAZYLEN(afk_thefts) >= AFK_THEFT_MAX_MESSAGES)
|
||||
print_msg += "<span class='warning'>There may have been more, but that's all you can remember...</span>"
|
||||
print_msg += "<span class='info'>*---------*</span>"
|
||||
|
||||
to_chat(src, print_msg.Join("\n"))
|
||||
LAZYNULL(afk_thefts)
|
||||
|
||||
@@ -439,6 +439,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
* * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc.
|
||||
*/
|
||||
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
|
||||
set waitfor = FALSE
|
||||
// Drop the items the new species can't wear
|
||||
for(var/slot_id in no_equip)
|
||||
var/obj/item/thing = C.get_item_by_slot(slot_id)
|
||||
@@ -679,7 +680,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/mutable_appearance/hair_overlay = mutable_appearance(layer = -HAIR_LAYER)
|
||||
if(!hair_hidden && !H.getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
|
||||
if(!(NOBLOOD in species_traits))
|
||||
hair_overlay.icon = 'icons/mob/hair.dmi'
|
||||
hair_overlay.icon = 'icons/mob/human_parts.dmi'
|
||||
hair_overlay.icon_state = "debrained"
|
||||
|
||||
else if(H.hair_style && (HAIR in species_traits))
|
||||
@@ -1364,7 +1365,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
/datum/species/proc/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.type == exotic_blood && !istype(exotic_blood, /datum/reagent/blood))
|
||||
H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM)
|
||||
H.adjust_integration_blood(round(chem.volume, 0.1))
|
||||
H.reagents.del_reagent(chem.type)
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -1458,13 +1459,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
switch(H.nutrition)
|
||||
if(NUTRITION_LEVEL_FULL to INFINITY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/fat)
|
||||
H.throw_alert("nutrition", /atom/movable/screen/alert/fat)
|
||||
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL)
|
||||
H.clear_alert("nutrition")
|
||||
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/hungry)
|
||||
H.throw_alert("nutrition", /atom/movable/screen/alert/hungry)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
H.throw_alert("nutrition", /obj/screen/alert/starving)
|
||||
H.throw_alert("nutrition", /atom/movable/screen/alert/starving)
|
||||
|
||||
/datum/species/proc/update_health_hud(mob/living/carbon/human/H)
|
||||
return 0
|
||||
@@ -1589,12 +1590,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/punchedbrute = target.getBruteLoss()
|
||||
|
||||
//CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage
|
||||
if(!SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
damage *= 1.2
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
damage *= 0.65
|
||||
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
damage *= 0.8
|
||||
//END OF CITADEL CHANGES
|
||||
|
||||
var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected))
|
||||
@@ -1718,12 +1715,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes disarmspam cause staminaloss, pugilists can do it almost effortlessly
|
||||
if(!user.UseStaminaBuffer(1, warn = TRUE))
|
||||
return
|
||||
else
|
||||
if(!user.UseStaminaBuffer(1, warn = TRUE))
|
||||
return
|
||||
if(!user.UseStaminaBuffer(1, warn = TRUE))
|
||||
return
|
||||
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
return TRUE
|
||||
@@ -1741,12 +1734,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
log_combat(user, target, "disarmed out of grab from")
|
||||
return
|
||||
var/randn = rand(1, 100)
|
||||
if(SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) // CITADEL CHANGE
|
||||
randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND)) //CITADEL CHANGE
|
||||
randn += 100 //CITADEL CHANGE - No kosher disarming if you're resting
|
||||
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) //CITADEL CHANGE
|
||||
randn += 25 //CITADEL CHANGE - Makes it harder to disarm outside of combat mode
|
||||
if(user.pulling == target)
|
||||
randn -= 20 //If you have the time to get someone in a grab, you should have a greater chance at snatching the thing in their hand. Will be made completely obsolete by the grab rework but i've got a poor track record for releasing big projects on time so w/e i guess
|
||||
if(HAS_TRAIT(user, TRAIT_PUGILIST))
|
||||
@@ -1951,9 +1940,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
|
||||
return
|
||||
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
to_chat(user, "<span class='warning'>You need combat mode to be active to that!</span>")
|
||||
return
|
||||
if(user.IsKnockdown() || user.IsParalyzed() || user.IsStun())
|
||||
to_chat(user, "<span class='warning'>You can't seem to force yourself up right now!</span>")
|
||||
return
|
||||
@@ -1993,6 +1979,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
target.adjustStaminaLoss(5)
|
||||
else
|
||||
target.adjustStaminaLoss(target.getStaminaLoss() > 75? 5 : 75)
|
||||
|
||||
if(target.is_shove_knockdown_blocked())
|
||||
return
|
||||
@@ -2035,7 +2023,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
|
||||
"<span class='danger'>[user.name] shoves you!</span>", null, COMBAT_MESSAGE_RANGE, null,
|
||||
user, "<span class='danger'>You shove [target.name]!</span>")
|
||||
target.Stagger(SHOVE_STAGGER_DURATION)
|
||||
var/obj/item/target_held_item = target.get_active_held_item()
|
||||
if(!target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
|
||||
if(target_held_item)
|
||||
@@ -2182,19 +2169,19 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
|
||||
switch((loc_temp - H.bodytemperature)*thermal_protection)
|
||||
if(-INFINITY to -50)
|
||||
H.throw_alert("tempfeel", /obj/screen/alert/cold, 3)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 3)
|
||||
if(-50 to -35)
|
||||
H.throw_alert("tempfeel", /obj/screen/alert/cold, 2)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 2)
|
||||
if(-35 to -20)
|
||||
H.throw_alert("tempfeel", /obj/screen/alert/cold, 1)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 1)
|
||||
if(-20 to 0) //This is the sweet spot where air is considered normal
|
||||
H.clear_alert("tempfeel")
|
||||
if(0 to 15) //When the air around you matches your body's temperature, you'll start to feel warm.
|
||||
H.throw_alert("tempfeel", /obj/screen/alert/hot, 1)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 1)
|
||||
if(15 to 30)
|
||||
H.throw_alert("tempfeel", /obj/screen/alert/hot, 2)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 2)
|
||||
if(30 to INFINITY)
|
||||
H.throw_alert("tempfeel", /obj/screen/alert/hot, 3)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 3)
|
||||
|
||||
// +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt.
|
||||
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT))
|
||||
@@ -2215,11 +2202,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if (burn_damage)
|
||||
switch(burn_damage)
|
||||
if(0 to 2)
|
||||
H.throw_alert("temp", /obj/screen/alert/sweat, 1)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/sweat, 1)
|
||||
if(2 to 4)
|
||||
H.throw_alert("temp", /obj/screen/alert/sweat, 2)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/sweat, 2)
|
||||
else
|
||||
H.throw_alert("temp", /obj/screen/alert/sweat, 3)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/sweat, 3)
|
||||
burn_damage = burn_damage * heatmod * H.physiology.heat_mod
|
||||
if (H.stat < UNCONSCIOUS && (prob(burn_damage) * 10) / 4) //40% for level 3 damage on humans
|
||||
H.emote("scream")
|
||||
@@ -2232,13 +2219,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.throw_alert("temp", /obj/screen/alert/shiver, 1)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/shiver, 1)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
|
||||
if(120 to 200)
|
||||
H.throw_alert("temp", /obj/screen/alert/shiver, 2)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/shiver, 2)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_2*coldmod*H.physiology.cold_mod, BURN)
|
||||
else
|
||||
H.throw_alert("temp", /obj/screen/alert/shiver, 3)
|
||||
H.throw_alert("temp", /atom/movable/screen/alert/shiver, 3)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN)
|
||||
|
||||
else
|
||||
@@ -2253,21 +2240,21 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(HAZARD_HIGH_PRESSURE to INFINITY)
|
||||
if(!HAS_TRAIT(H, TRAIT_RESISTHIGHPRESSURE))
|
||||
H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 ) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod)
|
||||
H.throw_alert("pressure", /obj/screen/alert/highpressure, 2)
|
||||
H.throw_alert("pressure", /atom/movable/screen/alert/highpressure, 2)
|
||||
else
|
||||
H.clear_alert("pressure")
|
||||
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
|
||||
H.throw_alert("pressure", /obj/screen/alert/highpressure, 1)
|
||||
H.throw_alert("pressure", /atom/movable/screen/alert/highpressure, 1)
|
||||
if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
|
||||
H.clear_alert("pressure")
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
|
||||
H.throw_alert("pressure", /atom/movable/screen/alert/lowpressure, 1)
|
||||
else
|
||||
if(HAS_TRAIT(H, TRAIT_RESISTLOWPRESSURE))
|
||||
H.clear_alert("pressure")
|
||||
else
|
||||
H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod)
|
||||
H.throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
|
||||
H.throw_alert("pressure", /atom/movable/screen/alert/lowpressure, 2)
|
||||
|
||||
//////////
|
||||
// FIRE //
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None")
|
||||
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None", "mam_body_markings" = list())
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -124,21 +124,21 @@
|
||||
brutemod = 1.25
|
||||
switch(get_charge(H))
|
||||
if(ETHEREAL_CHARGE_NONE)
|
||||
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 3)
|
||||
H.throw_alert("ethereal_charge", /atom/movable/screen/alert/etherealcharge, 3)
|
||||
if(ETHEREAL_CHARGE_NONE to ETHEREAL_CHARGE_LOWPOWER)
|
||||
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 2)
|
||||
H.throw_alert("ethereal_charge", /atom/movable/screen/alert/etherealcharge, 2)
|
||||
if(H.health > 10.5)
|
||||
apply_damage(0.65, TOX, null, null, H)
|
||||
brutemod = 1.75
|
||||
if(ETHEREAL_CHARGE_LOWPOWER to ETHEREAL_CHARGE_NORMAL)
|
||||
H.throw_alert("ethereal_charge", /obj/screen/alert/etherealcharge, 1)
|
||||
H.throw_alert("ethereal_charge", /atom/movable/screen/alert/etherealcharge, 1)
|
||||
brutemod = 1.5
|
||||
if(ETHEREAL_CHARGE_FULL to ETHEREAL_CHARGE_OVERLOAD)
|
||||
H.throw_alert("ethereal_overcharge", /obj/screen/alert/ethereal_overcharge, 1)
|
||||
H.throw_alert("ethereal_overcharge", /atom/movable/screen/alert/ethereal_overcharge, 1)
|
||||
apply_damage(0.2, TOX, null, null, H)
|
||||
brutemod = 1.5
|
||||
if(ETHEREAL_CHARGE_OVERLOAD to ETHEREAL_CHARGE_DANGEROUS)
|
||||
H.throw_alert("ethereal_overcharge", /obj/screen/alert/ethereal_overcharge, 2)
|
||||
H.throw_alert("ethereal_overcharge", /atom/movable/screen/alert/ethereal_overcharge, 2)
|
||||
apply_damage(0.65, TOX, null, null, H)
|
||||
brutemod = 1.75
|
||||
if(prob(10)) //10% each tick for ethereals to explosively release excess energy if it reaches dangerous levels
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
id = SPECIES_FELINID
|
||||
limbs_id = SPECIES_HUMAN
|
||||
|
||||
mutant_bodyparts = list("mam_tail" = "Cat", "mam_ears" = "Cat", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mam_tail" = "Cat", "mam_ears" = "Cat", "deco_wings" = "None", "mam_body_markings" = list())
|
||||
|
||||
mutantears = /obj/item/organ/ears/cat
|
||||
mutanttail = /obj/item/organ/tail/cat
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
default_color = "FFFFFF"
|
||||
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,HAS_FLESH,HAS_BONE)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade")
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None", "legs" = "Plantigrade", "mam_body_markings" = list())
|
||||
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
|
||||
@@ -53,16 +53,16 @@
|
||||
exotic_blood_color = "#" + H.dna.features["mcolor"]
|
||||
|
||||
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for blooduskers
|
||||
if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for bloodsuckers
|
||||
return
|
||||
if(!H.blood_volume)
|
||||
H.blood_volume += 5
|
||||
H.adjust_integration_blood(5)
|
||||
H.adjustBruteLoss(5)
|
||||
to_chat(H, "<span class='danger'>You feel empty!</span>")
|
||||
|
||||
if(H.blood_volume < (BLOOD_VOLUME_NORMAL * H.blood_ratio))
|
||||
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
|
||||
H.blood_volume += 3
|
||||
H.adjust_integration_blood(3)
|
||||
H.nutrition -= 2.5
|
||||
if(H.blood_volume < (BLOOD_VOLUME_OKAY*H.blood_ratio))
|
||||
if(prob(5))
|
||||
@@ -82,7 +82,7 @@
|
||||
consumed_limb.drop_limb()
|
||||
to_chat(H, "<span class='userdanger'>Your [consumed_limb] is drawn back into your body, unable to maintain its shape!</span>")
|
||||
qdel(consumed_limb)
|
||||
H.blood_volume += 20
|
||||
H.adjust_integration_blood(20)
|
||||
|
||||
////////////////////////////////////////////////////////SLIMEPEOPLE///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
if(prob(5))
|
||||
to_chat(H, "<span class='notice'>You feel very bloated!</span>")
|
||||
else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
H.blood_volume += 3
|
||||
H.adjust_integration_blood(3)
|
||||
H.nutrition -= 2.5
|
||||
|
||||
..()
|
||||
@@ -505,7 +505,7 @@
|
||||
button_icon_state = "slimeeject"
|
||||
..()
|
||||
|
||||
/datum/action/innate/integrate_extract/ApplyIcon(obj/screen/movable/action_button/current_button, force)
|
||||
/datum/action/innate/integrate_extract/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force)
|
||||
..(current_button, TRUE)
|
||||
if(species && species.current_extract)
|
||||
current_button.add_overlay(mutable_appearance(species.current_extract.icon, species.current_extract.icon_state))
|
||||
@@ -559,7 +559,7 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/use_extract/ApplyIcon(obj/screen/movable/action_button/current_button, force)
|
||||
/datum/action/innate/use_extract/ApplyIcon(atom/movable/screen/movable/action_button/current_button, force)
|
||||
..(current_button, TRUE)
|
||||
if(species && species.current_extract)
|
||||
current_button.add_overlay(mutable_appearance(species.current_extract.icon, species.current_extract.icon_state))
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
|
||||
if(environment)
|
||||
if(environment.total_moles())
|
||||
if(environment.get_moles(/datum/gas/oxygen) >= 1) //Same threshhold that extinguishes fire
|
||||
if(environment.get_moles(GAS_O2) >= 1) //Same threshhold that extinguishes fire
|
||||
H.adjust_fire_stacks(0.5)
|
||||
if(!H.on_fire && H.fire_stacks > 0)
|
||||
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/DefaultCombatKnockdown(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, knocktofloor)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ There are several things that need to be remembered:
|
||||
remove_overlay(UNIFORM_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_W_UNIFORM]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_W_UNIFORM]
|
||||
inv.update_icon()
|
||||
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
@@ -180,7 +180,7 @@ There are several things that need to be remembered:
|
||||
remove_overlay(ID_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_ID]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_ID]
|
||||
inv.update_icon()
|
||||
|
||||
var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER]
|
||||
@@ -205,7 +205,7 @@ There are several things that need to be remembered:
|
||||
remove_overlay(GLOVES_LAYER)
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_GLOVES])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES]
|
||||
inv.update_icon()
|
||||
|
||||
if(!gloves && bloody_hands)
|
||||
@@ -242,7 +242,7 @@ There are several things that need to be remembered:
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLASSES]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_GLASSES]
|
||||
inv.update_icon()
|
||||
|
||||
if(glasses)
|
||||
@@ -269,7 +269,7 @@ There are several things that need to be remembered:
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_EARS]
|
||||
inv.update_icon()
|
||||
|
||||
if(ears)
|
||||
@@ -295,7 +295,7 @@ There are several things that need to be remembered:
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
|
||||
inv.update_icon()
|
||||
|
||||
if(dna.species.mutant_bodyparts["taur"])
|
||||
@@ -330,7 +330,7 @@ There are several things that need to be remembered:
|
||||
remove_overlay(SUIT_STORE_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_S_STORE]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_S_STORE]
|
||||
inv.update_icon()
|
||||
|
||||
if(s_store)
|
||||
@@ -357,7 +357,7 @@ There are several things that need to be remembered:
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
inv.update_icon()
|
||||
|
||||
if(head)
|
||||
@@ -394,7 +394,7 @@ There are several things that need to be remembered:
|
||||
remove_overlay(BELT_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BELT]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_BELT]
|
||||
inv.update_icon()
|
||||
|
||||
if(belt)
|
||||
@@ -416,7 +416,7 @@ There are several things that need to be remembered:
|
||||
remove_overlay(SUIT_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_SUIT]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_SUIT]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_suit)
|
||||
@@ -477,7 +477,7 @@ There are several things that need to be remembered:
|
||||
|
||||
/mob/living/carbon/human/update_inv_pockets()
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv
|
||||
var/atom/movable/screen/inventory/inv
|
||||
|
||||
inv = hud_used.inv_slots[SLOT_L_STORE]
|
||||
inv.update_icon()
|
||||
@@ -506,7 +506,7 @@ There are several things that need to be remembered:
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_mask)
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
if(!targets)
|
||||
return
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
var/obj/screen/alert/give/G = C.throw_alert("[src]", /obj/screen/alert/give)
|
||||
var/atom/movable/screen/alert/give/G = C.throw_alert("[src]", /atom/movable/screen/alert/give)
|
||||
if(!G)
|
||||
return
|
||||
G.setup(C, src, receiving)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/carbon/BiologicalLife(seconds, times_fired)
|
||||
//Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs()
|
||||
handle_organs(seconds, times_fired)
|
||||
. = ..() // if . is false, we are dead.
|
||||
if(stat == DEAD)
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
@@ -23,7 +23,7 @@
|
||||
handle_brain_damage()
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_liver()
|
||||
handle_liver(seconds, times_fired)
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_corruption()
|
||||
@@ -115,16 +115,18 @@
|
||||
breath = loc_as_obj.handle_internal_lifeform(src, BREATH_VOLUME)
|
||||
|
||||
else if(isturf(loc)) //Breathe from loc as turf
|
||||
var/breath_moles = 0
|
||||
var/breath_ratio = 0
|
||||
if(environment)
|
||||
breath_moles = environment.total_moles()*BREATH_PERCENTAGE
|
||||
breath_ratio = BREATH_VOLUME/environment.return_volume()
|
||||
|
||||
breath = loc.remove_air(breath_moles)
|
||||
breath = loc.remove_air_ratio(breath_ratio)
|
||||
else //Breathe from loc as obj again
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/loc_as_obj = loc
|
||||
loc_as_obj.handle_internal_lifeform(src,0)
|
||||
|
||||
if(breath)
|
||||
breath.set_volume(BREATH_VOLUME)
|
||||
check_breath(breath)
|
||||
|
||||
if(breath)
|
||||
@@ -153,7 +155,7 @@
|
||||
adjustOxyLoss(1)
|
||||
|
||||
failed_last_breath = 1
|
||||
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
|
||||
throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
|
||||
return 0
|
||||
|
||||
var/safe_oxy_min = 16
|
||||
@@ -163,11 +165,11 @@
|
||||
var/SA_para_min = 1
|
||||
var/SA_sleep_min = 5
|
||||
var/oxygen_used = 0
|
||||
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
|
||||
|
||||
var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
|
||||
var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
|
||||
var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
|
||||
var/moles = breath.total_moles()
|
||||
var/breath_pressure = (moles*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
|
||||
var/O2_partialpressure = ((breath.get_moles(GAS_O2)/moles)*breath_pressure) + (((breath.get_moles(GAS_PLUOXIUM)*8)/moles)*breath_pressure)
|
||||
var/Toxins_partialpressure = (breath.get_moles(GAS_PLASMA)/moles)*breath_pressure
|
||||
var/CO2_partialpressure = (breath.get_moles(GAS_CO2)/moles)*breath_pressure
|
||||
|
||||
|
||||
//OXYGEN
|
||||
@@ -181,7 +183,7 @@
|
||||
adjustOxyLoss(8)
|
||||
if(prob(20))
|
||||
emote("cough")
|
||||
throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
|
||||
throw_alert("too_much_oxy", /atom/movable/screen/alert/too_much_oxy)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
|
||||
|
||||
if(O2_partialpressure < safe_oxy_min) //Not enough oxygen
|
||||
@@ -191,11 +193,11 @@
|
||||
var/ratio = 1 - O2_partialpressure/safe_oxy_min
|
||||
adjustOxyLoss(min(5*ratio, 3))
|
||||
failed_last_breath = 1
|
||||
oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
|
||||
oxygen_used = breath.get_moles(GAS_O2)*ratio
|
||||
else
|
||||
adjustOxyLoss(3)
|
||||
failed_last_breath = 1
|
||||
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
|
||||
throw_alert("not_enough_oxy", /atom/movable/screen/alert/not_enough_oxy)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
|
||||
|
||||
else //Enough oxygen
|
||||
@@ -203,12 +205,12 @@
|
||||
o2overloadtime = 0 //reset our counter for this too
|
||||
if(health >= crit_threshold)
|
||||
adjustOxyLoss(-5)
|
||||
oxygen_used = breath.get_moles(/datum/gas/oxygen)
|
||||
oxygen_used = breath.get_moles(GAS_O2)
|
||||
clear_alert("not_enough_oxy")
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
|
||||
|
||||
breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
|
||||
breath.adjust_moles(GAS_O2, -oxygen_used)
|
||||
breath.adjust_moles(GAS_CO2, oxygen_used)
|
||||
|
||||
//CARBON DIOXIDE
|
||||
if(CO2_partialpressure > safe_co2_max)
|
||||
@@ -227,15 +229,15 @@
|
||||
|
||||
//TOXINS/PLASMA
|
||||
if(Toxins_partialpressure > safe_tox_max)
|
||||
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_tox_max) * 10
|
||||
var/ratio = (breath.get_moles(GAS_PLASMA)/safe_tox_max) * 10
|
||||
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
|
||||
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
|
||||
throw_alert("too_much_tox", /atom/movable/screen/alert/too_much_tox)
|
||||
else
|
||||
clear_alert("too_much_tox")
|
||||
|
||||
//NITROUS OXIDE
|
||||
if(breath.get_moles(/datum/gas/nitrous_oxide))
|
||||
var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(GAS_NITROUS))
|
||||
var/SA_partialpressure = (breath.get_moles(GAS_NITROUS)/breath.total_moles())*breath_pressure
|
||||
if(SA_partialpressure > SA_para_min)
|
||||
Unconscious(60)
|
||||
if(SA_partialpressure > SA_sleep_min)
|
||||
@@ -248,26 +250,26 @@
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
|
||||
|
||||
//BZ (Facepunch port of their Agent B)
|
||||
if(breath.get_moles(/datum/gas/bz))
|
||||
var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(GAS_BZ))
|
||||
var/bz_partialpressure = (breath.get_moles(GAS_BZ)/breath.total_moles())*breath_pressure
|
||||
if(bz_partialpressure > 1)
|
||||
hallucination += 10
|
||||
else if(bz_partialpressure > 0.01)
|
||||
hallucination += 5
|
||||
|
||||
//TRITIUM
|
||||
if(breath.get_moles(/datum/gas/tritium))
|
||||
var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(GAS_TRITIUM))
|
||||
var/tritium_partialpressure = (breath.get_moles(GAS_TRITIUM)/breath.total_moles())*breath_pressure
|
||||
radiation += tritium_partialpressure/10
|
||||
|
||||
//NITRYL
|
||||
if(breath.get_moles(/datum/gas/nitryl))
|
||||
var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(GAS_NITRYL))
|
||||
var/nitryl_partialpressure = (breath.get_moles(GAS_NITRYL)/breath.total_moles())*breath_pressure
|
||||
adjustFireLoss(nitryl_partialpressure/4)
|
||||
|
||||
//MIASMA
|
||||
if(breath.get_moles(/datum/gas/miasma))
|
||||
var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
|
||||
if(breath.get_moles(GAS_MIASMA))
|
||||
var/miasma_partialpressure = (breath.get_moles(GAS_MIASMA)/breath.total_moles())*breath_pressure
|
||||
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
|
||||
if(prob(0.05 * miasma_partialpressure))
|
||||
@@ -365,7 +367,7 @@
|
||||
|
||||
var/datum/gas_mixture/stank = new
|
||||
|
||||
stank.set_moles(/datum/gas/miasma,0.1)
|
||||
stank.set_moles(GAS_MIASMA,0.1)
|
||||
|
||||
stank.set_temperature(BODYTEMP_NORMAL)
|
||||
|
||||
@@ -376,25 +378,25 @@
|
||||
/mob/living/carbon/proc/handle_blood()
|
||||
return
|
||||
|
||||
/mob/living/carbon/proc/handle_bodyparts()
|
||||
/mob/living/carbon/proc/handle_bodyparts(seconds, times_fired)
|
||||
for(var/I in bodyparts)
|
||||
var/obj/item/bodypart/BP = I
|
||||
if(BP.needs_processing)
|
||||
. |= BP.on_life()
|
||||
. |= BP.on_life(seconds, times_fired)
|
||||
|
||||
/mob/living/carbon/proc/handle_organs()
|
||||
/mob/living/carbon/proc/handle_organs(seconds, times_fired)
|
||||
if(stat != DEAD)
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
O.on_life()
|
||||
O.on_life(seconds, times_fired)
|
||||
else
|
||||
if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/preservahyde, 1)) // No organ decay if the body contains formaldehyde. Or preservahyde.
|
||||
return
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
O.on_death() //Needed so organs decay while inside the body.
|
||||
O.on_death(seconds, times_fired) //Needed so organs decay while inside the body.
|
||||
|
||||
/mob/living/carbon/handle_diseases()
|
||||
for(var/thing in diseases)
|
||||
@@ -510,9 +512,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
//this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc..
|
||||
/mob/living/carbon/handle_status_effects()
|
||||
..()
|
||||
var/combat_mode = SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)
|
||||
if(getStaminaLoss() && !HAS_TRAIT(src, TRAIT_NO_STAMINA_REGENERATION))
|
||||
adjustStaminaLoss((!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? STAM_RECOVERY_STAM_CRIT : STAM_RECOVERY_RESTING) : STAM_RECOVERY_NORMAL) * (combat_mode? 0.25 : 1))
|
||||
adjustStaminaLoss((!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? STAM_RECOVERY_STAM_CRIT : STAM_RECOVERY_RESTING) : STAM_RECOVERY_NORMAL))
|
||||
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && incomingstammult != 1)
|
||||
incomingstammult = max(0.01, incomingstammult)
|
||||
@@ -686,16 +687,16 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
//LIVER//
|
||||
/////////
|
||||
|
||||
/mob/living/carbon/proc/handle_liver()
|
||||
/mob/living/carbon/proc/handle_liver(seconds, times_fired)
|
||||
var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
|
||||
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
|
||||
return
|
||||
if(!liver || liver.organ_flags & ORGAN_FAILING)
|
||||
liver_failure()
|
||||
liver_failure(seconds, times_fired)
|
||||
|
||||
/mob/living/carbon/proc/liver_failure()
|
||||
/mob/living/carbon/proc/liver_failure(seconds, times_fired)
|
||||
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
|
||||
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
|
||||
reagents.metabolize(src, seconds, times_fired, can_overdose=FALSE, liverless = TRUE)
|
||||
if(HAS_TRAIT(src, TRAIT_STABLELIVER))
|
||||
return
|
||||
adjustToxLoss(4, TRUE, TRUE)
|
||||
|
||||
@@ -80,13 +80,13 @@
|
||||
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTHEAT))
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 1)
|
||||
throw_alert("temp", /atom/movable/screen/alert/hot, 1)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 2)
|
||||
throw_alert("temp", /atom/movable/screen/alert/hot, 2)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
throw_alert("temp", /atom/movable/screen/alert/hot, 3)
|
||||
if(on_fire)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
@@ -96,13 +96,13 @@
|
||||
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
throw_alert("temp", /atom/movable/screen/alert/cold, 1)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1, BURN)
|
||||
if(120 to 200)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
throw_alert("temp", /atom/movable/screen/alert/cold, 2)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2, BURN)
|
||||
if(-INFINITY to 120)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
throw_alert("temp", /atom/movable/screen/alert/cold, 3)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
clear_alert("temp")
|
||||
@@ -117,16 +117,16 @@
|
||||
switch(adjusted_pressure)
|
||||
if(HAZARD_HIGH_PRESSURE to INFINITY)
|
||||
adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
|
||||
throw_alert("pressure", /atom/movable/screen/alert/highpressure, 2)
|
||||
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/highpressure, 1)
|
||||
throw_alert("pressure", /atom/movable/screen/alert/highpressure, 1)
|
||||
if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
|
||||
clear_alert("pressure")
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
|
||||
throw_alert("pressure", /atom/movable/screen/alert/lowpressure, 1)
|
||||
else
|
||||
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
|
||||
throw_alert("pressure", /obj/screen/alert/lowpressure, 2)
|
||||
throw_alert("pressure", /atom/movable/screen/alert/lowpressure, 2)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -173,4 +173,4 @@
|
||||
if(prob(10))
|
||||
var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src)
|
||||
equip_to_slot_or_del(helmet,SLOT_HEAD)
|
||||
helmet.attack_self(src) // todo encapsulate toggle
|
||||
INVOKE_ASYNC(helmet, /obj/item.proc/attack_self, src) // todo encapsulate toggle
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
overlays_standing[HANDCUFF_LAYER] = legcuffs
|
||||
apply_overlay(LEGCUFF_LAYER)
|
||||
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
|
||||
throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = legcuffed)
|
||||
|
||||
//monkey HUD updates for items in our inventory
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
/mob/living/carbon/adjust_drugginess(amount)
|
||||
druggy = max(druggy+amount, 0)
|
||||
if(druggy)
|
||||
overlay_fullscreen("high", /obj/screen/fullscreen/high)
|
||||
throw_alert("high", /obj/screen/alert/high)
|
||||
overlay_fullscreen("high", /atom/movable/screen/fullscreen/high)
|
||||
throw_alert("high", /atom/movable/screen/alert/high)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "high", /datum/mood_event/high)
|
||||
sound_environment_override = SOUND_ENVIRONMENT_DRUGGED
|
||||
else
|
||||
@@ -18,8 +18,8 @@
|
||||
/mob/living/carbon/set_drugginess(amount)
|
||||
druggy = max(amount, 0)
|
||||
if(druggy)
|
||||
overlay_fullscreen("high", /obj/screen/fullscreen/high)
|
||||
throw_alert("high", /obj/screen/alert/high)
|
||||
overlay_fullscreen("high", /atom/movable/screen/fullscreen/high)
|
||||
throw_alert("high", /atom/movable/screen/alert/high)
|
||||
else
|
||||
clear_fullscreen("high")
|
||||
clear_alert("high")
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
inv?.update_icon()
|
||||
|
||||
if(wear_mask)
|
||||
@@ -105,7 +105,7 @@
|
||||
remove_overlay(NECK_LAYER)
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_NECK])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_NECK]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_NECK]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_neck)
|
||||
@@ -119,7 +119,7 @@
|
||||
remove_overlay(BACK_LAYER)
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK]
|
||||
inv?.update_icon()
|
||||
|
||||
if(back)
|
||||
@@ -135,7 +135,7 @@
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
inv?.update_icon()
|
||||
|
||||
if(head)
|
||||
@@ -163,7 +163,7 @@
|
||||
|
||||
overlays_standing[LEGCUFF_LAYER] = legcuffs
|
||||
apply_overlay(LEGCUFF_LAYER)
|
||||
throw_alert("legcuffed", /obj/screen/alert/restrained/legcuffed, new_master = legcuffed)
|
||||
throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = legcuffed)
|
||||
|
||||
//mob HUD updates for items in our inventory
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
/mob/living/carbon/proc/update_hud_handcuffed()
|
||||
if(hud_used)
|
||||
for(var/hand in hud_used.hand_slots)
|
||||
var/obj/screen/inventory/hand/H = hud_used.hand_slots[hand]
|
||||
var/atom/movable/screen/inventory/hand/H = hud_used.hand_slots[hand]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
ExtinguishMob()
|
||||
return
|
||||
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
|
||||
if(!G.get_moles(/datum/gas/oxygen, 1))
|
||||
if(!G.get_moles(GAS_O2, 1))
|
||||
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
|
||||
return
|
||||
var/turf/location = get_turf(src)
|
||||
|
||||
@@ -548,7 +548,7 @@
|
||||
var/severity = 0
|
||||
var/healthpercent = (health/maxHealth) * 100
|
||||
if(hud_used?.healthdoll) //to really put you in the boots of a simplemob
|
||||
var/obj/screen/healthdoll/living/livingdoll = hud_used.healthdoll
|
||||
var/atom/movable/screen/healthdoll/living/livingdoll = hud_used.healthdoll
|
||||
switch(healthpercent)
|
||||
if(100 to INFINITY)
|
||||
livingdoll.icon_state = "living0"
|
||||
@@ -579,7 +579,7 @@
|
||||
UNLINT(livingdoll.filters += filter(type="alpha", icon = mob_mask))
|
||||
livingdoll.filters += filter(type="drop_shadow", size = -1)
|
||||
if(severity > 0)
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
|
||||
@@ -869,11 +869,11 @@
|
||||
clear_alert("gravity")
|
||||
else
|
||||
if(has_gravity >= GRAVITY_DAMAGE_TRESHOLD)
|
||||
throw_alert("gravity", /obj/screen/alert/veryhighgravity)
|
||||
throw_alert("gravity", /atom/movable/screen/alert/veryhighgravity)
|
||||
else
|
||||
throw_alert("gravity", /obj/screen/alert/highgravity)
|
||||
throw_alert("gravity", /atom/movable/screen/alert/highgravity)
|
||||
else
|
||||
throw_alert("gravity", /obj/screen/alert/weightless)
|
||||
throw_alert("gravity", /atom/movable/screen/alert/weightless)
|
||||
if(!override && !is_flying())
|
||||
INVOKE_ASYNC(src, /atom/movable.proc/float, !has_gravity)
|
||||
|
||||
@@ -911,6 +911,12 @@
|
||||
"<span class='userdanger'>[src] tries to remove your [what.name].</span>", target = src,
|
||||
target_message = "<span class='danger'>You try to remove [who]'s [what.name].</span>")
|
||||
what.add_fingerprint(src)
|
||||
if(ishuman(who))
|
||||
var/mob/living/carbon/human/victim_human = who
|
||||
if(victim_human.key && !victim_human.client) // AKA braindead
|
||||
if(victim_human.stat <= SOFT_CRIT && LAZYLEN(victim_human.afk_thefts) <= AFK_THEFT_MAX_MESSAGES)
|
||||
var/list/new_entry = list(list(src.name, "tried unequipping your [what]", world.time))
|
||||
LAZYADD(victim_human.afk_thefts, new_entry)
|
||||
else
|
||||
to_chat(src,"<span class='notice'>You try to remove [who]'s [what.name].</span>")
|
||||
what.add_fingerprint(src)
|
||||
@@ -957,6 +963,13 @@
|
||||
to_chat(src, "<span class='warning'>\The [what.name] doesn't fit in that place!</span>")
|
||||
return
|
||||
|
||||
if(ishuman(who))
|
||||
var/mob/living/carbon/human/victim_human = who
|
||||
if(victim_human.key && !victim_human.client) // AKA braindead
|
||||
if(victim_human.stat <= SOFT_CRIT && LAZYLEN(victim_human.afk_thefts) <= AFK_THEFT_MAX_MESSAGES)
|
||||
var/list/new_entry = list(list(src.name, "tried equipping you with [what]", world.time))
|
||||
LAZYADD(victim_human.afk_thefts, new_entry)
|
||||
|
||||
who.visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>",
|
||||
"<span class='notice'>[src] tries to put [what] on you.</span>", target = src,
|
||||
target_message = "<span class='notice'>You try to put [what] on [who].</span>")
|
||||
@@ -995,7 +1008,7 @@
|
||||
loc_temp = obj_temp
|
||||
else if(isspaceturf(get_turf(src)))
|
||||
var/turf/heat_turf = get_turf(src)
|
||||
loc_temp = heat_turf.temperature
|
||||
loc_temp = heat_turf.return_temperature()
|
||||
return loc_temp
|
||||
|
||||
/mob/living/proc/get_standard_pixel_x_offset(lying = 0)
|
||||
@@ -1146,7 +1159,7 @@
|
||||
visible_message("<span class='warning'>[src] catches fire!</span>", \
|
||||
"<span class='userdanger'>You're set on fire!</span>")
|
||||
new/obj/effect/dummy/lighting_obj/moblight/fire(src)
|
||||
throw_alert("fire", /obj/screen/alert/fire)
|
||||
throw_alert("fire", /atom/movable/screen/alert/fire)
|
||||
update_fire()
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_IGNITED,src)
|
||||
return TRUE
|
||||
|
||||
@@ -48,25 +48,23 @@
|
||||
animate(src, pixel_x = get_standard_pixel_x_offset(), pixel_y = get_standard_pixel_y_offset(), time = 2.5, FALSE, SINE_EASING | EASE_IN)
|
||||
|
||||
/mob/living/proc/continue_starting_active_block()
|
||||
if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
return DO_AFTER_STOP
|
||||
return (combat_flags & COMBAT_FLAG_ACTIVE_BLOCK_STARTING)? DO_AFTER_CONTINUE : DO_AFTER_STOP
|
||||
|
||||
/mob/living/get_standard_pixel_x_offset()
|
||||
. = ..()
|
||||
if(combat_flags & (COMBAT_FLAG_ACTIVE_BLOCK_STARTING | COMBAT_FLAG_ACTIVE_BLOCKING))
|
||||
if(dir & EAST)
|
||||
. += 8
|
||||
. += 4
|
||||
if(dir & WEST)
|
||||
. -= 8
|
||||
. -= 4
|
||||
|
||||
/mob/living/get_standard_pixel_y_offset()
|
||||
. = ..()
|
||||
if(combat_flags & (COMBAT_FLAG_ACTIVE_BLOCK_STARTING | COMBAT_FLAG_ACTIVE_BLOCKING))
|
||||
if(dir & NORTH)
|
||||
. += 8
|
||||
. += 4
|
||||
if(dir & SOUTH)
|
||||
. -= 8
|
||||
. -= 4
|
||||
|
||||
/**
|
||||
* Proc called by keybindings to toggle active blocking.
|
||||
@@ -100,11 +98,6 @@
|
||||
if(!I.can_active_block())
|
||||
to_chat(src, "<span class='warning'>[I] is either not capable of being used to actively block, or is not currently in a state that can! (Try wielding it if it's twohanded, for example.)</span>")
|
||||
return
|
||||
// QOL: Attempt to toggle on combat mode if it isn't already
|
||||
SEND_SIGNAL(src, COMSIG_ENABLE_COMBAT_MODE)
|
||||
if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
to_chat(src, "<span class='warning'>You must be in combat mode to actively block!</span>")
|
||||
return FALSE
|
||||
var/datum/block_parry_data/data = I.get_block_parry_data()
|
||||
var/delay = data.block_start_delay
|
||||
combat_flags |= COMBAT_FLAG_ACTIVE_BLOCK_STARTING
|
||||
@@ -147,7 +140,7 @@
|
||||
/**
|
||||
* Calculates FINAL ATTACK DAMAGE after mitigation
|
||||
*/
|
||||
/obj/item/proc/active_block_calculate_final_damage(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
/obj/item/proc/active_block_calculate_final_damage(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, passive = FALSE)
|
||||
var/datum/block_parry_data/data = get_block_parry_data()
|
||||
var/absorption = data.attack_type_list_scan(data.block_damage_absorption_override, attack_type)
|
||||
var/efficiency = data.attack_type_list_scan(data.block_damage_multiplier_override, attack_type)
|
||||
@@ -156,7 +149,7 @@
|
||||
if(isnull(absorption))
|
||||
absorption = data.block_damage_absorption
|
||||
if(isnull(efficiency))
|
||||
efficiency = data.block_damage_multiplier
|
||||
efficiency = data.block_damage_multiplier * (passive? (1 / data.block_automatic_mitigation_multiplier) : 1)
|
||||
if(isnull(limit))
|
||||
limit = data.block_damage_limit
|
||||
// now we calculate damage to reduce.
|
||||
@@ -172,7 +165,7 @@
|
||||
return final_damage
|
||||
|
||||
/// Amount of stamina from damage blocked. Note that the damage argument is damage_blocked.
|
||||
/obj/item/proc/active_block_stamina_cost(mob/living/owner, atom/object, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
/obj/item/proc/active_block_stamina_cost(mob/living/owner, atom/object, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, passive = FALSE)
|
||||
var/datum/block_parry_data/data = get_block_parry_data()
|
||||
var/efficiency = data.attack_type_list_scan(data.block_stamina_efficiency_override, attack_type)
|
||||
if(isnull(efficiency))
|
||||
@@ -182,7 +175,7 @@
|
||||
multiplier = data.attack_type_list_scan(data.block_resting_stamina_penalty_multiplier_override, attack_type)
|
||||
if(isnull(multiplier))
|
||||
multiplier = data.block_resting_stamina_penalty_multiplier
|
||||
return (damage_blocked / efficiency) * multiplier
|
||||
return (damage_blocked / efficiency) * multiplier * (passive? data.block_automatic_stamina_multiplier : 1)
|
||||
|
||||
/// Apply the stamina damage to our user, notice how damage argument is stamina_amount.
|
||||
/obj/item/proc/active_block_do_stamina_damage(mob/living/owner, atom/object, stamina_amount, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
@@ -214,6 +207,18 @@
|
||||
return
|
||||
|
||||
/obj/item/proc/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
return directional_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, override_direction)
|
||||
|
||||
/obj/item/proc/can_passive_block()
|
||||
if(!block_parry_data || !(item_flags & ITEM_CAN_BLOCK))
|
||||
return FALSE
|
||||
var/datum/block_parry_data/data = return_block_parry_datum(block_parry_data)
|
||||
return data.block_automatic_enabled
|
||||
|
||||
/obj/item/proc/passive_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
return directional_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, override_direction, TRUE)
|
||||
|
||||
/obj/item/proc/directional_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction, passive = FALSE)
|
||||
if(!can_active_block())
|
||||
return BLOCK_NONE
|
||||
var/datum/block_parry_data/data = get_block_parry_data()
|
||||
@@ -228,12 +233,12 @@
|
||||
incoming_direction = get_dir(get_turf(attacker) || get_turf(object), src)
|
||||
if(!CHECK_MOBILITY(owner, MOBILITY_STAND) && !(data.block_resting_attack_types_anydir & attack_type) && (!(data.block_resting_attack_types_directional & attack_type) || !can_block_direction(owner.dir, incoming_direction)))
|
||||
return BLOCK_NONE
|
||||
else if(!can_block_direction(owner.dir, incoming_direction))
|
||||
else if(!can_block_direction(owner.dir, incoming_direction, passive))
|
||||
return BLOCK_NONE
|
||||
block_return[BLOCK_RETURN_ACTIVE_BLOCK] = TRUE
|
||||
var/final_damage = active_block_calculate_final_damage(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
var/final_damage = active_block_calculate_final_damage(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, passive)
|
||||
var/damage_blocked = damage - final_damage
|
||||
var/stamina_cost = active_block_stamina_cost(owner, object, damage_blocked, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
var/stamina_cost = active_block_stamina_cost(owner, object, damage_blocked, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return, passive)
|
||||
active_block_do_stamina_damage(owner, object, stamina_cost, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
block_return[BLOCK_RETURN_ACTIVE_BLOCK_DAMAGE_MITIGATED] = damage - final_damage
|
||||
block_return[BLOCK_RETURN_SET_DAMAGE_TO] = final_damage
|
||||
@@ -261,9 +266,9 @@
|
||||
/**
|
||||
* Gets the block direction bitflags of what we can block.
|
||||
*/
|
||||
/obj/item/proc/blockable_directions()
|
||||
/obj/item/proc/blockable_directions(passive = FALSE)
|
||||
var/datum/block_parry_data/data = get_block_parry_data()
|
||||
return data.can_block_directions
|
||||
return (!isnull(data.block_automatic_directions) && passive)? data.block_automatic_directions : data.can_block_directions
|
||||
|
||||
/**
|
||||
* Checks if we can block from a specific direction from our direction.
|
||||
@@ -272,14 +277,14 @@
|
||||
* * our_dir - our direction.
|
||||
* * their_dir - their direction. Must be a single direction, or NONE for an attack from the same tile. This is incoming direction.
|
||||
*/
|
||||
/obj/item/proc/can_block_direction(our_dir, their_dir)
|
||||
/obj/item/proc/can_block_direction(our_dir, their_dir, passive = FALSE)
|
||||
their_dir = turn(their_dir, 180)
|
||||
if(our_dir != NORTH)
|
||||
var/turn_angle = dir2angle(our_dir)
|
||||
// dir2angle(), ss13 proc is clockwise so dir2angle(EAST) == 90
|
||||
// turn(), byond proc is counterclockwise so turn(NORTH, 90) == WEST
|
||||
their_dir = turn(their_dir, turn_angle)
|
||||
return (DIR2BLOCKDIR(their_dir) & blockable_directions())
|
||||
return (DIR2BLOCKDIR(their_dir) & blockable_directions(passive))
|
||||
|
||||
/**
|
||||
* can_block_direction but for "compound" directions to check all of them and return the number of directions that were blocked.
|
||||
|
||||
@@ -14,18 +14,58 @@
|
||||
/**
|
||||
* Initiates a parrying sequence.
|
||||
*/
|
||||
/mob/living/proc/initiate_parry_sequence()
|
||||
/mob/living/proc/initiate_parry_sequence(silent = FALSE, list/override_method_data)
|
||||
if(parrying)
|
||||
return // already parrying
|
||||
return FALSE // already parrying
|
||||
if(!(mobility_flags & MOBILITY_USE))
|
||||
to_chat(src, "<span class='warning'>You can't move your arms!</span>")
|
||||
return
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You can't move your arms!</span>")
|
||||
return FALSE
|
||||
if(!(combat_flags & COMBAT_FLAG_PARRY_CAPABLE))
|
||||
to_chat(src, "<span class='warning'>You are not something that can parry attacks.</span>")
|
||||
return
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You are not something that can parry attacks.</span>")
|
||||
return FALSE
|
||||
if(!(mobility_flags & MOBILITY_STAND))
|
||||
to_chat(src, "<span class='warning'>You aren't able to parry without solid footing!</span>")
|
||||
return
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You aren't able to parry without solid footing!</span>")
|
||||
return FALSE
|
||||
var/datum/block_parry_data/data
|
||||
var/list/determined = override_method_data || determine_parry_method(FALSE, FALSE)
|
||||
if(!islist(determined))
|
||||
return FALSE
|
||||
var/method = determined[1]
|
||||
data = return_block_parry_datum(determined[2])
|
||||
var/datum/tool = determined[3]
|
||||
var/full_parry_duration = data.parry_time_windup + data.parry_time_active + data.parry_time_spindown
|
||||
// no system in place to "fallback" if out of the 3 the top priority one can't parry due to constraints but something else can.
|
||||
// can always implement it later, whatever.
|
||||
if((data.parry_respect_clickdelay && !CheckActionCooldown()) || ((parry_end_time_last + data.parry_cooldown) > world.time))
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You are not ready to parry (again)!</span>")
|
||||
return FALSE
|
||||
// Point of no return, make sure everything is set.
|
||||
parrying = method
|
||||
if(method == ITEM_PARRY)
|
||||
active_parry_item = tool
|
||||
if(!UseStaminaBuffer(data.parry_stamina_cost, TRUE))
|
||||
return FALSE
|
||||
parry_start_time = world.time
|
||||
successful_parries = list()
|
||||
successful_parry_counterattacks = list()
|
||||
addtimer(CALLBACK(src, .proc/end_parry_sequence), full_parry_duration)
|
||||
if(data.parry_flags & PARRY_LOCK_ATTACKING)
|
||||
ADD_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_PARRY_TRAIT)
|
||||
if(data.parry_flags & PARRY_LOCK_SPRINTING)
|
||||
ADD_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_PARRY_TRAIT)
|
||||
handle_parry_starting_effects(data)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Massive snowflake proc for getting something to parry with.
|
||||
*
|
||||
* @return list of [method, data, tool], where method is the parry method define, data is the block_parry_data var that must be run through return_block_parry_data, and tool is the concept/object/martial art/etc used.
|
||||
*/
|
||||
/mob/living/proc/determine_parry_method(silent = TRUE, autoparry = FALSE)
|
||||
// Prioritize item, then martial art, then unarmed.
|
||||
// yanderedev else if time
|
||||
var/obj/item/using_item = get_active_held_item()
|
||||
@@ -55,7 +95,8 @@
|
||||
var/list/other_items = list()
|
||||
var/list/override = list()
|
||||
if(SEND_SIGNAL(src, COMSIG_LIVING_ACTIVE_PARRY_START, method, tool, other_items, override) & COMPONENT_PREVENT_PARRY_START)
|
||||
to_chat(src, "<span class='warning'>Something is preventing you from parrying!</span>")
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>Something is preventing you from parrying!</span>")
|
||||
return
|
||||
if(length(override))
|
||||
var/datum/thing = override[1]
|
||||
@@ -72,35 +113,10 @@
|
||||
method = ITEM_PARRY
|
||||
data = using_item.block_parry_data
|
||||
if(!method)
|
||||
to_chat(src, "<span class='warning'>You have nothing to parry with!</span>")
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You have nothing to parry with!</span>")
|
||||
return FALSE
|
||||
//QOL: Try to enable combat mode if it isn't already
|
||||
SEND_SIGNAL(src, COMSIG_ENABLE_COMBAT_MODE)
|
||||
if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
to_chat(src, "<span class='warning'>You must be in combat mode to parry!</span>")
|
||||
return FALSE
|
||||
data = return_block_parry_datum(data)
|
||||
var/full_parry_duration = data.parry_time_windup + data.parry_time_active + data.parry_time_spindown
|
||||
// no system in place to "fallback" if out of the 3 the top priority one can't parry due to constraints but something else can.
|
||||
// can always implement it later, whatever.
|
||||
if((data.parry_respect_clickdelay && !CheckActionCooldown()) || ((parry_end_time_last + data.parry_cooldown) > world.time))
|
||||
to_chat(src, "<span class='warning'>You are not ready to parry (again)!</span>")
|
||||
return FALSE
|
||||
// Point of no return, make sure everything is set.
|
||||
parrying = method
|
||||
if(method == ITEM_PARRY)
|
||||
active_parry_item = using_item
|
||||
if(!UseStaminaBuffer(data.parry_stamina_cost, TRUE))
|
||||
return FALSE
|
||||
parry_start_time = world.time
|
||||
successful_parries = list()
|
||||
addtimer(CALLBACK(src, .proc/end_parry_sequence), full_parry_duration)
|
||||
if(data.parry_flags & PARRY_LOCK_ATTACKING)
|
||||
ADD_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_PARRY_TRAIT)
|
||||
if(data.parry_flags & PARRY_LOCK_SPRINTING)
|
||||
ADD_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_PARRY_TRAIT)
|
||||
handle_parry_starting_effects(data)
|
||||
return TRUE
|
||||
return list(method, data, tool)
|
||||
|
||||
/**
|
||||
* Tries to find a backup parry item.
|
||||
@@ -146,6 +162,7 @@
|
||||
parry_start_time = 0
|
||||
parry_end_time_last = world.time + (successful? 0 : data.parry_failed_cooldown_duration)
|
||||
successful_parries = null
|
||||
successful_parry_counterattacks = null
|
||||
|
||||
/**
|
||||
* Handles starting effects for parrying.
|
||||
@@ -178,17 +195,17 @@
|
||||
/**
|
||||
* Called when an attack is parried using this, whether or not the parry was successful.
|
||||
*/
|
||||
/obj/item/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
/obj/item/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time, autoparry = FALSE)
|
||||
|
||||
/**
|
||||
* Called when an attack is parried innately, whether or not the parry was successful.
|
||||
*/
|
||||
/mob/living/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
/mob/living/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time, autoparry = FALSE)
|
||||
|
||||
/**
|
||||
* Called when an attack is parried using this, whether or not the parry was successful.
|
||||
*/
|
||||
/datum/martial_art/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
|
||||
/datum/martial_art/proc/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time, autoparry = FALSE)
|
||||
|
||||
/**
|
||||
* Called when an attack is parried and block_parra_data indicates to use a proc to handle counterattack.
|
||||
@@ -205,6 +222,94 @@
|
||||
*/
|
||||
/datum/martial_art/proc/active_parry_reflex_counter(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, parry_efficiency, list/effect_text)
|
||||
|
||||
/**
|
||||
* Attempts to automatically parry an attacker.
|
||||
*/
|
||||
/mob/living/proc/attempt_auto_parry(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list())
|
||||
// determine how we'll parry
|
||||
var/list/determined = determine_parry_method(TRUE, TRUE)
|
||||
if(!islist(determined))
|
||||
return BLOCK_NONE
|
||||
var/datum/block_parry_data/data = return_block_parry_datum(determined[2])
|
||||
if(!data.parry_automatic_enabled || (last_autoparry > (world.time - data.autoparry_cooldown_absolute)))
|
||||
return BLOCK_NONE
|
||||
if(attack_type && !(attack_type & data.parry_attack_types))
|
||||
return BLOCK_NONE
|
||||
// before doing anything, check if the user moused over them properly
|
||||
if(!client)
|
||||
return BLOCK_NONE
|
||||
var/found = attacker == client.mouseObject
|
||||
if(!found)
|
||||
for(var/i in client.moused_over_objects)
|
||||
if(i == object)
|
||||
if((client.moused_over_objects[i] + (data.autoparry_mouse_delay_maximum)) >= world.time)
|
||||
found = TRUE
|
||||
break
|
||||
if(!found)
|
||||
return BLOCK_NONE
|
||||
|
||||
// if that works, try to start parry
|
||||
// first, check cooldowns
|
||||
|
||||
// now, depending on if we're doing a single simulation or a full sequence
|
||||
last_autoparry = world.time
|
||||
if(data.autoparry_sequence_simulation)
|
||||
// for full sequence simulation
|
||||
initiate_parry_sequence(TRUE, determined)
|
||||
if(data.autoparry_sequence_start_time == -1)
|
||||
parry_start_time = world.time - data.parry_time_windup
|
||||
else
|
||||
parry_start_time = world.time - data.autoparry_sequence_start_time
|
||||
// recurse back to original
|
||||
return run_parry(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, FALSE)
|
||||
else
|
||||
// yes, this is mostly a copypaste of run_parry.
|
||||
var/efficiency = data.attack_type_list_scan(data.autoparry_single_efficiency_override, attack_type)
|
||||
if(isnull(efficiency))
|
||||
efficiency = data.autoparry_single_efficiency
|
||||
var/method = determined[1]
|
||||
switch(method)
|
||||
if(ITEM_PARRY)
|
||||
var/obj/item/I = determined[3]
|
||||
. = I.on_active_parry(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, null, TRUE)
|
||||
if(UNARMED_PARRY)
|
||||
. = on_active_parry(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, null, TRUE)
|
||||
if(MARTIAL_PARRY)
|
||||
. = mind.martial_art.on_active_parry(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, null, TRUE)
|
||||
if(!isnull(return_list[BLOCK_RETURN_OVERRIDE_PARRY_EFFICIENCY])) // one of our procs overrode
|
||||
efficiency = return_list[BLOCK_RETURN_OVERRIDE_PARRY_EFFICIENCY]
|
||||
if(efficiency <= 0) // Do not allow automatically handled/standardized parries that increase damage for now.
|
||||
return
|
||||
. |= BLOCK_SHOULD_PARTIAL_MITIGATE
|
||||
if(efficiency >= data.parry_efficiency_perfect)
|
||||
. |= data.perfect_parry_block_return_flags
|
||||
if(data.perfect_parry_block_return_list)
|
||||
return_list |= data.perfect_parry_block_return_list
|
||||
else if(efficiency >= data.parry_efficiency_considered_successful)
|
||||
. |= data.imperfect_parry_block_return_flags
|
||||
if(data.imperfect_parry_block_return_list)
|
||||
return_list |= data.imperfect_parry_block_return_list
|
||||
else
|
||||
. |= data.failed_parry_block_return_flags
|
||||
if(data.failed_parry_block_return_list)
|
||||
return_list |= data.failed_parry_block_return_list
|
||||
if(isnull(return_list[BLOCK_RETURN_MITIGATION_PERCENT])) // if one of the on_active_parry procs overrode. We don't have to worry about interference since parries are the first thing checked in the [do_run_block()] sequence.
|
||||
return_list[BLOCK_RETURN_MITIGATION_PERCENT] = clamp(efficiency, 0, 100) // do not allow > 100% or < 0% for now.
|
||||
if((return_list[BLOCK_RETURN_MITIGATION_PERCENT] >= 100) || (damage <= 0))
|
||||
. |= BLOCK_SUCCESS
|
||||
var/list/effect_text
|
||||
var/pacifist_counter_check = TRUE
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM))
|
||||
switch(parrying)
|
||||
if(ITEM_PARRY)
|
||||
pacifist_counter_check = (!active_parry_item.force || active_parry_item.damtype == STAMINA)
|
||||
else
|
||||
pacifist_counter_check = FALSE //Both martial and unarmed counter attacks generally are harmful, so no need to have the same line twice.
|
||||
if(efficiency >= data.parry_efficiency_to_counterattack && pacifist_counter_check && !return_list[BLOCK_RETURN_FORCE_NO_PARRY_COUNTERATTACK] && (!(attacker in successful_parry_counterattacks) && !data.parry_allow_repeated_counterattacks))
|
||||
effect_text = run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, data)
|
||||
if(data.parry_flags & PARRY_DEFAULT_HANDLE_FEEDBACK)
|
||||
handle_parry_feedback(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, effect_text, data)
|
||||
|
||||
/**
|
||||
* Gets the stage of our parry sequence we're currently in.
|
||||
*/
|
||||
@@ -235,12 +340,20 @@
|
||||
return world.time - parry_start_time
|
||||
|
||||
/// same return values as normal blocking, called with absolute highest priority in the block "chain".
|
||||
/mob/living/proc/run_parry(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list())
|
||||
/mob/living/proc/run_parry(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), allow_auto = TRUE)
|
||||
var/stage = get_parry_stage()
|
||||
if(attack_type & ATTACK_TYPE_PARRY_COUNTERATTACK)
|
||||
return BLOCK_NONE // don't infinite loop
|
||||
if(stage != PARRY_ACTIVE)
|
||||
return BLOCK_NONE
|
||||
// If they're not currently parrying, attempt auto parry
|
||||
if(stage == NOT_PARRYING)
|
||||
if(!allow_auto || SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
return BLOCK_NONE
|
||||
return attempt_auto_parry(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)
|
||||
else
|
||||
return BLOCK_NONE
|
||||
var/datum/block_parry_data/data = get_parry_data()
|
||||
if(attack_type && (!(attack_type & data.parry_attack_types) || (attack_type & ATTACK_TYPE_PARRY_COUNTERATTACK))) // if this attack is from a parry do not parry it lest we infinite loop.
|
||||
if(attack_type && !(attack_type & data.parry_attack_types))
|
||||
return BLOCK_NONE
|
||||
var/efficiency = data.get_parry_efficiency(attack_type, get_parry_time())
|
||||
switch(parrying)
|
||||
@@ -281,7 +394,7 @@
|
||||
pacifist_counter_check = (!active_parry_item.force || active_parry_item.damtype == STAMINA)
|
||||
else
|
||||
pacifist_counter_check = FALSE //Both martial and unarmed counter attacks generally are harmful, so no need to have the same line twice.
|
||||
if(efficiency >= data.parry_efficiency_to_counterattack && pacifist_counter_check)
|
||||
if(efficiency >= data.parry_efficiency_to_counterattack && pacifist_counter_check && !return_list[BLOCK_RETURN_FORCE_NO_PARRY_COUNTERATTACK] && (!(attacker in successful_parry_counterattacks) && !data.parry_allow_repeated_counterattacks))
|
||||
effect_text = run_parry_countereffects(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency)
|
||||
if(data.parry_flags & PARRY_DEFAULT_HANDLE_FEEDBACK)
|
||||
handle_parry_feedback(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, effect_text)
|
||||
@@ -289,8 +402,9 @@
|
||||
if(length(successful_parries) >= data.parry_max_attacks)
|
||||
end_parry_sequence()
|
||||
|
||||
/mob/living/proc/handle_parry_feedback(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency, list/effect_text)
|
||||
var/datum/block_parry_data/data = get_parry_data()
|
||||
/mob/living/proc/handle_parry_feedback(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency, list/effect_text, datum/block_parry_data/data)
|
||||
if(!data)
|
||||
data = get_parry_data()
|
||||
var/knockdown_check = FALSE
|
||||
if(data.parry_data[PARRY_KNOCKDOWN_ATTACKER] && parry_efficiency >= data.parry_efficiency_to_counterattack)
|
||||
knockdown_check = TRUE
|
||||
@@ -299,12 +413,14 @@
|
||||
visible_message("<span class='danger'>[src] parries [attack_text][length(effect_text)? ", [english_list(effect_text)] [attacker]" : ""][length(effect_text) && knockdown_check? " and" : ""][knockdown_check? " knocking them to the ground" : ""]!</span>")
|
||||
|
||||
/// Run counterattack if any
|
||||
/mob/living/proc/run_parry_countereffects(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency)
|
||||
/mob/living/proc/run_parry_countereffects(atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list(), parry_efficiency, datum/block_parry_data/data)
|
||||
if(!isliving(attacker))
|
||||
return
|
||||
var/mob/living/L = attacker
|
||||
var/datum/block_parry_data/data = get_parry_data()
|
||||
if(!data)
|
||||
data = get_parry_data()
|
||||
var/list/effect_text = list()
|
||||
successful_parry_counterattacks |= attacker
|
||||
// Always proc so items can override behavior easily
|
||||
switch(parrying)
|
||||
if(ITEM_PARRY)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
var/results
|
||||
if(I == active_block_item)
|
||||
results = I.active_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list, attack_direction)
|
||||
else if(I.can_passive_block() && !SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
results = I.passive_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list, attack_direction)
|
||||
else
|
||||
results = I.run_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list)
|
||||
. |= results
|
||||
|
||||
@@ -75,7 +75,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
var/block_stamina_buffer_ratio = 1
|
||||
|
||||
/// Stamina dealt directly via UseStaminaBuffer() per SECOND of block.
|
||||
var/block_stamina_cost_per_second = 1.5
|
||||
var/block_stamina_cost_per_second = 1
|
||||
/// Prevent stamina buffer regeneration while block?
|
||||
var/block_no_stambuffer_regeneration = TRUE
|
||||
/// Prevent stamina regeneration while block?
|
||||
@@ -93,20 +93,31 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Sounds for blocking
|
||||
var/list/block_sounds = list('sound/block_parry/block_metal1.ogg' = 1, 'sound/block_parry/block_metal1.ogg' = 1)
|
||||
|
||||
// Autoblock
|
||||
// Other than for overrides, this mostly just reads from the above vars
|
||||
/// Can this item automatically block?
|
||||
var/block_automatic_enabled = TRUE
|
||||
/// Directions that you can autoblock in. Null to default to normal directions.
|
||||
var/block_automatic_directions = null
|
||||
/// Effectiveness multiplier for automated block. Only applies to efficiency, absorption and limits stay the same!
|
||||
var/block_automatic_mitigation_multiplier = 0.33
|
||||
/// Stamina cost multiplier for automated block
|
||||
var/block_automatic_stamina_multiplier = 1
|
||||
|
||||
/////////// PARRYING ////////////
|
||||
/// Prioriry for [mob/do_run_block()] while we're being used to parry.
|
||||
/// Priority for [mob/do_run_block()] while we're being used to parry.
|
||||
// None - Parry is always highest priority!
|
||||
/// Parry doesn't work if you aren't able to otherwise attack due to clickdelay
|
||||
var/parry_respect_clickdelay = TRUE
|
||||
var/parry_respect_clickdelay = FALSE
|
||||
/// Parry stamina cost
|
||||
var/parry_stamina_cost = 5
|
||||
/// Attack types we can block
|
||||
var/parry_attack_types = ALL
|
||||
/// Parry flags
|
||||
var/parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
var/parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK
|
||||
|
||||
/// Parry windup duration in deciseconds. 0 to this is windup, afterwards is main stage.
|
||||
var/parry_time_windup = 2
|
||||
var/parry_time_windup = 0
|
||||
/// Parry spindown duration in deciseconds. main stage end to this is the spindown stage, afterwards the parry fully ends.
|
||||
var/parry_time_spindown = 3
|
||||
/// Main parry window in deciseconds. This is between [parry_time_windup] and [parry_time_spindown]
|
||||
@@ -139,7 +150,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Efficiency must be at least this to be considered successful
|
||||
var/parry_efficiency_considered_successful = 0.1
|
||||
/// Efficiency must be at least this to run automatic counterattack
|
||||
var/parry_efficiency_to_counterattack = 0.1
|
||||
var/parry_efficiency_to_counterattack = INFINITY
|
||||
/// Maximum attacks to parry successfully or unsuccessfully (but not efficiency < 0) during active period, hitting this immediately ends the sequence.
|
||||
var/parry_max_attacks = INFINITY
|
||||
/// Visual icon state override for parrying
|
||||
@@ -153,7 +164,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Stagger duration post-parry if you fail to parry an attack
|
||||
var/parry_failed_stagger_duration = 3.5 SECONDS
|
||||
/// Clickdelay duration post-parry if you fail to parry an attack
|
||||
var/parry_failed_clickcd_duration = 2 SECONDS
|
||||
var/parry_failed_clickcd_duration = 0 SECONDS
|
||||
/// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!!
|
||||
var/parry_failed_cooldown_duration = 0 SECONDS
|
||||
|
||||
@@ -166,6 +177,29 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
var/perfect_parry_block_return_list
|
||||
var/imperfect_parry_block_return_list
|
||||
var/failed_parry_block_return_list
|
||||
/// Allow multiple counterattacks per parry sequence. Bad idea.
|
||||
var/parry_allow_repeated_counterattacks = FALSE
|
||||
|
||||
// Auto parry
|
||||
// Anything not specified like cooldowns/clickdelay respecting is pulled from above.
|
||||
/// Can this data automatically parry? This is off by default because this is something that requires thought to balance.
|
||||
var/parry_automatic_enabled = FALSE
|
||||
/// Hard autoparry cooldown
|
||||
var/autoparry_cooldown_absolute = 7.5 SECONDS
|
||||
/// Autoparry : Simulate a parry sequence starting at a certain tick, or simply simulate a single attack parry?
|
||||
var/autoparry_sequence_simulation = FALSE
|
||||
// Single attack simulation:
|
||||
/// Single attack autoparry - efficiency
|
||||
var/autoparry_single_efficiency = 75
|
||||
/// Single attack autoparry - efficiency overrides by attack type, see above
|
||||
var/list/autoparry_single_efficiency_override
|
||||
// Parry sequence simulation:
|
||||
/// Decisecond of sequence to start on. -1 to start to 0th tick of active parry window.
|
||||
var/autoparry_sequence_start_time = -1
|
||||
// Clickdelay/cooldown settings not included, as well as whether or not to lock attack/sprinting/etc. They will be pulled from the above.
|
||||
|
||||
/// ADVANCED - Autoparry requirement for time since last moused over for a specific object
|
||||
var/autoparry_mouse_delay_maximum = 0.35 SECONDS
|
||||
|
||||
/**
|
||||
* Quirky proc to get average of flags in list that are in attack_type because why is attack_type a flag.
|
||||
@@ -308,6 +342,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
RENDER_VARIABLE_SIMPLE(parry_cooldown, "Deciseconds it has to be since the last time a parry sequence <b>ended</b> for you before you can parry again.")
|
||||
RENDER_VARIABLE_SIMPLE(parry_failed_stagger_duration, "Deciseconds you are staggered for at the of the parry sequence if you do not successfully parry anything.")
|
||||
RENDER_VARIABLE_SIMPLE(parry_failed_clickcd_duration, "Deciseconds you are put on attack cooldown at the end of the parry sequence if you do not successfully parry anything.")
|
||||
dat += ""
|
||||
dat += "</div></table>"
|
||||
return dat.Join("")
|
||||
#undef RENDER_VARIABLE_SIMPLE
|
||||
|
||||
@@ -539,7 +539,7 @@
|
||||
|
||||
|
||||
//called when the mob receives a bright flash
|
||||
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash, override_protection = 0)
|
||||
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, override_protection = 0)
|
||||
if((override_protection || get_eye_protection() < intensity) && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND))))
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
|
||||
|
||||
@@ -50,8 +50,12 @@
|
||||
var/obj/effect/abstract/parry/parry_visual_effect
|
||||
/// world.time of last parry end
|
||||
var/parry_end_time_last = 0
|
||||
/// Last autoparry
|
||||
var/last_autoparry = 0
|
||||
/// Successful parries within the current parry cycle. It's a list of efficiency percentages.
|
||||
var/list/successful_parries
|
||||
/// Current parry counterattacks. Makes sure we can only counterattack someone once per parry.
|
||||
var/list/successful_parry_counterattacks
|
||||
|
||||
var/confused = 0 //Makes the mob move in random directions.
|
||||
|
||||
@@ -63,8 +67,6 @@
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
|
||||
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
|
||||
/// Do we make floors dirty as we move?
|
||||
var/causes_dirt_buildup_on_floor = FALSE
|
||||
|
||||
var/list/roundstart_quirks = list()
|
||||
|
||||
@@ -110,6 +112,7 @@
|
||||
var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added
|
||||
|
||||
var/blood_volume = 0 //how much blood the mob has
|
||||
var/integrating_blood = 0 //this is the variable you want to affect if you want to give the mob blood, this will slowly turn into normal blood, preventing some cheesyness, use adjust_integration_blood() instead of modifying directly
|
||||
var/blood_ratio = 1 //How much blood the mob needs, in terms of ratio (i.e 1.2 will require BLOOD_VOLUME_NORMAL of 672) DO NOT GO ABOVE 3.55 Well, actually you can but, then they can't get enough blood.
|
||||
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
|
||||
|
||||
|
||||
@@ -102,31 +102,6 @@
|
||||
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
|
||||
makeTrail(newloc, T, old_direction)
|
||||
|
||||
if(causes_dirt_buildup_on_floor && (movement_type & GROUND))
|
||||
dirt_buildup()
|
||||
|
||||
/**
|
||||
* Attempts to make the floor dirty.
|
||||
*/
|
||||
/mob/living/proc/dirt_buildup(strength = 1)
|
||||
var/turf/open/T = loc
|
||||
if(!istype(T) || !T.dirt_buildup_allowed)
|
||||
return
|
||||
var/area/A = T.loc
|
||||
if(!A.dirt_buildup_allowed)
|
||||
return
|
||||
var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
|
||||
strength *= multiplier
|
||||
var/obj/effect/decal/cleanable/dirt/D = locate() in T
|
||||
if(D)
|
||||
D.dirty(strength)
|
||||
else
|
||||
T.dirtyness += strength
|
||||
if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
|
||||
D = new /obj/effect/decal/cleanable/dirt(T)
|
||||
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
|
||||
T.dirtyness = 0 // reset.
|
||||
|
||||
/mob/living/Move_Pulled(atom/A)
|
||||
. = ..()
|
||||
if(!. || !isliving(A))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_SPRINT_LOCKED), .proc/update_sprint_lock)
|
||||
|
||||
/mob/living/proc/update_sprint_icon()
|
||||
var/obj/screen/sprintbutton/S = locate() in hud_used?.static_inventory
|
||||
var/atom/movable/screen/sprintbutton/S = locate() in hud_used?.static_inventory
|
||||
S?.update_icon()
|
||||
|
||||
/mob/living/proc/update_hud_sprint_bar()
|
||||
|
||||
@@ -267,16 +267,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
eavesdrop_range = EAVESDROP_EXTRA_RANGE
|
||||
var/list/listening = get_hearers_in_view(message_range+eavesdrop_range, source)
|
||||
var/list/the_dead = list()
|
||||
var/list/yellareas //CIT CHANGE - adds the ability for yelling to penetrate walls and echo throughout areas
|
||||
if(!eavesdrop_range && say_test(message) == "2") //CIT CHANGE - ditto
|
||||
yellareas = get_areas_in_range(message_range*0.5, source) //CIT CHANGE - ditto
|
||||
|
||||
for(var/_M in GLOB.player_list)
|
||||
var/mob/M = _M
|
||||
if(M.stat != DEAD) //not dead, not important
|
||||
if(yellareas) //CIT CHANGE - see above. makes yelling penetrate walls
|
||||
var/area/A = get_area(M) //CIT CHANGE - ditto
|
||||
if(istype(A) && A.ambientsounds != SPACE && (A in yellareas)) //CIT CHANGE - ditto
|
||||
listening |= M //CIT CHANGE - ditto
|
||||
continue
|
||||
if(!M.client || !client) //client is so that ghosts don't have to listen to mice
|
||||
continue
|
||||
@@ -303,6 +297,9 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
AM.Hear(rendered, src, message_language, message, null, spans, message_mode, source)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
|
||||
|
||||
if(!eavesdrop_range && say_test(message) == "2") // Yell hook
|
||||
process_yelling(listening, rendered, src, message_language, message, spans, message_mode, source)
|
||||
|
||||
//speech bubble
|
||||
var/list/speech_bubble_recipients = list()
|
||||
for(var/mob/M in listening)
|
||||
@@ -312,6 +309,30 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30)
|
||||
|
||||
/atom/movable/proc/process_yelling(list/already_heard, rendered, atom/movable/speaker, datum/language/message_language, message, list/spans, message_mode, obj/source)
|
||||
if(last_yell > (world.time - 10))
|
||||
to_chat(src, "<span class='warning'>Your voice doesn't project as far as you try to yell in such quick succession.") // yeah no, no spamming an expensive floodfill.
|
||||
return
|
||||
last_yell = world.time
|
||||
var/list/overhearing = list()
|
||||
var/list/overhearing_text = list()
|
||||
overhearing = yelling_wavefill(src, yell_power)
|
||||
if(!overhearing.len)
|
||||
overhearing_text = "none"
|
||||
else
|
||||
for(var/mob/M as anything in overhearing)
|
||||
overhearing_text += key_name(M)
|
||||
overhearing_text = english_list(overhearing_text)
|
||||
log_say("YELL: [ismob(src)? key_name(src) : src] yelled [message] with overhearing mobs [overhearing_text]")
|
||||
// overhearing = get_hearers_in_view(35, src) | get_hearers_in_range(5, src)
|
||||
overhearing -= already_heard
|
||||
if(!overhearing.len)
|
||||
return
|
||||
// to_chat(world, "DEBUG: overhearing [english_list(overhearing)]")
|
||||
for(var/_AM in overhearing)
|
||||
var/atom/movable/AM = _AM
|
||||
AM.Hear(rendered, speaker, message_language, message, null, spans, message_mode, source)
|
||||
|
||||
/mob/proc/binarycheck()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
|
||||
var/multicam_on = FALSE
|
||||
var/obj/screen/movable/pic_in_pic/ai/master_multicam
|
||||
var/atom/movable/screen/movable/pic_in_pic/ai/master_multicam
|
||||
var/list/multicam_screens = list()
|
||||
var/list/all_eyes = list()
|
||||
var/max_multicams = 6
|
||||
@@ -182,6 +182,7 @@
|
||||
. = ..()
|
||||
|
||||
/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C)
|
||||
set waitfor = FALSE
|
||||
if(client && !C)
|
||||
C = client
|
||||
if(!input && !C?.prefs?.preferred_ai_core_display)
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
//Picture in picture
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai
|
||||
/atom/movable/screen/movable/pic_in_pic/ai
|
||||
var/mob/living/silicon/ai/ai
|
||||
var/mutable_appearance/highlighted_background
|
||||
var/highlighted = FALSE
|
||||
var/mob/camera/aiEye/pic_in_pic/aiEye
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/Initialize()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/Initialize()
|
||||
. = ..()
|
||||
aiEye = new /mob/camera/aiEye/pic_in_pic()
|
||||
aiEye.screen = src
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/Destroy()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/Destroy()
|
||||
set_ai(null)
|
||||
QDEL_NULL(aiEye)
|
||||
return ..()
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/Click()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/Click()
|
||||
..()
|
||||
if(ai)
|
||||
ai.select_main_multicam_window(src)
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/make_backgrounds()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/make_backgrounds()
|
||||
..()
|
||||
highlighted_background = new /mutable_appearance()
|
||||
highlighted_background.icon = 'icons/misc/pic_in_pic.dmi'
|
||||
highlighted_background.icon_state = "background_highlight"
|
||||
highlighted_background.layer = SPACE_LAYER
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/add_background()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/add_background()
|
||||
if((width > 0) && (height > 0))
|
||||
var/matrix/M = matrix()
|
||||
M.Scale(width + 0.5, height + 0.5)
|
||||
@@ -37,35 +37,35 @@
|
||||
standard_background.transform = M
|
||||
add_overlay(highlighted ? highlighted_background : standard_background)
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/set_view_size(width, height, do_refresh = TRUE)
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/set_view_size(width, height, do_refresh = TRUE)
|
||||
aiEye.static_visibility_range = (round(max(width, height) / 2) + 1)
|
||||
if(ai)
|
||||
ai.camera_visibility(aiEye)
|
||||
..()
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/set_view_center(atom/target, do_refresh = TRUE)
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/set_view_center(atom/target, do_refresh = TRUE)
|
||||
..()
|
||||
aiEye.setLoc(get_turf(target))
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/refresh_view()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/refresh_view()
|
||||
..()
|
||||
aiEye.setLoc(get_turf(center))
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/proc/highlight()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/proc/highlight()
|
||||
if(highlighted)
|
||||
return
|
||||
highlighted = TRUE
|
||||
cut_overlay(standard_background)
|
||||
add_overlay(highlighted_background)
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/proc/unhighlight()
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/proc/unhighlight()
|
||||
if(!highlighted)
|
||||
return
|
||||
highlighted = FALSE
|
||||
cut_overlay(highlighted_background)
|
||||
add_overlay(standard_background)
|
||||
|
||||
/obj/screen/movable/pic_in_pic/ai/proc/set_ai(mob/living/silicon/ai/new_ai)
|
||||
/atom/movable/screen/movable/pic_in_pic/ai/proc/set_ai(mob/living/silicon/ai/new_ai)
|
||||
if(ai)
|
||||
ai.multicam_screens -= src
|
||||
ai.all_eyes -= aiEye
|
||||
@@ -120,7 +120,7 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
icon_state = "ai_pip_camera"
|
||||
var/obj/screen/movable/pic_in_pic/ai/screen
|
||||
var/atom/movable/screen/movable/pic_in_pic/ai/screen
|
||||
var/list/cameras_telegraphed = list()
|
||||
var/telegraph_cameras = TRUE
|
||||
var/telegraph_range = 7
|
||||
@@ -204,7 +204,7 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>Cannot place more than [max_multicams] multicamera windows.</span>")
|
||||
return
|
||||
var/obj/screen/movable/pic_in_pic/ai/C = new /obj/screen/movable/pic_in_pic/ai()
|
||||
var/atom/movable/screen/movable/pic_in_pic/ai/C = new /atom/movable/screen/movable/pic_in_pic/ai()
|
||||
C.set_view_size(3, 3, FALSE)
|
||||
C.set_view_center(get_turf(eyeobj))
|
||||
C.set_ai(src)
|
||||
@@ -235,7 +235,7 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
|
||||
reset_perspective(GLOB.ai_camera_room_landmark)
|
||||
if(client)
|
||||
for(var/V in multicam_screens)
|
||||
var/obj/screen/movable/pic_in_pic/P = V
|
||||
var/atom/movable/screen/movable/pic_in_pic/P = V
|
||||
P.show_to(client)
|
||||
|
||||
/mob/living/silicon/ai/proc/end_multicam()
|
||||
@@ -245,13 +245,13 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
|
||||
select_main_multicam_window(null)
|
||||
if(client)
|
||||
for(var/V in multicam_screens)
|
||||
var/obj/screen/movable/pic_in_pic/P = V
|
||||
var/atom/movable/screen/movable/pic_in_pic/P = V
|
||||
P.unshow_to(client)
|
||||
reset_perspective()
|
||||
to_chat(src, "<span class='notice'>Multiple-camera viewing mode deactivated.</span>")
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/select_main_multicam_window(obj/screen/movable/pic_in_pic/ai/P)
|
||||
/mob/living/silicon/ai/proc/select_main_multicam_window(atom/movable/screen/movable/pic_in_pic/ai/P)
|
||||
if(master_multicam == P)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts
|
||||
. = ..()
|
||||
if(laws && isobserver(user))
|
||||
. += "<b>[src] has the following laws:</b>"
|
||||
for(var/law in laws.get_law_list(include_zeroth = TRUE))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
make_laws()
|
||||
|
||||
/mob/living/silicon/proc/post_lawchange(announce = TRUE)
|
||||
throw_alert("newlaw", /obj/screen/alert/newlaw)
|
||||
throw_alert("newlaw", /atom/movable/screen/alert/newlaw)
|
||||
if(announce && last_lawchange_announce != world.time)
|
||||
to_chat(src, "<b>Your laws have been changed.</b>")
|
||||
addtimer(CALLBACK(src, .proc/show_laws), 0)
|
||||
|
||||
@@ -575,7 +575,7 @@
|
||||
for(var/id in environment.get_gases())
|
||||
var/gas_level = environment.get_moles(id)/total_moles
|
||||
if(gas_level > 0.01)
|
||||
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>"
|
||||
dat += "[GLOB.gas_data.names[id]]: [round(gas_level*100)]%<br>"
|
||||
dat += "Temperature: [round(environment.return_temperature()-T0C)]°C<br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
|
||||
dat += "<br>"
|
||||
|
||||
@@ -58,15 +58,15 @@
|
||||
if(0.75 to INFINITY)
|
||||
clear_alert("charge")
|
||||
if(0.5 to 0.75)
|
||||
throw_alert("charge", /obj/screen/alert/lowcell, 1)
|
||||
throw_alert("charge", /atom/movable/screen/alert/lowcell, 1)
|
||||
if(0.25 to 0.5)
|
||||
throw_alert("charge", /obj/screen/alert/lowcell, 2)
|
||||
throw_alert("charge", /atom/movable/screen/alert/lowcell, 2)
|
||||
if(0.01 to 0.25)
|
||||
throw_alert("charge", /obj/screen/alert/lowcell, 3)
|
||||
throw_alert("charge", /atom/movable/screen/alert/lowcell, 3)
|
||||
else
|
||||
throw_alert("charge", /obj/screen/alert/emptycell)
|
||||
throw_alert("charge", /atom/movable/screen/alert/emptycell)
|
||||
else
|
||||
throw_alert("charge", /obj/screen/alert/nocell)
|
||||
throw_alert("charge", /atom/movable/screen/alert/nocell)
|
||||
|
||||
//Robots on fire
|
||||
/mob/living/silicon/robot/handle_fire()
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer ABOVE_HUD_LAYER, UI should be just below it.
|
||||
robot_modules_background.plane = HUD_PLANE
|
||||
|
||||
inv1 = new /obj/screen/robot/module1()
|
||||
inv2 = new /obj/screen/robot/module2()
|
||||
inv3 = new /obj/screen/robot/module3()
|
||||
inv1 = new /atom/movable/screen/robot/module1()
|
||||
inv2 = new /atom/movable/screen/robot/module2()
|
||||
inv3 = new /atom/movable/screen/robot/module3()
|
||||
|
||||
previous_health = health
|
||||
|
||||
@@ -598,7 +598,7 @@
|
||||
if(wires.is_cut(WIRE_LOCKDOWN))
|
||||
state = TRUE
|
||||
if(state)
|
||||
throw_alert("locked", /obj/screen/alert/locked)
|
||||
throw_alert("locked", /atom/movable/screen/alert/locked)
|
||||
else
|
||||
clear_alert("locked")
|
||||
locked_down = state
|
||||
@@ -611,7 +611,7 @@
|
||||
module.rebuild_modules()
|
||||
update_icons()
|
||||
if(emagged)
|
||||
throw_alert("hacked", /obj/screen/alert/hacked)
|
||||
throw_alert("hacked", /atom/movable/screen/alert/hacked)
|
||||
else
|
||||
clear_alert("hacked")
|
||||
|
||||
@@ -992,7 +992,8 @@
|
||||
|
||||
upgrades.Cut()
|
||||
|
||||
speed = 0
|
||||
vtec = 0
|
||||
vtec_disabled = FALSE
|
||||
ionpulse = FALSE
|
||||
revert_shell()
|
||||
|
||||
|
||||
@@ -82,6 +82,18 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
|
||||
if(!opened)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/disarm_shove(mob/living/carbon/human/H)
|
||||
visible_message(span_danger("[src]'s motors grind as they are shoved by [H]!"))
|
||||
vtec_disable(10 SECONDS)
|
||||
|
||||
/mob/living/silicon/robot/proc/vtec_disable(time)
|
||||
var/datum/status_effect/vtec_disabled/V = has_status_effect(/datum/status_effect/vtec_disabled)
|
||||
if(V)
|
||||
V.duration = max(V.duration, world.time + time)
|
||||
else
|
||||
apply_status_effect(/datum/status_effect/vtec_disabled, time)
|
||||
update_movespeed()
|
||||
|
||||
/mob/living/silicon/robot/fire_act()
|
||||
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
|
||||
IgniteMob()
|
||||
|
||||
@@ -26,15 +26,15 @@
|
||||
var/previous_health
|
||||
//Hud stuff
|
||||
|
||||
var/obj/screen/inv1 = null
|
||||
var/obj/screen/inv2 = null
|
||||
var/obj/screen/inv3 = null
|
||||
var/obj/screen/lamp_button = null
|
||||
var/obj/screen/thruster_button = null
|
||||
var/obj/screen/hands = null
|
||||
var/atom/movable/screen/inv1 = null
|
||||
var/atom/movable/screen/inv2 = null
|
||||
var/atom/movable/screen/inv3 = null
|
||||
var/atom/movable/screen/lamp_button = null
|
||||
var/atom/movable/screen/thruster_button = null
|
||||
var/atom/movable/screen/hands = null
|
||||
|
||||
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
|
||||
var/obj/screen/robot_modules_background
|
||||
var/atom/movable/screen/robot_modules_background
|
||||
|
||||
//3 Modules can be activated at any one time.
|
||||
var/obj/item/robot_module/module = null
|
||||
@@ -61,7 +61,9 @@
|
||||
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
|
||||
|
||||
var/speed = 0 // VTEC speed boost.
|
||||
var/vtec = 0 // VTEC speed boost.
|
||||
/// vtec shorted out
|
||||
var/vtec_disabled = FALSE
|
||||
var/magpulse = FALSE // Magboot-like effect.
|
||||
var/ionpulse = FALSE // Jetpack-like effect.
|
||||
var/ionpulse_on = FALSE // Jetpack-like effect.
|
||||
@@ -88,14 +90,14 @@
|
||||
///Lamp brightness. Starts at 3, but can be 1 - 5.
|
||||
var/lamp_intensity = 3
|
||||
///Lamp button reference
|
||||
var/obj/screen/robot/lamp/lampButton
|
||||
var/atom/movable/screen/robot/lamp/lampButton
|
||||
|
||||
var/sight_mode = 0
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
|
||||
|
||||
///The reference to the built-in tablet that borgs carry.
|
||||
var/obj/item/modular_computer/tablet/integrated/modularInterface
|
||||
var/obj/screen/robot/modPC/interfaceButton
|
||||
var/atom/movable/screen/robot/modPC/interfaceButton
|
||||
|
||||
var/list/upgrades = list()
|
||||
|
||||
|
||||
@@ -23,4 +23,4 @@
|
||||
. = ..()
|
||||
if(!resting && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
. += 1
|
||||
. += speed
|
||||
. += vtec_disabled? 0 : vtec
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
M.visible_message("[M] pets [src].", \
|
||||
"<span class='notice'>You pet [src].</span>", target = src,
|
||||
target_message = "[M] pets you.")
|
||||
if(INTENT_DISARM)
|
||||
disarm_shove(M)
|
||||
if(INTENT_GRAB)
|
||||
grabbedby(M)
|
||||
else
|
||||
@@ -88,6 +90,9 @@
|
||||
"<span class='warning'>[M] punches you, but doesn't leave a dent.</span>", null, COMBAT_MESSAGE_RANGE, null, M,
|
||||
"<span class='danger'>You punch [src], but don't leave a dent.</span>")
|
||||
|
||||
/mob/living/silicon/proc/disarm_shove(mob/living/carbon/human/H)
|
||||
visible_message(span_danger("[H] shoves [src], but doesn't manage to make much of an effect."))
|
||||
|
||||
/mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M)
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
return
|
||||
@@ -139,6 +144,6 @@
|
||||
P.on_hit(src, 0, def_zone)
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/static)
|
||||
/mob/living/silicon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash/static)
|
||||
if(affect_silicon)
|
||||
return ..()
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/mob/living/simple_animal/bot/secbot/grievous/Initialize()
|
||||
. = ..()
|
||||
weapon = new baton_type(src)
|
||||
weapon.attack_self(src)
|
||||
INVOKE_ASYNC(weapon, /obj/item.proc/attack_self, src)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/grievous/Destroy()
|
||||
QDEL_NULL(weapon)
|
||||
|
||||
@@ -753,6 +753,12 @@
|
||||
else
|
||||
return null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/remove_air_ratio(ratio)
|
||||
if(loc)
|
||||
return loc.remove_air_ratio(ratio)
|
||||
else
|
||||
return null
|
||||
|
||||
/mob/living/simple_animal/bot/mulebot/do_resist()
|
||||
. = ..()
|
||||
if(load)
|
||||
|
||||
@@ -381,6 +381,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory()
|
||||
set waitfor = FALSE
|
||||
if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new
|
||||
var/savefile/S = new /savefile("data/npc_saves/Ian.sav")
|
||||
S["age"] >> age
|
||||
|
||||
@@ -55,7 +55,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
var/cooldown = 0
|
||||
var/mob/living/carbon/summoner
|
||||
var/range = 13 //how far from the user the spirit can be
|
||||
var/toggle_button_type = /obj/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses
|
||||
var/toggle_button_type = /atom/movable/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses
|
||||
var/playstyle_string = "<span class='holoparasite bold'>You are a standard Guardian. You shouldn't exist!</span>"
|
||||
var/magic_fluff_string = "<span class='holoparasite'>You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!</span>"
|
||||
var/tech_fluff_string = "<span class='holoparasite'>BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!</span>"
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Assassin modules loaded. Holoparasite swarm online.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's an assassin carp! Just when you thought it was safe to go back to the water... which is unhelpful, because we're in space.</span>"
|
||||
|
||||
toggle_button_type = /obj/screen/guardian/ToggleMode/Assassin
|
||||
toggle_button_type = /atom/movable/screen/guardian/ToggleMode/Assassin
|
||||
var/toggle = FALSE
|
||||
var/stealthcooldown = 100
|
||||
var/obj/screen/alert/canstealthalert
|
||||
var/obj/screen/alert/instealthalert
|
||||
var/atom/movable/screen/alert/canstealthalert
|
||||
var/atom/movable/screen/alert/instealthalert
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/assassin/Initialize()
|
||||
. = ..()
|
||||
@@ -86,12 +86,12 @@
|
||||
if(stealthcooldown <= world.time)
|
||||
if(toggle)
|
||||
if(!instealthalert)
|
||||
instealthalert = throw_alert("instealth", /obj/screen/alert/instealth)
|
||||
instealthalert = throw_alert("instealth", /atom/movable/screen/alert/instealth)
|
||||
clear_alert("canstealth")
|
||||
canstealthalert = null
|
||||
else
|
||||
if(!canstealthalert)
|
||||
canstealthalert = throw_alert("canstealth", /obj/screen/alert/canstealth)
|
||||
canstealthalert = throw_alert("canstealth", /atom/movable/screen/alert/canstealth)
|
||||
clear_alert("instealth")
|
||||
instealthalert = null
|
||||
else
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Charge modules loaded. Holoparasite swarm online.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one! It's a charger carp, that likes running at people. But it doesn't have any legs...</span>"
|
||||
var/charging = 0
|
||||
var/obj/screen/alert/chargealert
|
||||
var/atom/movable/screen/alert/chargealert
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/charger/BiologicalLife(seconds, times_fired)
|
||||
if(!(. = ..()))
|
||||
return
|
||||
if(ranged_cooldown <= world.time)
|
||||
if(!chargealert)
|
||||
chargealert = throw_alert("charge", /obj/screen/alert/cancharge)
|
||||
chargealert = throw_alert("charge", /atom/movable/screen/alert/cancharge)
|
||||
else
|
||||
clear_alert("charge")
|
||||
chargealert = null
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
magic_fluff_string = "<span class='holoparasite'>..And draw the Guardian, a stalwart protector that never leaves the side of its charge.</span>"
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Protector modules loaded. Holoparasite swarm online.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught one! Wait, no... it caught you! The fisher has become the fishy.</span>"
|
||||
toggle_button_type = /obj/screen/guardian/ToggleMode
|
||||
toggle_button_type = /atom/movable/screen/guardian/ToggleMode
|
||||
var/toggle = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/protector/ex_act(severity)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! Caught one, it's a ranged carp. This fishy can watch people pee in the ocean.</span>"
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
see_in_dark = 8
|
||||
toggle_button_type = /obj/screen/guardian/ToggleMode
|
||||
toggle_button_type = /atom/movable/screen/guardian/ToggleMode
|
||||
var/list/snares = list()
|
||||
var/toggle = FALSE
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
magic_fluff_string = "<span class='holoparasite'>..And draw the CMO, a potent force of life... and death.</span>"
|
||||
carp_fluff_string = "<span class='holoparasite'>CARP CARP CARP! You caught a support carp. It's a kleptocarp!</span>"
|
||||
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Support modules active. Holoparasite swarm online.</span>"
|
||||
toggle_button_type = /obj/screen/guardian/ToggleMode
|
||||
toggle_button_type = /atom/movable/screen/guardian/ToggleMode
|
||||
var/obj/structure/receiving_pad/beacon
|
||||
var/beacon_cooldown = 0
|
||||
var/toggle = FALSE
|
||||
|
||||
@@ -133,6 +133,10 @@
|
||||
chance_to_hold_onto_points = highest_cost*0.5
|
||||
if(points != max_points && prob(chance_to_hold_onto_points))
|
||||
return //Let's save our points for a better ability (unless we're at max points, in which case we can't save anymore!)
|
||||
do_ability()
|
||||
|
||||
/datum/boss_active_timed_battle/proc/do_ability()
|
||||
set waitfor = FALSE
|
||||
if(!boss.client)
|
||||
abilities = shuffle(abilities)
|
||||
for(var/ab in abilities)
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
L.SetUnconscious(0, FALSE)
|
||||
L.adjustOxyLoss(-50)// do CPR first
|
||||
if(L.blood_volume <= 500) //bandage them up and give em some blood if they're bleeding
|
||||
L.blood_volume += 30
|
||||
L.adjust_integration_blood(30)
|
||||
L.bleedsuppress = 0
|
||||
if(L.getBruteLoss() >= 50)// first, did we beat them into crit? if so, heal that
|
||||
var/healing = min(L.getBruteLoss(), 120)
|
||||
|
||||
@@ -364,11 +364,10 @@
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
SEND_SIGNAL(src, COMSIG_HOSTILE_ATTACKINGTARGET, target)
|
||||
in_melee = TRUE
|
||||
/* sorry for the simplemob vore fans
|
||||
if(vore_active)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!client && L.Adjacent(src) && CHECK_BITFIELD(L.vore_flags,DEVOURABLE)) // aggressive check to ensure vore attacks can be made
|
||||
if(!client && L.Adjacent(src) && CHECK_BITFIELD(L.vore_flags, DEVOURABLE) && CHECK_BITFIELD(L.vore_flags, MOBVORE)) // aggressive check to ensure vore attacks can be made
|
||||
if(prob(voracious_chance))
|
||||
vore_attack(src,L,src)
|
||||
else
|
||||
@@ -379,7 +378,6 @@
|
||||
return target.attack_animal(src)
|
||||
else
|
||||
return target.attack_animal(src)
|
||||
*/
|
||||
return target.attack_animal(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Aggro()
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
status_type = STATUS_EFFECT_MULTIPLE
|
||||
alert_type = null
|
||||
tick_interval = 1
|
||||
var/obj/screen/seedling/seedling_screen_object
|
||||
var/atom/movable/screen/seedling/seedling_screen_object
|
||||
var/atom/target
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
/datum/status_effect/seedling_beam_indicator/on_apply()
|
||||
if(owner.client)
|
||||
seedling_screen_object = new /obj/screen/seedling()
|
||||
seedling_screen_object = new /atom/movable/screen/seedling()
|
||||
owner.client.screen += seedling_screen_object
|
||||
tick()
|
||||
return ..()
|
||||
@@ -98,7 +98,7 @@
|
||||
final.Turn(target_angle)
|
||||
seedling_screen_object.transform = final
|
||||
|
||||
/obj/screen/seedling
|
||||
/atom/movable/screen/seedling
|
||||
icon = 'icons/mob/jungle/arachnid.dmi'
|
||||
icon_state = "seedling_beam_indicator"
|
||||
screen_loc = "CENTER:-16,CENTER:-16"
|
||||
|
||||
@@ -40,8 +40,10 @@ Difficulty: Medium
|
||||
ranged = 1
|
||||
ranged_cooldown_time = 16
|
||||
pixel_x = -16
|
||||
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye)
|
||||
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka)
|
||||
crusher_loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka, /obj/item/crusher_trophy/miner_eye, /obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
|
||||
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
|
||||
loot = list(/obj/item/melee/transforming/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator/premiumka,/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
|
||||
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
|
||||
@@ -26,8 +26,10 @@ Difficulty: Extremely Hard
|
||||
speed = 20
|
||||
move_to_delay = 20
|
||||
ranged = TRUE
|
||||
crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman)
|
||||
loot = list(/obj/effect/decal/remains/plasma)
|
||||
crusher_loot = list(/obj/effect/decal/remains/plasma, /obj/item/crusher_trophy/ice_block_talisman, ,/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
|
||||
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
|
||||
loot = list(/obj/effect/decal/remains/plasma, ,/obj/item/disk/design_disk/modkit_disc/mob_and_turf_aoe,
|
||||
/obj/item/disk/design_disk/modkit_disc/bounty,/obj/item/disk/design_disk/modkit_disc/resonator_blast,/obj/item/disk/design_disk/modkit_disc/rapid_repeater)
|
||||
wander = FALSE
|
||||
del_on_death = TRUE
|
||||
blood_volume = BLOOD_VOLUME_NORMAL
|
||||
@@ -337,11 +339,11 @@ Difficulty: Extremely Hard
|
||||
id = "ice_block_talisman"
|
||||
duration = 25
|
||||
status_type = STATUS_EFFECT_REFRESH
|
||||
alert_type = /obj/screen/alert/status_effect/ice_block_talisman
|
||||
alert_type = /atom/movable/screen/alert/status_effect/ice_block_talisman
|
||||
/// Stored icon overlay for the hit mob, removed when effect is removed
|
||||
var/icon/cube
|
||||
|
||||
/obj/screen/alert/status_effect/ice_block_talisman
|
||||
/atom/movable/screen/alert/status_effect/ice_block_talisman
|
||||
name = "Frozen Solid"
|
||||
desc = "You're frozen inside an ice cube, and cannot move!"
|
||||
icon_state = "frozen"
|
||||
|
||||
@@ -102,23 +102,13 @@
|
||||
consume_bait()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait()
|
||||
var/list/L = list()
|
||||
for(var/obj/O in view(src, 9))
|
||||
L += O
|
||||
var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in L
|
||||
if(diamonds)
|
||||
var/distanced = 0
|
||||
distanced = get_dist(loc,diamonds.loc)
|
||||
if(distanced <= 1 && diamonds)
|
||||
qdel(diamonds)
|
||||
src.visible_message("<span class='notice'>[src] consumes [diamonds], and it disappears! ...At least, you think.</span>")
|
||||
var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in L
|
||||
if(bait)
|
||||
var/distanceb = 0
|
||||
distanceb = get_dist(loc,bait.loc)
|
||||
if(distanceb <= 1 && bait)
|
||||
qdel(bait)
|
||||
visible_message("<span class='notice'>[src] examines [bait] closer, and telekinetically shatters the pen.</span>")
|
||||
for(var/obj/O in view(1, src))
|
||||
if(istype(O, /obj/item/stack/ore/diamond))
|
||||
qdel(O)
|
||||
src.visible_message("<span class='notice'>[src] consumes [O], and it disappears! ...At least, you think.</span>")
|
||||
else if(istype(O, /obj/item/pen/survival))
|
||||
qdel(O)
|
||||
src.visible_message("<span class='notice'>[src] examines [O] closer, and telekinetically shatters the pen.</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -113,7 +113,7 @@ While using this makes the system rely on OnFire, it still gives options for tim
|
||||
severity = 7
|
||||
hud_used.healths.icon_state = "elite_health[severity]"
|
||||
if(severity > 0)
|
||||
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
|
||||
overlay_fullscreen("brute", /atom/movable/screen/fullscreen/brute, severity)
|
||||
else
|
||||
clear_fullscreen("brute")
|
||||
|
||||
|
||||
@@ -35,14 +35,16 @@
|
||||
coffer.Grant(src)
|
||||
riot = new /datum/action/cooldown/riot
|
||||
riot.Grant(src)
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
INVOKE_ASYNC(src, .proc/poll_for_player)
|
||||
|
||||
/mob/living/simple_animal/hostile/regalrat/proc/poll_for_player()
|
||||
var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the Royal Rat, cheesey be his crown?", ROLE_SENTIENCE, null, FALSE, 100, POLL_IGNORE_SENTIENCE_POTION)
|
||||
if(LAZYLEN(candidates) && !mind)
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
key = C.key
|
||||
notify_ghosts("All rise for the rat king, ascendant to the throne in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE)
|
||||
|
||||
AddElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS)
|
||||
|
||||
/mob/living/simple_animal/hostile/regalrat/handle_automated_action()
|
||||
if(prob(20))
|
||||
riot.Trigger()
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
/mob/living/simple_animal/hostile/retaliate/clown/handle_temperature_damage()
|
||||
if(bodytemperature < minbodytemp)
|
||||
adjustBruteLoss(10)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
throw_alert("temp", /atom/movable/screen/alert/cold, 2)
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
adjustBruteLoss(15)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
throw_alert("temp", /atom/movable/screen/alert/hot, 3)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
|
||||
@@ -50,12 +50,12 @@
|
||||
if(isopenturf(loc))
|
||||
var/turf/open/T = src.loc
|
||||
if(T.air)
|
||||
var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
|
||||
var/co2 = T.air.get_moles(GAS_CO2)
|
||||
if(co2 > 0)
|
||||
if(prob(25))
|
||||
var/amt = min(co2, 9)
|
||||
T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
|
||||
T.atmos_spawn_air("o2=[amt]")
|
||||
T.air.adjust_moles(GAS_CO2, -amt)
|
||||
T.atmos_spawn_air("o2=[amt];TEMP=293.15")
|
||||
|
||||
/mob/living/simple_animal/hostile/tree/AttackingTarget()
|
||||
. = ..()
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
setup_visuals()
|
||||
|
||||
/mob/living/simple_animal/hostile/zombie/proc/setup_visuals()
|
||||
set waitfor = FALSE
|
||||
var/datum/preferences/dummy_prefs = new
|
||||
dummy_prefs.pref_species = new /datum/species/zombie
|
||||
dummy_prefs.be_random_body = TRUE
|
||||
|
||||
@@ -264,10 +264,10 @@
|
||||
var/turf/open/ST = src.loc
|
||||
if(ST.air)
|
||||
|
||||
var/tox = ST.air.get_moles(/datum/gas/plasma)
|
||||
var/oxy = ST.air.get_moles(/datum/gas/oxygen)
|
||||
var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
|
||||
var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
|
||||
var/tox = ST.air.get_moles(GAS_PLASMA)
|
||||
var/oxy = ST.air.get_moles(GAS_O2)
|
||||
var/n2 = ST.air.get_moles(GAS_N2)
|
||||
var/co2 = ST.air.get_moles(GAS_CO2)
|
||||
|
||||
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
|
||||
. = FALSE
|
||||
@@ -554,7 +554,7 @@
|
||||
var/oindex = active_hand_index
|
||||
active_hand_index = hand_index
|
||||
if(hud_used)
|
||||
var/obj/screen/inventory/hand/H
|
||||
var/atom/movable/screen/inventory/hand/H
|
||||
H = hud_used.hand_slots["[hand_index]"]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
Tempstun = 0
|
||||
|
||||
if(stat != DEAD)
|
||||
var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
|
||||
var/bz_percentage = environment.total_moles() ? (environment.get_moles(GAS_BZ) / environment.total_moles()) : 0
|
||||
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
|
||||
|
||||
if(stat == CONSCIOUS && stasis)
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/slime/proc/update_name()
|
||||
/mob/living/simple_animal/slime/update_name()
|
||||
if(slime_name_regex.Find(name))
|
||||
number = rand(1, 1000)
|
||||
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
|
||||
|
||||
@@ -35,11 +35,10 @@
|
||||
return
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/out_of_combat_timer, out_of_combat_timer)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/base_regeneration, base_regeneration)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/combat_regeneration, combat_regeneration)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/percent_regeneration_out_of_combat, percent_regeneration_out_of_combat)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/post_action_penalty_delay, post_action_penalty_delay)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/post_action_penalty_factor, post_action_penalty_factor)
|
||||
var/base_regen = (SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))? base_regeneration : combat_regeneration
|
||||
var/base_regen = base_regeneration
|
||||
var/time_since_last_action = world.time - stamina_buffer_last_use
|
||||
var/action_penalty = ((time_since_last_action) < (post_action_penalty_delay * 10))? post_action_penalty_factor : 1
|
||||
var/out_of_combat_bonus = (time_since_last_action < (out_of_combat_timer * 10))? 0 : ((buffer_max * percent_regeneration_out_of_combat * 0.01))
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
// ignore_castun = same logic as Paralyze() in general
|
||||
// override_duration = If this is set, does Paralyze() for this duration.
|
||||
// override_stam = If this is set, does this amount of stamina damage.
|
||||
/mob/living/proc/DefaultCombatKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg)
|
||||
// knocktofloor - whether to knock them to the ground
|
||||
/mob/living/proc/DefaultCombatKnockdown(amount, updating = TRUE, ignore_canknockdown = FALSE, override_hardstun, override_stamdmg, knocktofloor = TRUE)
|
||||
if(!iscarbon(src))
|
||||
return Paralyze(amount, updating, ignore_canknockdown)
|
||||
if(!ignore_canknockdown && !(status_flags & CANKNOCKDOWN))
|
||||
@@ -13,7 +14,8 @@
|
||||
buckled.unbuckle_mob(src)
|
||||
var/drop_items = amount > 80 //80 is cutoff for old item dropping behavior
|
||||
var/stamdmg = isnull(override_stamdmg)? (amount * 0.25) : override_stamdmg
|
||||
KnockToFloor(drop_items, TRUE, updating)
|
||||
if(knocktofloor)
|
||||
KnockToFloor(drop_items, TRUE, updating)
|
||||
adjustStaminaLoss(stamdmg)
|
||||
if(!isnull(override_hardstun))
|
||||
Paralyze(override_hardstun)
|
||||
@@ -597,7 +599,7 @@
|
||||
|
||||
/mob/living/proc/become_nearsighted(source)
|
||||
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
|
||||
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
|
||||
overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1)
|
||||
ADD_TRAIT(src, TRAIT_NEARSIGHT, source)
|
||||
|
||||
/mob/living/proc/cure_husk(source)
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
t += "<span class='danger'>Temperature: [environment.return_temperature()] \n</span>"
|
||||
for(var/id in environment.get_gases())
|
||||
if(environment.get_moles(id))
|
||||
t+="<span class='notice'>[GLOB.meta_gas_names[id]]: [environment.get_moles(id)] \n</span>"
|
||||
t+="<span class='notice'>[GLOB.gas_data.names[id]]: [environment.get_moles(id)] \n</span>"
|
||||
|
||||
to_chat(usr, t)
|
||||
|
||||
@@ -884,7 +884,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
|
||||
/mob/proc/sync_lighting_plane_alpha()
|
||||
if(hud_used)
|
||||
var/obj/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
|
||||
var/atom/movable/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
|
||||
if (L)
|
||||
L.alpha = lighting_alpha
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
var/registered_z
|
||||
|
||||
var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
|
||||
var/list/alerts = list() // contains /atom/movable/screen/alert only // On /mob so clientless mobs will throw alerts properly
|
||||
var/list/screens = list()
|
||||
var/list/client_colours = list()
|
||||
var/hud_type = /datum/hud
|
||||
|
||||
@@ -362,7 +362,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
if(flashwindow)
|
||||
window_flash(O.client)
|
||||
if(source)
|
||||
var/obj/screen/alert/notify_action/A = O.throw_alert("[REF(source)]_notify_action", /obj/screen/alert/notify_action)
|
||||
var/atom/movable/screen/alert/notify_action/A = O.throw_alert("[REF(source)]_notify_action", /atom/movable/screen/alert/notify_action)
|
||||
if(A)
|
||||
if(O.client.prefs && O.client.prefs.UI_style)
|
||||
A.icon = ui_style2icon(O.client.prefs.UI_style)
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
. = ..()
|
||||
|
||||
if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully
|
||||
add_delay *= 2
|
||||
add_delay *= SQRT_2
|
||||
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay), FALSE)
|
||||
move_delay += add_delay
|
||||
if(.) // If mob is null here, we deserve the runtime
|
||||
@@ -267,7 +267,7 @@
|
||||
//1: r-leg 2: groin 3: l-leg
|
||||
|
||||
/client/proc/check_has_body_select()
|
||||
return mob && mob.hud_used && mob.hud_used.zone_select && istype(mob.hud_used.zone_select, /obj/screen/zone_sel)
|
||||
return mob && mob.hud_used && mob.hud_used.zone_select && istype(mob.hud_used.zone_select, /atom/movable/screen/zone_sel)
|
||||
|
||||
/client/verb/body_toggle_head()
|
||||
set name = "body-toggle-head"
|
||||
@@ -285,7 +285,7 @@
|
||||
else
|
||||
next_in_line = BODY_ZONE_HEAD
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(next_in_line, mob)
|
||||
|
||||
/client/verb/body_r_arm()
|
||||
@@ -295,7 +295,7 @@
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_R_ARM, mob)
|
||||
|
||||
/client/verb/body_chest()
|
||||
@@ -305,7 +305,7 @@
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_CHEST, mob)
|
||||
|
||||
/client/verb/body_l_arm()
|
||||
@@ -315,7 +315,7 @@
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_L_ARM, mob)
|
||||
|
||||
/client/verb/body_r_leg()
|
||||
@@ -325,7 +325,7 @@
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_R_LEG, mob)
|
||||
|
||||
/client/verb/body_groin()
|
||||
@@ -335,7 +335,7 @@
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_PRECISE_GROIN, mob)
|
||||
|
||||
/client/verb/body_l_leg()
|
||||
@@ -345,7 +345,7 @@
|
||||
if(!check_has_body_select())
|
||||
return
|
||||
|
||||
var/obj/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
var/atom/movable/screen/zone_sel/selector = mob.hud_used.zone_select
|
||||
selector.set_selected_zone(BODY_ZONE_L_LEG, mob)
|
||||
|
||||
/client/verb/toggle_walk_run()
|
||||
@@ -364,7 +364,7 @@
|
||||
return FALSE
|
||||
m_intent = MOVE_INTENT_RUN
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
|
||||
for(var/atom/movable/screen/mov_intent/selector in hud_used.static_inventory)
|
||||
selector.update_icon()
|
||||
|
||||
/mob/verb/up()
|
||||
|
||||
@@ -144,33 +144,14 @@
|
||||
message = "<span class='emote'><b>[user]</b> <i>[user.say_emphasis(message)]</i></span>"
|
||||
|
||||
var/list/show_to = list()
|
||||
var/list/processing = list()
|
||||
var/safety = 25
|
||||
var/list/processed = list()
|
||||
for(var/obj/structure/table/T in range(user, 1))
|
||||
processing |= T
|
||||
for(var/i = 1; i <= processing.len; ++i)
|
||||
var/obj/structure/table/T = processing[i]
|
||||
if(safety-- <= 0)
|
||||
to_chat(user, "Table scan aborted early, some people might have not received the message (max 25)")
|
||||
break
|
||||
if(get_dist(T, user) > 7)
|
||||
continue // nah
|
||||
processing |= T
|
||||
for(var/mob/living/M in range(T, 1)) // no ghosts/cameramobs
|
||||
show_to |= M
|
||||
var/obj/structure/table/other
|
||||
other = locate() in get_step(T, NORTH)
|
||||
if(other)
|
||||
processing |= other
|
||||
other = locate() in get_step(T, SOUTH)
|
||||
if(other)
|
||||
processing |= other
|
||||
other = locate() in get_step(T, WEST)
|
||||
if(other)
|
||||
processing |= other
|
||||
other = locate() in get_step(T, EAST)
|
||||
if(other)
|
||||
processing |= other
|
||||
if(processed[T])
|
||||
continue
|
||||
for(var/obj/structure/table/T2 in T.connected_floodfill(25))
|
||||
processed[T2] = TRUE
|
||||
for(var/mob/living/L in range(T2, 1))
|
||||
show_to |= L
|
||||
|
||||
for(var/i in show_to)
|
||||
var/mob/M = i
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
/mob/proc/update_blindness()
|
||||
if(eye_blind) // UNCONSCIOUS or has blind trait, or has temporary blindness
|
||||
if(stat == CONSCIOUS || stat == SOFT_CRIT)
|
||||
throw_alert("blind", /obj/screen/alert/blind)
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
throw_alert("blind", /atom/movable/screen/alert/blind)
|
||||
overlay_fullscreen("blind", /atom/movable/screen/fullscreen/blind)
|
||||
// You are blind why should you be able to make out details like color, only shapes near you
|
||||
// add_client_colour(/datum/client_colour/monochrome/blind)
|
||||
else // CONSCIOUS no blind trait, no blindness
|
||||
@@ -91,7 +91,7 @@
|
||||
var/list/screens = list(hud_used.plane_masters["[GAME_PLANE]"], hud_used.plane_masters["[FLOOR_PLANE]"],
|
||||
hud_used.plane_masters["[WALL_PLANE]"], hud_used.plane_masters["[ABOVE_WALL_PLANE]"])
|
||||
for(var/A in screens)
|
||||
var/obj/screen/plane_master/P = A
|
||||
var/atom/movable/screen/plane_master/P = A
|
||||
P.add_filter("blurry_eyes", 2, EYE_BLUR(clamp(eye_blurry*0.1,0.6,3)))
|
||||
|
||||
/mob/proc/remove_eyeblur()
|
||||
@@ -100,7 +100,7 @@
|
||||
var/list/screens = list(hud_used.plane_masters["[GAME_PLANE]"], hud_used.plane_masters["[FLOOR_PLANE]"],
|
||||
hud_used.plane_masters["[WALL_PLANE]"], hud_used.plane_masters["[ABOVE_WALL_PLANE]"])
|
||||
for(var/A in screens)
|
||||
var/obj/screen/plane_master/P = A
|
||||
var/atom/movable/screen/plane_master/P = A
|
||||
P.remove_filter("blurry_eyes")
|
||||
|
||||
///Adjust the drugginess of a mob
|
||||
|
||||
Reference in New Issue
Block a user