Merge remote-tracking branch 'upstream/master' into logging-improvements-V2

This commit is contained in:
joep van der velden
2020-08-08 17:30:09 +02:00
1614 changed files with 92235 additions and 477938 deletions
+5
View File
@@ -14,3 +14,8 @@
/mob/camera/experience_pressure_difference()
return
/mob/camera/forceMove(atom/destination)
var/oldloc = loc
loc = destination
Moved(oldloc, NONE)
+1 -1
View File
@@ -15,7 +15,7 @@
onTransitZ(old_turf?.z, new_turf?.z)
var/oldloc = loc
loc = destination
Moved(oldloc, NONE, TRUE)
Moved(oldloc, NONE)
/mob/dead/onTransitZ(old_z,new_z)
..()
+3 -45
View File
@@ -23,7 +23,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
//If you died in the game and are a ghsot - this will remain as null.
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
universal_speak = TRUE
var/atom/movable/following = null
var/image/ghostimage = null //this mobs ghost image, for deleting and stuff
var/ghostvision = TRUE //is the ghost able to see things humans can't?
var/seedarkness = TRUE
@@ -90,10 +89,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
..()
/mob/dead/observer/Destroy()
if(ismob(following))
var/mob/M = following
M.following_mobs -= src
following = null
if(ghostimage)
GLOB.ghost_images -= ghostimage
QDEL_NULL(ghostimage)
@@ -116,7 +111,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
MA.blend_mode = COPY.blend_mode
MA.color = COPY.color
MA.dir = COPY.dir
MA.gender = COPY.gender
MA.icon = COPY.icon
MA.icon_state = COPY.icon_state
MA.layer = COPY.layer
@@ -130,7 +124,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
if(!isicon(MA.icon) && !LAZYLEN(MA.overlays)) // Gibbing/dusting/melting removes the icon before ghostize()ing the mob, so we need to account for that
MA.icon = initial(icon)
MA.icon_state = initial(icon_state)
MA.suffix = COPY.suffix
MA.underlays = COPY.underlays
. = MA
@@ -143,13 +136,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
Transfer_mind is there to check if mob is being deleted/not going to have a body.
Works together with spawning an observer, noted above.
*/
/mob/dead/observer/Life(seconds, times_fired)
..()
if(!loc) return
if(!client) return 0
/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U)
var/client/C = U.client
for(var/mob/living/carbon/human/target in target_list)
@@ -242,7 +228,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Move(NewLoc, direct)
update_parallax_contents()
following = null
setDir(direct)
ghostimage.setDir(dir)
@@ -424,7 +409,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
forceMove(pick(L))
update_parallax_contents()
following = null
/mob/dead/observer/verb/follow()
set category = "Ghost"
@@ -436,7 +420,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
A.on_close(CALLBACK(src, .proc/ManualFollow))
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
/mob/dead/observer/proc/ManualFollow(atom/movable/target)
if(!target || !isobserver(usr))
return
@@ -444,7 +428,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
if(target != src)
if(following && following == target)
if(orbiting && orbiting == target)
return
var/icon/I = icon(target.icon,target.icon_state,target.dir)
@@ -470,7 +454,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else //Circular
rot_seg = 36 //360/10 bby, smooth enough aproximation of a circle
following = target
to_chat(src, "<span class='notice'>Now following [target]</span>")
orbit(target,orbitsize, FALSE, 20, rot_seg)
@@ -478,28 +461,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
setDir(2)//reset dir so the right directional sprites show up
return ..()
/mob/proc/update_following()
. = get_turf(src)
for(var/mob/dead/observer/M in following_mobs)
if(M.following != src)
following_mobs -= M
else
if(M.loc != .)
M.forceMove(.)
/mob
var/list/following_mobs = list()
/mob/Move()
. = ..()
if(.)
update_following()
/mob/Life(seconds, times_fired)
// to catch teleports etc which directly set loc
update_following()
return ..()
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
set name = "Jump to Mob"
@@ -519,7 +480,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
A.forceMove(T)
M.update_parallax_contents()
following = null
return
to_chat(A, "This mob is not located in the game world.")
@@ -650,7 +610,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/Topic(href, href_list)
if(usr != src)
return
..()
if(href_list["track"])
var/atom/target = locate(href_list["track"])
@@ -664,7 +623,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(href_list["jump"])
var/mob/target = locate(href_list["jump"])
var/mob/A = usr;
var/mob/A = usr
to_chat(A, "Teleporting to [target]...")
//var/mob/living/silicon/ai/A = locate(href_list["track2"]) in GLOB.mob_list
if(target && target != usr)
@@ -677,7 +636,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!client)
return
forceMove(T)
following = null
if(href_list["reenter"])
reenter_corpse()
+1 -1
View File
@@ -135,7 +135,7 @@
if(message)
for(var/mob/M in GLOB.player_list)
if(istype(M, /mob/new_player))
if(isnewplayer(M))
continue
if(check_rights(R_ADMIN|R_MOD, 0, M) && M.get_preference(CHAT_DEAD)) // Show the emote to admins/mods
+1 -1
View File
@@ -90,7 +90,7 @@
if(speaker_name != speaker.real_name && speaker.real_name)
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "([ghost_follow_link(speaker, ghost=src)]) "
if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
if(client.prefs.toggles & CHAT_GHOSTEARS && (speaker in view(src)))
message = "<b>[message]</b>"
if(!can_hear())
-1
View File
@@ -22,7 +22,6 @@
var/atom/movable/mob_container
mob_container = M
mob_container.forceMove(get_turf(src))
M.reset_perspective()
qdel(src)
+2 -2
View File
@@ -214,9 +214,9 @@
if(M.equip_to_appropriate_slot(src))
if(M.hand)
M.update_inv_l_hand(0)
M.update_inv_l_hand()
else
M.update_inv_r_hand(0)
M.update_inv_r_hand()
return 1
if(M.s_active && M.s_active.can_be_inserted(src, 1)) //if storage active insert there
+9 -15
View File
@@ -33,7 +33,7 @@
for(var/i = 0;i<name_count;i++)
new_name = ""
for(var/x = rand(Floor(syllable_count/2),syllable_count);x>0;x--)
for(var/x = rand(FLOOR(syllable_count/2, 1),syllable_count);x>0;x--)
new_name += pick(syllables)
full_name += " [capitalize(lowertext(new_name))]"
@@ -98,7 +98,9 @@
if(!check_can_speak(speaker))
return FALSE
log_say("([name]-HIVE) [message]", speaker)
var/log_message = "([name]-HIVE) [message]"
log_say(log_message, speaker)
speaker.create_log(SAY_LOG, log_message)
if(!speaker_mask)
speaker_mask = speaker.name
@@ -605,7 +607,10 @@
if(!message)
return
log_say("(ROBOT) [message]", speaker)
var/log_message = "(ROBOT) [message]"
log_say(log_message, speaker)
speaker.create_log(SAY_LOG, log_message)
var/message_start = "<i><span class='game say'>[name], <span class='name'>[speaker.name]</span>"
var/message_body = "<span class='message'>[speaker.say_quote(message)],</i><span class='robot'>\"[message]\"</span></span></span>"
@@ -614,7 +619,7 @@
var/message_start_dead = "<i><span class='game say'>[name], <span class='name'>[speaker.name] ([ghost_follow_link(speaker, ghost=M)])</span>"
M.show_message("[message_start_dead] [message_body]", 2)
for(var/mob/living/S in GLOB.living_mob_list)
for(var/mob/living/S in GLOB.alive_mob_list)
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
continue
else if(isAI(S))
@@ -762,17 +767,6 @@
desc = "Bark bark bark."
key = "vu"
/datum/language/zombie
name = "Zombie"
desc = "BRAAAAAAINS!"
speech_verb = "moans"
whisper_verb = "mutters"
exclaim_verb = "wails"
colour = "zombie"
key = "zom"
flags = RESTRICTED
syllables = list("BRAAAAAAAAAAAAAAAAINS", "BRAAINS", "BRAINS")
/mob/proc/grant_all_babel_languages()
for(var/la in GLOB.all_languages)
var/datum/language/new_language = GLOB.all_languages[la]
+4 -20
View File
@@ -2,6 +2,7 @@
name = "alien"
voice_name = "alien"
speak_emote = list("hisses")
bubble_icon = "alien"
icon = 'icons/mob/alien.dmi'
gender = NEUTER
dna = null
@@ -26,6 +27,8 @@
var/death_sound = 'sound/voice/hiss6.ogg'
/mob/living/carbon/alien/New()
..()
create_reagents(1000)
verbs += /mob/living/verb/mob_sleep
verbs += /mob/living/verb/lay_down
alien_organs += new /obj/item/organ/internal/brain/xeno
@@ -33,7 +36,6 @@
alien_organs += new /obj/item/organ/internal/ears
for(var/obj/item/organ/internal/I in alien_organs)
I.insert(src)
..()
/mob/living/carbon/alien/get_default_language()
if(default_language)
@@ -67,18 +69,6 @@
/mob/living/carbon/alien/check_eye_prot()
return 2
/mob/living/carbon/alien/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
return
health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
update_stat("updatehealth([reason])")
med_hud_set_health()
med_hud_set_status()
handle_hud_icons_health()
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
if(!environment)
@@ -118,12 +108,6 @@
else
clear_alert("alien_fire")
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
if(..())
return
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
return
/mob/living/carbon/alien/IsAdvancedToolUser()
return has_fine_manipulation
@@ -243,7 +227,7 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/handle_footstep(turf/T)
if(..())
if(T.footstep_sounds["xeno"])
if(T.footstep_sounds && T.footstep_sounds["xeno"])
var/S = pick(T.footstep_sounds["xeno"])
if(S)
if(m_intent == MOVE_INTENT_RUN)
@@ -136,14 +136,11 @@ Doesn't work on other aliens/AI.*/
set category = "Alien"
if(powerc())
if(stomach_contents.len)
if(LAZYLEN(stomach_contents))
for(var/mob/M in src)
if(M in stomach_contents)
stomach_contents.Remove(M)
M.forceMove(loc)
//Paralyse(10)
src.visible_message("<span class='alertalien'><B>[src] hurls out the contents of [p_their()] stomach!</span>")
return
LAZYREMOVE(stomach_contents, M)
M.forceMove(drop_location())
visible_message("<span class='alertalien'><B>[src] hurls out the contents of [p_their()] stomach!</span>")
/mob/living/carbon/proc/getPlasma()
var/obj/item/organ/internal/xenos/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/xenos/plasmavessel)
@@ -167,4 +164,4 @@ Doesn't work on other aliens/AI.*/
adjustPlasma(-amount)
return 1
return 0
return 0
@@ -6,7 +6,6 @@
icon_state = "aliend_s"
/mob/living/carbon/alien/humanoid/drone/New()
create_reagents(100)
if(src.name == "alien drone")
src.name = text("alien drone ([rand(1, 1000)])")
src.real_name = src.name
@@ -26,7 +25,7 @@
if(powerc(500))
// Queen check
var/no_queen = 1
for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.living_mob_list)
for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list)
if(!Q.key && Q.get_int_organ(/obj/item/organ/internal/brain/))
continue
no_queen = 0
@@ -6,7 +6,6 @@
icon_state = "alienh_s"
/mob/living/carbon/alien/humanoid/hunter/New()
create_reagents(100)
if(name == "alien hunter")
name = text("alien hunter ([rand(1, 1000)])")
real_name = name
@@ -17,28 +16,6 @@
. = -1 //hunters are sanic
. += ..() //but they still need to slow down on stun
/mob/living/carbon/alien/humanoid/hunter/handle_hud_icons_health()
..() //-Yvarov
if(healths)
if(stat != 2)
switch(health)
if(125 to INFINITY)
healths.icon_state = "health0"
if(100 to 125)
healths.icon_state = "health1"
if(50 to 100)
healths.icon_state = "health2"
if(25 to 50)
healths.icon_state = "health3"
if(0 to 25)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
/mob/living/carbon/alien/humanoid/hunter/handle_environment()
if(m_intent == MOVE_INTENT_RUN || resting)
..()
@@ -83,7 +60,7 @@
else //Maybe uses plasma in the future, although that wouldn't make any sense...
leaping = 1
update_icons()
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin = 0, diagonals_first = 1, callback = CALLBACK(src, .leap_end))
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin = 0, diagonals_first = 1, callback = CALLBACK(src, .proc/leap_end))
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
leaping = 0
@@ -33,7 +33,6 @@
overlays += I
/mob/living/carbon/alien/humanoid/sentinel/New()
create_reagents(100)
if(name == "alien sentinel")
name = text("alien sentinel ([rand(1, 1000)])")
real_name = name
@@ -42,27 +41,6 @@
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
..()
/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health()
..() //-Yvarov
if(healths)
if(stat != 2)
switch(health)
if(150 to INFINITY)
healths.icon_state = "health0"
if(100 to 150)
healths.icon_state = "health1"
if(75 to 100)
healths.icon_state = "health2"
if(25 to 75)
healths.icon_state = "health3"
if(0 to 25)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
/*
/mob/living/carbon/alien/humanoid/sentinel/verb/evolve() // -- TLE
set name = "Evolve (250)"
@@ -6,6 +6,7 @@
icon_state = "alienq_s"
status_flags = CANPARALYSE
mob_size = MOB_SIZE_LARGE
bubble_icon = "alienroyal"
large = 1
ventcrawler = 0
@@ -30,17 +31,17 @@
overlays += I
/mob/living/carbon/alien/humanoid/empress/New()
create_reagents(100)
//there should only be one queen
for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.living_mob_list)
if(E == src) continue
if(E.stat == DEAD) continue
for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.alive_mob_list)
if(E == src)
continue
if(E.stat == DEAD)
continue
if(E.client)
name = "alien grand princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
break
real_name = src.name
real_name = name
alien_organs += new /obj/item/organ/internal/xenos/plasmavessel/queen
alien_organs += new /obj/item/organ/internal/xenos/acidgland
alien_organs += new /obj/item/organ/internal/xenos/eggsac
@@ -48,27 +49,6 @@
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
..()
/mob/living/carbon/alien/humanoid/empress/handle_hud_icons_health()
..() //-Yvarov
if(healths)
if(stat != 2)
switch(health)
if(250 to INFINITY)
healths.icon_state = "health0"
if(175 to 250)
healths.icon_state = "health1"
if(100 to 175)
healths.icon_state = "health2"
if(50 to 100)
healths.icon_state = "health3"
if(0 to 50)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
/mob/living/carbon/alien/humanoid/empress/verb/lay_egg()
set name = "Lay Egg (250)"
set desc = "Lay an egg to produce huggers to impregnate prey with."
@@ -2,7 +2,7 @@
name = "alien"
icon_state = "alien_s"
butcher_results = list(/obj/item/reagent_containers/food/snacks/xenomeat = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
butcher_results = list(/obj/item/reagent_containers/food/snacks/monstermeat/xenomeat= 5, /obj/item/stack/sheet/animalhide/xeno = 1)
var/obj/item/r_store = null
var/obj/item/l_store = null
var/caste = ""
@@ -17,7 +17,6 @@
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/humanoid/New()
create_reagents(1000)
if(name == "alien")
name = text("alien ([rand(1, 1000)])")
real_name = name
@@ -55,7 +55,7 @@
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>")
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_CLAW
..()
@@ -2,27 +2,6 @@
. = ..()
update_icons()
/mob/living/carbon/alien/humanoid/handle_disabilities()
if(disabilities & EPILEPSY)
if((prob(1) && paralysis < 10))
to_chat(src, "<span class='danger'>You have a seizure!</span>")
Paralyse(10)
if(disabilities & COUGHING)
if((prob(5) && paralysis <= 1))
drop_item()
emote("cough")
return
if(disabilities & TOURETTES)
if((prob(10) && paralysis <= 1))
Stun(10)
emote("twitch")
return
if(disabilities & NERVOUS)
if(prob(10))
stuttering = max(10, stuttering)
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
var/difference = abs(current-loc_temp) //get difference
@@ -39,51 +18,3 @@
temperature = max(loc_temp, temperature-change)
temp_change = (temperature - current)
return temp_change
/mob/living/carbon/alien/humanoid/handle_regular_status_updates()
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
SetSilence(0)
else //ALIVE. LIGHTS ARE ON
if(health < HEALTH_THRESHOLD_DEAD && check_death_method() || !get_int_organ(/obj/item/organ/internal/brain))
death()
SetSilence(0)
return 1
//UNCONSCIOUS. NO-ONE IS HOME
if((getOxyLoss() > 50) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method()))
if(health <= 20 && prob(1))
emote("gasp")
if(!reagents.has_reagent("epinephrine"))
adjustOxyLoss(1)
Paralyse(3)
if(paralysis)
stat = UNCONSCIOUS
else if(sleeping)
stat = UNCONSCIOUS
if(prob(10) && health)
emote("hiss")
//CONSCIOUS
else
stat = CONSCIOUS
/* What in the living hell is this?*/
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
if(eye_blind) //blindness, heals slowly over time
AdjustEyeBlind(-1)
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
if(stuttering)
AdjustStuttering(-1)
if(silent)
AdjustSilence(-1)
if(druggy)
AdjustDruggy(-1)
return 1
@@ -11,12 +11,12 @@
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
/mob/living/carbon/alien/humanoid/queen/New()
create_reagents(100)
//there should only be one queen
for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.living_mob_list)
if(Q == src) continue
if(Q.stat == DEAD) continue
for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list)
if(Q == src)
continue
if(Q.stat == DEAD)
continue
if(Q.client)
name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
break
@@ -33,28 +33,7 @@
. = ..()
. += 3
/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health()
..() //-Yvarov
if(healths)
if(stat != DEAD)
switch(health)
if(250 to INFINITY)
healths.icon_state = "health0"
if(175 to 250)
healths.icon_state = "health1"
if(100 to 175)
healths.icon_state = "health2"
if(50 to 100)
healths.icon_state = "health3"
if(0 to 50)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
/mob/living/carbon/alien/humanoid/queen/can_inject()
/mob/living/carbon/alien/humanoid/queen/can_inject(mob/user, error_msg, target_zone, penetrate_thick)
return FALSE
//Queen verbs
@@ -56,20 +56,21 @@
/mob/living/carbon/alien/humanoid/regenerate_icons()
..()
if(notransform) return
if(notransform)
return
update_inv_head(0,0)
update_inv_wear_suit(0,0)
update_inv_r_hand(0)
update_inv_l_hand(0)
update_inv_pockets(0)
update_inv_head()
update_inv_wear_suit()
update_inv_r_hand()
update_inv_l_hand()
update_inv_pockets()
update_icons()
update_fire()
update_transform()
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
if(lying > 0)
lying = 90 //Anything else looks retarded
lying = 90 //Anything else looks lousy
..()
update_icons()
@@ -82,7 +83,7 @@
else
overlays_standing[X_FIRE_LAYER] = null
/mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1)
/mob/living/carbon/alien/humanoid/update_inv_wear_suit()
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit]
inv.update_icon()
@@ -110,10 +111,10 @@
overlays_standing[X_SUIT_LAYER] = standing
else
overlays_standing[X_SUIT_LAYER] = null
if(update_icons) update_icons()
update_icons()
/mob/living/carbon/alien/humanoid/update_inv_head(var/update_icons=1)
/mob/living/carbon/alien/humanoid/update_inv_head()
if(head)
var/t_state = head.item_state
if(!t_state) t_state = head.icon_state
@@ -124,17 +125,19 @@
overlays_standing[X_HEAD_LAYER] = standing
else
overlays_standing[X_HEAD_LAYER] = null
if(update_icons) update_icons()
update_icons()
/mob/living/carbon/alien/humanoid/update_inv_pockets(var/update_icons=1)
if(l_store) l_store.screen_loc = ui_storage1
if(r_store) r_store.screen_loc = ui_storage2
if(update_icons) update_icons()
/mob/living/carbon/alien/humanoid/update_inv_pockets()
if(l_store)
l_store.screen_loc = ui_storage1
if(r_store)
r_store.screen_loc = ui_storage2
update_icons()
/mob/living/carbon/alien/humanoid/update_inv_r_hand(var/update_icons=1)
..(1)
/mob/living/carbon/alien/humanoid/update_inv_r_hand()
..()
if(r_hand)
var/t_state = r_hand.item_state
if(!t_state) t_state = r_hand.icon_state
@@ -142,10 +145,10 @@
overlays_standing[X_R_HAND_LAYER] = image("icon" = r_hand.righthand_file, "icon_state" = t_state)
else
overlays_standing[X_R_HAND_LAYER] = null
if(update_icons) update_icons()
update_icons()
/mob/living/carbon/alien/humanoid/update_inv_l_hand(var/update_icons=1)
..(1)
/mob/living/carbon/alien/humanoid/update_inv_l_hand()
..()
if(l_hand)
var/t_state = l_hand.item_state
if(!t_state) t_state = l_hand.icon_state
@@ -153,7 +156,7 @@
overlays_standing[X_L_HAND_LAYER] = image("icon" = l_hand.lefthand_file, "icon_state" = t_state)
else
overlays_standing[X_L_HAND_LAYER] = null
if(update_icons) update_icons()
update_icons()
//Xeno Overlays Indexes//////////
@@ -5,8 +5,8 @@
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
maxHealth = 30
health = 30
maxHealth = 25
health = 25
density = 0
var/amount_grown = 0
@@ -17,7 +17,6 @@
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/New()
create_reagents(100)
if(name == "alien larva")
name = "alien larva ([rand(1, 1000)])"
real_name = name
@@ -25,7 +24,6 @@
add_language("Xenomorph")
add_language("Hivemind")
alien_organs += new /obj/item/organ/internal/xenos/plasmavessel/larva
..()
//This needs to be fixed
@@ -31,7 +31,7 @@
step_away(src, user, 15)
return TRUE
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_BITE
..()
@@ -1,57 +1,28 @@
/mob/living/carbon/alien/larva/Life(seconds, times_fired)
if(..()) //still breathing
set invisibility = 0
if(notransform)
return
if(..()) //not dead and not in stasis
// GROW!
if(amount_grown < max_grown)
amount_grown++
update_icons()
//some kind of bug in canmove() isn't properly calling update_icons, so this is here as a placeholder
update_icons()
/mob/living/carbon/alien/larva/handle_regular_status_updates()
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
SetSilence(0)
else //ALIVE. LIGHTS ARE ON
if(health < -25 || !get_int_organ(/obj/item/organ/internal/brain))
/mob/living/carbon/alien/larva/update_stat(reason = "None given")
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health <= -maxHealth || !get_int_organ(/obj/item/organ/internal/brain))
death()
SetSilence(0)
return 1
return
//UNCONSCIOUS. NO-ONE IS HOME
if((getOxyLoss() > 25) || (HEALTH_THRESHOLD_CRIT >= health && check_death_method()))
//if( health <= 20 && prob(1) )
// spawn(0)
// emote("gasp")
if(!reagents.has_reagent("epinephrine"))
adjustOxyLoss(1)
Paralyse(3)
if(paralysis)
stat = UNCONSCIOUS
else if(sleeping)
stat = UNCONSCIOUS
if(prob(10) && health)
emote("hiss_")
//CONSCIOUS
if(paralysis || sleeping || getOxyLoss() > 50 || (health <= HEALTH_THRESHOLD_CRIT && check_death_method()))
if(stat == CONSCIOUS)
KnockOut()
create_debug_log("fell unconscious, trigger reason: [reason]")
else
stat = CONSCIOUS
/* What in the living hell is this?*/
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
if(eye_blind) //blindness, heals slowly over time
AdjustEyeBlind(-1)
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
if(stuttering)
AdjustStuttering(-1)
if(silent)
AdjustSilence(-1)
if(druggy)
AdjustDruggy(-1)
return 1
if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
update_damage_hud()
update_health_hud()
@@ -28,3 +28,15 @@
//BREATH TEMPERATURE
handle_breath_temperature(breath)
/mob/living/carbon/alien/handle_status_effects()
..()
//natural reduction of movement delay due to stun.
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
. = ..()
if(.) //if the mob isn't on fire anymore
return
adjust_bodytemperature(BODYTEMP_HEATING_MAX) //If you're on fire, you heat up!
@@ -83,7 +83,7 @@
return Attach(AM)
return 0
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force)
if(!..())
return
if(stat == CONSCIOUS)
@@ -146,7 +146,7 @@
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
src.loc = target
target.equip_to_slot(src, slot_wear_mask,,0)
target.equip_to_slot_if_possible(src, slot_wear_mask, FALSE, TRUE)
if(!sterile)
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
+2 -2
View File
@@ -49,7 +49,7 @@
brainmob.stat = CONSCIOUS
GLOB.respawnable_list -= brainmob
GLOB.dead_mob_list -= brainmob//Update dem lists
GLOB.living_mob_list += brainmob
GLOB.alive_mob_list += brainmob
held_brain = B
if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
@@ -157,7 +157,7 @@
brainmob.container = null//Reset brainmob mmi var.
brainmob.forceMove(held_brain) //Throw mob into brain.
GLOB.respawnable_list += brainmob
GLOB.living_mob_list -= brainmob//Get outta here
GLOB.alive_mob_list -= brainmob//Get outta here
held_brain.brainmob = brainmob//Set the brain to use the brainmob
held_brain.brainmob.cancel_camera()
brainmob = null//Set mmi brainmob var to null
@@ -7,9 +7,8 @@
icon_state = "brain1"
/mob/living/carbon/brain/New()
create_reagents(330)
add_language("Galactic Common")
..()
add_language("Galactic Common")
/mob/living/carbon/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
@@ -26,11 +26,9 @@
mmi_icon = 'icons/mob/alien.dmi'
mmi_icon_state = "AlienMMI"
/obj/item/organ/internal/brain/New()
..()
spawn(5)
if(brainmob && brainmob.client)
brainmob.client.screen.len = null //clear the hud
/obj/item/organ/internal/brain/Destroy()
QDEL_NULL(brainmob)
return ..()
/obj/item/organ/internal/brain/proc/transfer_identity(var/mob/living/carbon/H)
brainmob = new(src)
@@ -72,7 +70,7 @@
if(istype(owner,/mob/living/carbon/human))
var/mob/living/carbon/human/H = owner
H.update_hair(1)
H.update_hair()
. = ..()
/obj/item/organ/internal/brain/insert(var/mob/living/target,special = 0)
@@ -84,7 +82,7 @@
brain_already_exists = 1
var/mob/living/carbon/human/H = target
H.update_hair(1)
H.update_hair()
if(!brain_already_exists)
if(brainmob)
+2 -4
View File
@@ -28,13 +28,11 @@
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
adjustFireLoss(5.0*discomfort)
/mob/living/carbon/brain/handle_regular_status_updates()
/mob/living/carbon/brain/Life()
. = ..()
if(.)
if(!container && (health < HEALTH_THRESHOLD_DEAD && check_death_method() || ((world.time - timeofhostdeath) > config.revival_brain_life)))
if(!container && (world.time - timeofhostdeath) > config.revival_brain_life)
death()
return 0
/mob/living/carbon/brain/breathe()
return
@@ -110,7 +110,6 @@
if(imprinted_master)
to_chat(H, "<span class='biggerdanger'>You are permanently imprinted to [imprinted_master], obey [imprinted_master]'s every order and assist [imprinted_master.p_them()] in completing [imprinted_master.p_their()] goals at any cost.</span>")
/obj/item/mmi/robotic_brain/proc/transfer_personality(mob/candidate)
searching = FALSE
brainmob.key = candidate.key
@@ -206,6 +205,10 @@
brainmob.container = src
brainmob.stat = CONSCIOUS
brainmob.SetSilence(0)
brainmob.dna = new(brainmob)
brainmob.dna.species = new /datum/species/machine() // Else it will default to human. And we don't want to clone IRC humans now do we?
brainmob.dna.ResetSE()
brainmob.dna.ResetUI()
GLOB.dead_mob_list -= brainmob
..()
+78 -58
View File
@@ -2,6 +2,10 @@
var/canEnterVentWith = "/obj/item/implant=0&/obj/item/clothing/mask/facehugger=0&/obj/item/radio/borg=0&/obj/machinery/camera=0"
var/datum/middleClickOverride/middleClickOverride = null
/mob/living/carbon/Initialize(mapload)
. = ..()
GLOB.carbon_list += src
/mob/living/carbon/Destroy()
// This clause is here due to items falling off from limb deletion
for(var/obj/item in get_all_slots())
@@ -9,10 +13,16 @@
qdel(item)
QDEL_LIST(internal_organs)
QDEL_LIST(stomach_contents)
QDEL_LIST(processing_patches)
var/mob/living/simple_animal/borer/B = has_brain_worms()
if(B)
B.leave_host()
qdel(B)
GLOB.carbon_list -= src
return ..()
/mob/living/carbon/handle_atom_del(atom/A)
LAZYREMOVE(processing_patches, A)
return ..()
/mob/living/carbon/blob_act(obj/structure/blob/B)
@@ -40,41 +50,40 @@
/mob/living/carbon/var/last_stomach_attack //defining this here because no one would look in carbon_defines for it
/mob/living/carbon/relaymove(var/mob/user, direction)
if(user in src.stomach_contents)
if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time) return
/mob/living/carbon/relaymove(mob/user, direction)
if(LAZYLEN(stomach_contents))
if(user in stomach_contents)
if(last_stomach_attack + STOMACH_ATTACK_DELAY > world.time)
return
last_stomach_attack = world.time
for(var/mob/M in hearers(4, src))
if(M.client)
M.show_message(text("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>"), 2)
var/obj/item/I = user.get_active_hand()
if(I && I.force)
var/d = rand(round(I.force / 4), I.force)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
var/obj/item/organ/external/organ = H.get_organ("chest")
if(istype(organ))
if(organ.receive_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth("stomach attack")
else
src.take_organ_damage(d)
for(var/mob/M in viewers(user, null))
last_stomach_attack = world.time
for(var/mob/M in hearers(4, src))
if(M.client)
M.show_message(text("<span class='warning'><B>[user] attacks [src]'s stomach wall with the [I.name]!</span>"), 2)
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
M.show_message(text("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>"), 2)
if(prob(src.getBruteLoss() - 50))
for(var/atom/movable/A in stomach_contents)
A.forceMove(drop_location())
stomach_contents.Remove(A)
src.gib()
var/obj/item/I = user.get_active_hand()
if(I && I.force)
var/d = rand(round(I.force / 4), I.force)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
var/obj/item/organ/external/organ = H.get_organ("chest")
if(istype(organ))
if(organ.receive_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth("stomach attack")
else
take_organ_damage(d)
for(var/mob/M in viewers(user, null))
if(M.client)
M.show_message(text("<span class='warning'><B>[user] attacks [src]'s stomach wall with the [I.name]!</span>"), 2)
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(prob(getBruteLoss() - 50))
gib()
#undef STOMACH_ATTACK_DELAY
@@ -129,9 +138,8 @@
I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
for(var/mob/M in src)
if(M in src.stomach_contents)
src.stomach_contents.Remove(M)
M.forceMove(get_turf(src))
LAZYREMOVE(stomach_contents, M)
M.forceMove(drop_location())
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
@@ -432,13 +440,8 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
if(!vent_found)
for(var/obj/machinery/atmospherics/machine in range(1,src))
if(is_type_in_list(machine, GLOB.ventcrawl_machinery))
if(is_type_in_list(machine, GLOB.ventcrawl_machinery) && machine.can_crawl_through())
vent_found = machine
if(!vent_found.can_crawl_through())
vent_found = null
if(vent_found)
break
if(vent_found)
@@ -485,7 +488,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine)
if(!istype(starting_machine) || !starting_machine.returnPipenet())
if(!istype(starting_machine) || !starting_machine.returnPipenet() || !starting_machine.can_see_pipes())
return
var/datum/pipeline/pipeline = starting_machine.returnPipenet()
var/list/totalMembers = list()
@@ -869,7 +872,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
unEquip(I)
I.dropped()
return
return 1
else
to_chat(src, "<span class='warning'>You fail to remove [I]!</span>")
@@ -925,9 +927,10 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
return initial(pixel_y)
/mob/living/carbon/emp_act(severity)
for(var/obj/item/organ/internal/O in internal_organs)
O.emp_act(severity)
..()
for(var/X in internal_organs)
var/obj/item/organ/internal/O = X
O.emp_act(severity)
/mob/living/carbon/Stat()
..()
@@ -975,25 +978,30 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/proc/slip(description, stun, weaken, tilesSlipped, walkSafely, slipAny, slipVerb = "slip")
if(flying || buckled || (walkSafely && m_intent == MOVE_INTENT_WALK))
return 0
return FALSE
if((lying) && (!(tilesSlipped)))
return 0
return FALSE
if(!(slipAny))
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
if(isobj(H.shoes) && H.shoes.flags & NOSLIP)
return 0
return FALSE
if(tilesSlipped)
for(var/t = 0, t<=tilesSlipped, t++)
spawn (t) step(src, src.dir)
for(var/i in 1 to tilesSlipped)
spawn(i)
step(src, dir)
stop_pulling()
to_chat(src, "<span class='notice'>You [slipVerb]ped on [description]!</span>")
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
playsound(loc, 'sound/misc/slip.ogg', 50, 1, -3)
// Something something don't run with scissors
moving_diagonally = 0 //If this was part of diagonal move slipping will stop it.
Stun(stun)
Weaken(weaken)
return 1
return TRUE
/mob/living/carbon/proc/can_eat(flags = 255)
return 1
@@ -1058,10 +1066,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
/mob/living/carbon/proc/forceFedAttackLog(var/obj/item/reagent_containers/food/toEat, mob/user)
add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagents.log_list(toEat)]", toEat.reagents.harmless_helper() ? ATKLOG_ALMOSTALL : null)
if(!iscarbon(user))
LAssailant = null
else
LAssailant = user
/*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach
@@ -1078,8 +1082,9 @@ so that different stomachs can handle things in different ways VB*/
if(can_taste_container)
taste(toEat.reagents)
var/fraction = min(this_bite/toEat.reagents.total_volume, 1)
toEat.reagents.reaction(src, toEat.apply_type, fraction)
toEat.reagents.trans_to(src, this_bite*toEat.transfer_efficiency)
if(fraction)
toEat.reagents.reaction(src, toEat.apply_type, fraction)
toEat.reagents.trans_to(src, this_bite*toEat.transfer_efficiency)
/mob/living/carbon/get_access()
. = ..()
@@ -1193,3 +1198,18 @@ so that different stomachs can handle things in different ways VB*/
I.acid_level = 0 //washes off the acid on our clothes
I.extinguish() //extinguishes our clothes
..()
/mob/living/carbon/clean_blood(clean_hands = TRUE, clean_mask = TRUE, clean_feet = TRUE)
if(head)
if(head.clean_blood())
update_inv_head()
if(head.flags_inv & HIDEMASK)
clean_mask = FALSE
if(wear_suit)
if(wear_suit.clean_blood())
update_inv_wear_suit()
if(wear_suit.flags_inv & HIDESHOES)
clean_feet = FALSE
if(wear_suit.flags_inv & HIDEGLOVES)
clean_hands = FALSE
..(clean_hands, clean_mask, clean_feet)
@@ -12,7 +12,7 @@
visible_message("<span class='warning'>[src] catches [AM]!</span>")
throw_mode_off()
return TRUE
..()
return ..()
/mob/living/carbon/water_act(volume, temperature, source, method = REAGENT_TOUCH)
. = ..()
@@ -1,10 +1,10 @@
/mob/living/carbon
gender = MALE
pressure_resistance = 15
var/list/stomach_contents = list()
var/list/stomach_contents
var/list/processing_patches
var/list/internal_organs = list()
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
var/antibodies = 0
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
@@ -131,7 +131,7 @@
m_styles["head"] = "None"
update_markings()
update_body(1, 1) //Update the body and force limb icon regeneration to update the head with the new icon.
update_body(TRUE) //Update the body and force limb icon regeneration to update the head with the new icon.
if(wear_mask)
update_inv_wear_mask()
return 1
@@ -469,7 +469,7 @@
scramble(1, src, 100)
real_name = random_name(gender, dna.species.name) //Give them a name that makes sense for their species.
sync_organ_dna(assimilate = 1)
update_body(0)
update_body()
reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover.
reset_markings() //...Or markings.
dna.ResetUIFrom(src)
@@ -1,17 +1,5 @@
GLOBAL_LIST_INIT(body_accessory_by_name, list("None" = null))
/hook/startup/proc/initalize_body_accessories()
__init_body_accessory(/datum/body_accessory/body)
__init_body_accessory(/datum/body_accessory/tail)
if(GLOB.body_accessory_by_name.len)
if(initialize_body_accessory_by_species())
return TRUE
return FALSE //fail if no bodies are found
GLOBAL_LIST_INIT(body_accessory_by_species, list("None" = null))
/proc/initialize_body_accessory_by_species()
@@ -77,15 +65,6 @@ GLOBAL_LIST_INIT(body_accessory_by_species, list("None" = null))
/datum/body_accessory/body
blend_mode = ICON_MULTIPLY
/datum/body_accessory/body/snake
name = "Snake"
icon = 'icons/mob/body_accessory_64.dmi'
icon_state = "snake"
pixel_x_offset = -16
//Tails
/datum/body_accessory/tail
icon = 'icons/mob/body_accessory.dmi'
+15 -22
View File
@@ -6,7 +6,7 @@
canmove = 0
icon = null
invisibility = 101
if(!isSynthetic())
if(!ismachineperson(src))
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
@@ -32,12 +32,11 @@
E.droplimb(DROPLIMB_SHARP)
for(var/mob/M in src)
if(M in stomach_contents)
stomach_contents.Remove(M)
M.forceMove(get_turf(src))
LAZYREMOVE(stomach_contents, M)
M.forceMove(drop_location())
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
if(!isSynthetic())
if(!ismachineperson(src))
flick("gibbed-h", animation)
hgibs(loc, dna)
else
@@ -103,15 +102,9 @@
set_heartattack(FALSE)
SSmobs.cubemonkeys -= src
if(dna.species)
dna.species.handle_hud_icons(src)
//Handle species-specific deaths.
dna.species.handle_death(gibbed, src)
if(ishuman(LAssailant))
var/mob/living/carbon/human/H=LAssailant
if(H.mind)
H.mind.kills += "[key_name(src)]"
if(SSticker && SSticker.mode)
// log_world("k")
sql_report_death(src)
@@ -124,10 +117,10 @@
if(. && healthdoll)
// We're alive again, so re-build the entire healthdoll
healthdoll.cached_healthdoll_overlays.Cut()
update_health_hud()
// Update healthdoll
if(dna.species)
dna.species.update_sight(src)
dna.species.handle_hud_icons(src)
/mob/living/carbon/human/proc/makeSkeleton()
var/obj/item/organ/external/head/H = get_organ("head")
@@ -146,14 +139,14 @@
H.alt_head = initial(H.alt_head)
H.handle_alt_icon()
m_styles = DEFAULT_MARKING_STYLES
update_fhair(0)
update_hair(0)
update_head_accessory(0)
update_markings(0)
update_fhair()
update_hair()
update_head_accessory()
update_markings()
mutations.Add(SKELETON)
mutations.Add(NOCLONE)
update_body(0)
update_body()
update_mutantrace()
return
@@ -172,11 +165,11 @@
H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE
if(H.h_style)
H.h_style = "Bald"
update_fhair(0)
update_hair(0)
update_fhair()
update_hair()
mutations.Add(HUSK)
update_body(0)
update_body()
update_mutantrace()
return
@@ -190,6 +183,6 @@
var/obj/item/organ/external/head/H = bodyparts_by_name["head"]
if(istype(H))
H.disfigured = FALSE
update_body(0)
update_mutantrace(0)
update_body()
update_mutantrace()
UpdateAppearance() // reset hair from DNA
+21 -11
View File
@@ -34,7 +34,7 @@
//Cooldown-inducing emotes
if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no", "buzz2")
var/found_machine_head = FALSE
if(ismachine(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
if(ismachineperson(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
found_machine_head = TRUE
else
@@ -139,10 +139,18 @@
//WHO THE FUCK THOUGHT THAT WAS A GOOD FUCKING IDEA!?!?
if("howl", "howls")
var/M = handle_emote_param(param) //Check to see if the param is valid (mob with the param name is in view).
message = "<B>[src]</B> howls[M ? " at [M]" : ""]!"
playsound(loc, 'sound/goonstation/voice/howl.ogg', 100, 1, 10, frequency = get_age_pitch())
m_type = 2
var/M = handle_emote_param(param)
if(miming)
message = "<B>[src]</B> acts out a howl[M ? " at [M]" : ""]!"
m_type = 1
else
if(!muzzled)
message = "<B>[src]</B> howls[M ? " at [M]" : ""]!"
playsound(loc, 'sound/goonstation/voice/howl.ogg', 100, 1, 10, frequency = get_age_pitch())
m_type = 2
else
message = "<B>[src]</B> makes a very loud noise[M ? " at [M]" : ""]."
m_type = 2
if("growl", "growls")
var/M = handle_emote_param(param)
@@ -256,12 +264,12 @@
if(body_accessory)
if(body_accessory.try_restrictions(src))
message = "<B>[src]</B> starts wagging [p_their()] tail."
start_tail_wagging(1)
start_tail_wagging()
else if(dna.species.bodyflags & TAIL_WAGGING)
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL))
message = "<B>[src]</B> starts wagging [p_their()] tail."
start_tail_wagging(1)
start_tail_wagging()
else
return
else
@@ -271,7 +279,7 @@
if("swag", "swags")
if(dna.species.bodyflags & TAIL_WAGGING || body_accessory)
message = "<B>[src]</B> stops wagging [p_their()] tail."
stop_tail_wagging(1)
stop_tail_wagging()
else
return
m_type = 1
@@ -300,14 +308,14 @@
m_type = 1
if("bow", "bows")
if(!buckled)
if(!restrained())
var/M = handle_emote_param(param)
message = "<B>[src]</B> bows[M ? " to [M]" : ""]."
m_type = 1
if("salute", "salutes")
if(!buckled)
if(!restrained())
var/M = handle_emote_param(param)
message = "<B>[src]</B> salutes[M ? " to [M]" : ""]."
@@ -400,7 +408,9 @@
var/turf/newloc = G.affecting.loc
if(isturf(oldloc) && isturf(newloc))
SpinAnimation(5,1)
glide_for(6) // This and the glide_for below are purely arbitrary. Pick something that looks aesthetically pleasing.
forceMove(newloc)
G.glide_for(6)
G.affecting.forceMove(oldloc)
message = "<B>[src]</B> flips over [G.affecting]!"
else
@@ -937,7 +947,7 @@
if("Skrell")
emotelist += "\nSkrell specific emotes :- warble(s)"
if(ismachine(src))
if(ismachineperson(src))
emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
else
var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises
+34 -15
View File
@@ -208,7 +208,7 @@
if(!E)
wound_flavor_text["[organ_tag]"] = "<B>[p_they(TRUE)] [p_are()] missing [p_their()] [organ_descriptor].</B>\n"
else
if(!isSynthetic())
if(!ismachineperson(src))
if(E.is_robotic())
wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a robotic [E.name]!\n"
@@ -252,7 +252,7 @@
var/temp = getBruteLoss() //no need to calculate each of these twice
if(temp)
var/brute_message = !isSynthetic() ? "bruising" : "denting"
var/brute_message = !ismachineperson(src) ? "bruising" : "denting"
if(temp < 30)
msg += "[p_they(TRUE)] [p_have()] minor [brute_message ].\n"
else
@@ -292,19 +292,22 @@
if(nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA)
msg += "[p_they(TRUE)] [p_are()] severely malnourished.\n"
else if(nutrition >= NUTRITION_LEVEL_FAT)
if(FAT in mutations)
msg += "[p_they(TRUE)] [p_are()] morbidly obese.\n"
if(user.nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA)
msg += "[p_they(TRUE)] [p_are()] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
else
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
if(!isSynthetic() && blood_volume < BLOOD_VOLUME_SAFE)
else if(nutrition >= NUTRITION_LEVEL_FAT)
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
if(!ismachineperson(src) && blood_volume < BLOOD_VOLUME_SAFE)
msg += "[p_they(TRUE)] [p_have()] pale skin.\n"
if(bleedsuppress)
msg += "[p_they(TRUE)] [p_are()] bandaged with something.\n"
else if(bleed_rate)
var/bleed_message = !isSynthetic() ? "bleeding" : "leaking"
var/bleed_message = !ismachineperson(src) ? "bleeding" : "leaking"
msg += "<B>[p_they(TRUE)] [p_are()] [bleed_message]!</B>\n"
if(reagents.has_reagent("teslium"))
@@ -338,11 +341,12 @@
if(decaylevel == 3)
msg += "[p_they(TRUE)] [p_are()] rotting and blackened, the skin sloughing off. The smell is indescribably foul.\n"
if(decaylevel == 4)
msg += "[p_they(TRUE)] [p_are()] mostly dessicated now, with only bones remaining of what used to be a person.\n"
msg += "[p_they(TRUE)] [p_are()] mostly desiccated now, with only bones remaining of what used to be a person.\n"
if(hasHUD(user,"security"))
var/perpname = get_visible_name(TRUE)
var/criminal = "None"
var/commentLatest = "ERROR: Unable to locate a data core entry for this person." //If there is no datacore present, give this
if(perpname)
for(var/datum/data/record/E in GLOB.data_core.general)
@@ -350,9 +354,16 @@
for(var/datum/data/record/R in GLOB.data_core.security)
if(R.fields["id"] == E.fields["id"])
criminal = R.fields["criminal"]
if(LAZYLEN(R.fields["comments"])) //if the commentlist is present
var/list/comments = R.fields["comments"]
commentLatest = LAZYACCESS(comments, comments.len) //get the latest entry from the comment log
else
commentLatest = "No entries." //If present but without entries (=target is recognized crew)
var/criminal_status = hasHUD(user, "read_only_security") ? "\[[criminal]\]" : "<a href='?src=[UID()];criminal=1'>\[[criminal]\]</a>"
msg += "<span class = 'deptradio'>Criminal status:</span> [criminal_status]\n"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=[UID()];secrecord=`'>\[View\]</a> <a href='?src=[UID()];secrecordadd=`'>\[Add comment\]</a>\n"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=[UID()];secrecordComment=`'>\[View comment log\]</a> <a href='?src=[UID()];secrecordadd=`'>\[Add comment\]</a>\n"
msg += "<span class = 'deptradio'>Latest entry:</span> [commentLatest]\n"
if(hasHUD(user,"medical"))
var/perpname = get_visible_name(TRUE)
@@ -395,17 +406,25 @@
if("medical")
return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical)
else
return 0
return FALSE
else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system
switch(hudtype)
if("security")
return 1
return TRUE
if("medical")
return 1
return TRUE
else
return 0
return FALSE
else if(isobserver(M))
var/mob/dead/observer/O = M
if(O.data_hud_seen == DATA_HUD_SECURITY_ADVANCED || O.data_hud_seen == DATA_HUD_DIAGNOSTIC + DATA_HUD_SECURITY_ADVANCED + DATA_HUD_MEDICAL_ADVANCED)
switch(hudtype)
if("security")
return TRUE
else
return FALSE
else
return 0
return FALSE
// Ignores robotic limb branding prefixes like "Morpheus Cybernetics"
/proc/ignore_limb_branding(limb_name)
@@ -431,4 +450,4 @@
if("l_hand")
. = "left hand"
if("r_hand")
. = "right hand"
. = "right hand"
+46 -53
View File
@@ -18,9 +18,9 @@
dna = new /datum/dna(null)
// Species name is handled by set_species()
set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE)
. = ..()
..()
set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE)
if(dna.species)
real_name = dna.species.get_random_name(gender)
@@ -41,6 +41,7 @@
sync_organ_dna(1)
UpdateAppearance()
GLOB.human_list += src
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
@@ -60,61 +61,62 @@
SSmobs.cubemonkeys -= src
QDEL_LIST(bodyparts)
splinted_limbs.Cut()
GLOB.human_list -= src
/mob/living/carbon/human/dummy
real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH
/mob/living/carbon/human/skrell/Initialize(mapload)
..(mapload, /datum/species/skrell)
. = ..(mapload, /datum/species/skrell)
/mob/living/carbon/human/tajaran/Initialize(mapload)
..(mapload, /datum/species/tajaran)
. = ..(mapload, /datum/species/tajaran)
/mob/living/carbon/human/vulpkanin/Initialize(mapload)
..(mapload, /datum/species/vulpkanin)
. = ..(mapload, /datum/species/vulpkanin)
/mob/living/carbon/human/unathi/Initialize(mapload)
..(mapload, /datum/species/unathi)
. = ..(mapload, /datum/species/unathi)
/mob/living/carbon/human/vox/Initialize(mapload)
..(mapload, /datum/species/vox)
. = ..(mapload, /datum/species/vox)
/mob/living/carbon/human/voxarmalis/Initialize(mapload)
..(mapload, /datum/species/vox/armalis)
. = ..(mapload, /datum/species/vox/armalis)
/mob/living/carbon/human/skeleton/Initialize(mapload)
..(mapload, /datum/species/skeleton)
. = ..(mapload, /datum/species/skeleton)
/mob/living/carbon/human/kidan/Initialize(mapload)
..(mapload, /datum/species/kidan)
. = ..(mapload, /datum/species/kidan)
/mob/living/carbon/human/plasma/Initialize(mapload)
..(mapload, /datum/species/plasmaman)
. = ..(mapload, /datum/species/plasmaman)
/mob/living/carbon/human/slime/Initialize(mapload)
..(mapload, /datum/species/slime)
. = ..(mapload, /datum/species/slime)
/mob/living/carbon/human/grey/Initialize(mapload)
..(mapload, /datum/species/grey)
. = ..(mapload, /datum/species/grey)
/mob/living/carbon/human/abductor/Initialize(mapload)
..(mapload, /datum/species/abductor)
. = ..(mapload, /datum/species/abductor)
/mob/living/carbon/human/diona/Initialize(mapload)
..(mapload, /datum/species/diona)
. = ..(mapload, /datum/species/diona)
/mob/living/carbon/human/pod_diona/Initialize(mapload)
..(mapload, /datum/species/diona/pod)
. = ..(mapload, /datum/species/diona/pod)
/mob/living/carbon/human/machine/Initialize(mapload)
..(mapload, /datum/species/machine)
. = ..(mapload, /datum/species/machine)
/mob/living/carbon/human/machine/created
name = "Integrated Robotic Chassis"
/mob/living/carbon/human/machine/created/Initialize(mapload)
..()
. = ..()
rename_character(null, "Integrated Robotic Chassis ([rand(1, 9999)])")
update_dna()
for(var/obj/item/organ/external/E in bodyparts)
@@ -127,34 +129,34 @@
death()
/mob/living/carbon/human/shadow/Initialize(mapload)
..(mapload, /datum/species/shadow)
. = ..(mapload, /datum/species/shadow)
/mob/living/carbon/human/golem/Initialize(mapload)
..(mapload, /datum/species/golem)
. = ..(mapload, /datum/species/golem)
/mob/living/carbon/human/wryn/Initialize(mapload)
..(mapload, /datum/species/wryn)
. = ..(mapload, /datum/species/wryn)
/mob/living/carbon/human/nucleation/Initialize(mapload)
..(mapload, /datum/species/nucleation)
. = ..(mapload, /datum/species/nucleation)
/mob/living/carbon/human/drask/Initialize(mapload)
..(mapload, /datum/species/drask)
. = ..(mapload, /datum/species/drask)
/mob/living/carbon/human/monkey/Initialize(mapload)
..(mapload, /datum/species/monkey)
. = ..(mapload, /datum/species/monkey)
/mob/living/carbon/human/farwa/Initialize(mapload)
..(mapload, /datum/species/monkey/tajaran)
. = ..(mapload, /datum/species/monkey/tajaran)
/mob/living/carbon/human/wolpin/Initialize(mapload)
..(mapload, /datum/species/monkey/vulpkanin)
. = ..(mapload, /datum/species/monkey/vulpkanin)
/mob/living/carbon/human/neara/Initialize(mapload)
..(mapload, /datum/species/monkey/skrell)
. = ..(mapload, /datum/species/monkey/skrell)
/mob/living/carbon/human/stok/Initialize(mapload)
..(mapload, /datum/species/monkey/unathi)
. = ..(mapload, /datum/species/monkey/unathi)
/mob/living/carbon/human/Stat()
..()
@@ -658,7 +660,7 @@
else
if(place_item)
usr.unEquip(place_item)
equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
equip_to_slot_if_possible(place_item, pocket_id, FALSE, TRUE)
add_attack_logs(usr, src, "Equipped with [place_item]", isLivingSSD(src) ? null : ATKLOG_ALL)
// Update strip window
@@ -715,14 +717,14 @@
for(var/datum/data/record/R in GLOB.data_core.security)
if(R.fields["id"] == E.fields["id"])
var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Released", "Cancel")
var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list(SEC_RECORD_STATUS_NONE, SEC_RECORD_STATUS_ARREST, SEC_RECORD_STATUS_SEARCH, SEC_RECORD_STATUS_MONITOR, SEC_RECORD_STATUS_DEMOTE, SEC_RECORD_STATUS_INCARCERATED, SEC_RECORD_STATUS_PAROLLED, SEC_RECORD_STATUS_RELEASED, "Cancel")
var/t1 = copytext(trim(sanitize(input("Enter Reason:", "Security HUD", null, null) as text)), 1, MAX_MESSAGE_LEN)
if(!t1)
t1 = "(none)"
if(hasHUD(usr, "security") && setcriminal != "Cancel")
found_record = 1
if(R.fields["criminal"] == "*Execute*")
if(R.fields["criminal"] == SEC_RECORD_STATUS_EXECUTE)
to_chat(usr, "<span class='warning'>Unable to modify the sec status of a person with an active Execution order. Use a security computer instead.</span>")
else
var/rank
@@ -768,7 +770,7 @@
if(href_list["secrecordComment"])
if(hasHUD(usr,"security"))
if(usr.incapacitated())
if(usr.incapacitated() && !isobserver(usr)) //give the ghosts access to "View Comment Log" while they can't manipulate it
return
var/perpname = get_visible_name(TRUE)
var/read = 0
@@ -783,7 +785,7 @@
for(var/c in R.fields["comments"])
to_chat(usr, c)
else
to_chat(usr, "<span class='warning'>No comment found</span>")
to_chat(usr, "<span class='warning'>No comments found</span>")
to_chat(usr, "<a href='?src=[UID()];secrecordadd=`'>\[Add comment\]</a>")
if(!read)
@@ -1160,18 +1162,6 @@
custom_pain("You feel a stabbing pain in your chest!")
L.damage = L.min_bruised_damage
//returns 1 if made bloody, returns 0 otherwise
/mob/living/carbon/human/clean_blood(var/clean_feet)
.=..()
if(clean_feet && !shoes && istype(feet_blood_DNA, /list) && feet_blood_DNA.len)
feet_blood_color = null
qdel(feet_blood_DNA)
bloody_feet = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_NOT_BLOODY = 0)
blood_state = BLOOD_STATE_NOT_BLOODY
update_inv_shoes(1)
return 1
/mob/living/carbon/human/cuff_resist(obj/item/I)
if(HULK in mutations)
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
@@ -1349,7 +1339,7 @@
dna.species.create_organs(src)
for(var/obj/item/thing in kept_items)
equip_to_slot_if_possible(thing, kept_items[thing], redraw_mob = 0)
equip_to_slot_if_possible(thing, kept_items[thing])
thing.flags = item_flags[thing] // Reset the flags to the origional ones
//Handle default hair/head accessories for created mobs.
@@ -1399,7 +1389,7 @@
UpdateAppearance()
overlays.Cut()
update_mutantrace(1)
update_mutantrace()
regenerate_icons()
if(dna.species)
@@ -1554,13 +1544,13 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security)
if(R && R.fields["criminal"])
switch(R.fields["criminal"])
if("*Execute*")
if(SEC_RECORD_STATUS_EXECUTE)
threatcount += 7
if("*Arrest*")
if(SEC_RECORD_STATUS_ARREST)
threatcount += 5
if("Incarcerated")
if(SEC_RECORD_STATUS_INCARCERATED)
threatcount += 2
if("Parolled")
if(SEC_RECORD_STATUS_PAROLLED)
threatcount += 2
//Check for dresscode violations
@@ -1699,14 +1689,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
/mob/living/carbon/human/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness)
if(!check_has_mouth())
if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachine(src)))))
if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachineperson(src)))))
to_chat(user, "Where do you intend to put \the [toEat]? \The [src] doesn't have a mouth!")
return 0
return ..()
/mob/living/carbon/human/selfDrink(var/obj/item/reagent_containers/food/drinks/toDrink)
if(!check_has_mouth())
if(!ismachine(src))
if(!ismachineperson(src))
to_chat(src, "Where do you intend to put \the [src]? You don't have a mouth!")
return 0
else
@@ -1962,3 +1952,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(O && O.glowing)
O.toggle_biolum(TRUE)
visible_message("<span class='danger'>[src] is engulfed in shadows and fades into the darkness.</span>", "<span class='danger'>A sense of dread washes over you as you suddenly dim dark.</span>")
/mob/living/carbon/human/proc/get_perceived_trauma()
return min(health, maxHealth - getStaminaLoss())
@@ -19,8 +19,6 @@
ChangeToHusk()
update_stat("updatehealth([reason])")
med_hud_set_health()
med_hud_set_status()
handle_hud_icons_health()
/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE)
if(status_flags & GODMODE)
@@ -32,7 +30,7 @@
if(dna.species && amount > 0)
if(use_brain_mod)
amount = amount * dna.species.brain_mod
sponge.damage = Clamp(sponge.damage + amount, 0, 120)
sponge.damage = clamp(sponge.damage + amount, 0, 120)
if(sponge.damage >= 120)
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
death()
@@ -50,7 +48,7 @@
if(dna.species && amount > 0)
if(use_brain_mod)
amount = amount * dna.species.brain_mod
sponge.damage = Clamp(amount, 0, 120)
sponge.damage = clamp(amount, 0, 120)
if(sponge.damage >= 120)
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
death()
@@ -111,7 +109,7 @@
var/obj/item/organ/external/O = get_organ(organ_name)
if(amount > 0)
O.receive_damage(amount, 0, sharp=is_sharp(damage_source), used_weapon=damage_source, list(), FALSE, updating_health)
O.receive_damage(amount, 0, sharp=is_sharp(damage_source), used_weapon=damage_source, forbidden_limbs = list(), ignore_resists=FALSE, updating_health=updating_health)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal = 0, robo_repair = O.is_robotic(), updating_health = updating_health)
@@ -84,7 +84,7 @@ emp_act
E.heal_damage(rembrute,0,0,1)
rembrute = nrembrute
user.visible_message("<span class='alert'>[user] patches some dents on [src]'s [E.name] with [I].</span>")
if(bleed_rate && isSynthetic())
if(bleed_rate && ismachineperson(src))
bleed_rate = 0
user.visible_message("<span class='alert'>[user] patches some leaks on [src] with [I].</span>")
if(IgniteMob())
@@ -134,7 +134,7 @@ emp_act
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & def_zone.body_part)
protection += C.armor[type]
protection += C.armor.getRating(type)
return protection
@@ -185,19 +185,19 @@ emp_act
var/block_chance_modifier = round(damage / -3)
if(l_hand && !istype(l_hand, /obj/item/clothing))
var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
var/final_block_chance = l_hand.block_chance - (clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(l_hand.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(r_hand && !istype(r_hand, /obj/item/clothing))
var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
var/final_block_chance = r_hand.block_chance - (clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
if(r_hand.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
var/final_block_chance = wear_suit.block_chance - (clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
if(w_uniform)
var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
var/final_block_chance = w_uniform.block_chance - (clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
return 1
return 0
@@ -206,12 +206,6 @@ emp_act
if(martial_art && prob(martial_art.block_chance) && martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE))
return TRUE
/mob/living/carbon/human/emp_act(severity)
for(var/obj/O in src)
if(!O) continue
O.emp_act(severity)
..()
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc
var/list/damaged = list()
var/list/inventory_items_to_kill = list()
@@ -393,11 +387,6 @@ emp_act
to_chat(user, "<span class='warning'>You hack off a chunk of meat from [name]</span>")
if(!meatleft)
add_attack_logs(user, src, "Chopped up into meat")
if(!iscarbon(user))
LAssailant = null
else
LAssailant = user
qdel(src)
var/obj/item/organ/external/affecting = get_organ(ran_zone(user.zone_selected))
@@ -463,13 +452,13 @@ emp_act
if(bloody)//Apply blood
if(wear_mask)
wear_mask.add_mob_blood(src)
update_inv_wear_mask(0)
update_inv_wear_mask()
if(head)
head.add_mob_blood(src)
update_inv_head(0,0)
update_inv_head()
if(glasses && prob(33))
glasses.add_mob_blood(src)
update_inv_glasses(0)
update_inv_glasses()
if("chest")//Easier to score a stun but lasts less time
@@ -481,10 +470,10 @@ emp_act
if(bloody)
if(wear_suit)
wear_suit.add_mob_blood(src)
update_inv_wear_suit(1)
update_inv_wear_suit()
if(w_uniform)
w_uniform.add_mob_blood(src)
update_inv_w_uniform(1)
update_inv_w_uniform()
@@ -531,16 +520,16 @@ emp_act
else
add_mob_blood(source)
bloody_hands = amount
update_inv_gloves(1) //updates on-mob overlays for bloody hands and/or bloody gloves
update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
/mob/living/carbon/human/proc/bloody_body(var/mob/living/source)
if(wear_suit)
wear_suit.add_mob_blood(source)
update_inv_wear_suit(0)
update_inv_wear_suit()
return
if(w_uniform)
w_uniform.add_mob_blood(source)
update_inv_w_uniform(1)
update_inv_w_uniform()
/mob/living/carbon/human/proc/handle_suit_punctures(var/damtype, var/damage)
@@ -23,7 +23,7 @@ GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new())
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
//Equipment slots
var/obj/item/w_uniform = null
var/obj/item/clothing/under/w_uniform = null
var/obj/item/shoes = null
var/obj/item/belt = null
var/obj/item/gloves = null
@@ -37,7 +37,6 @@ GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new())
var/obj/item/s_store = null
var/icon/stand_icon = null
var/icon/lying_icon = null
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
@@ -81,7 +81,7 @@
/mob/living/carbon/human/handle_footstep(turf/T)
if(..())
if(T.footstep_sounds["human"])
if(T.footstep_sounds && T.footstep_sounds["human"])
var/S = pick(T.footstep_sounds["human"])
if(S)
if(m_intent == MOVE_INTENT_RUN)
@@ -8,12 +8,15 @@
/mob/living/carbon/human/var/list/bodyparts_by_name = list() // map organ names to organs
// Takes care of organ related updates, such as broken and missing limbs
/mob/living/carbon/human/proc/handle_organs()
/mob/living/carbon/human/handle_organs()
..()
//processing internal organs is pretty cheap, do that first.
for(var/obj/item/organ/internal/I in internal_organs)
for(var/X in internal_organs)
var/obj/item/organ/internal/I = X
I.process()
for(var/obj/item/organ/external/E in bodyparts)
for(var/Y in bodyparts)
var/obj/item/organ/external/E = Y
E.process()
if(!lying && world.time - l_move_time < 15)
@@ -109,35 +112,18 @@
do_sparks(5, 0, src)
/mob/living/carbon/human/handle_germs()
..()
if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
/mob/living/carbon/human/proc/becomeSlim()
to_chat(src, "<span class='notice'>You feel fit again!</span>")
var/obj/item/organ/external/chest/C = get_organ("chest")
if(istype(C))
C.makeSlim(0)
else
to_chat(src, "Err, well, you *would*, but you don't have a torso. Yell at a coder.")
log_debug("[src] at ([x],[y],[z]) doesn't have a torso.")
mutations.Remove(FAT)
update_mutantrace(0)
update_mutations(0)
update_body(0, 1)
update_inv_w_uniform(0)
update_inv_wear_suit()
/mob/living/carbon/human/proc/becomeFat()
to_chat(src, "<span class='alert'>You suddenly feel blubbery!</span>")
var/obj/item/organ/external/chest/C = get_organ("chest")
if(istype(C))
C.makeFat()
else
to_chat(src, "Err, well, you *would*, but you don't have a torso. Yell at a coder.")
log_debug("[src] at ([x],[y],[z]) doesn't have a torso.")
mutations.Add(FAT)
update_mutantrace(0)
update_mutations(0)
update_body(0, 1)
update_inv_w_uniform(0)
update_inv_wear_suit()
//Handles chem traces
/mob/living/carbon/human/proc/handle_trace_chems()
@@ -178,8 +178,7 @@
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc.
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot, redraw_mob = 1)
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
if(!slot)
return
if(!istype(I))
@@ -203,40 +202,40 @@
switch(slot)
if(slot_back)
back = I
update_inv_back(redraw_mob)
update_inv_back()
if(slot_wear_mask)
wear_mask = I
if((wear_mask.flags & BLOCKHAIR) || (wear_mask.flags & BLOCKHEADHAIR))
update_hair(redraw_mob) //rebuild hair
update_fhair(redraw_mob)
update_head_accessory(redraw_mob)
update_hair() //rebuild hair
update_fhair()
update_head_accessory()
if(hud_list.len)
sec_hud_set_ID()
wear_mask_update(I, toggle_off = TRUE)
update_inv_wear_mask(redraw_mob)
update_inv_wear_mask()
if(slot_handcuffed)
handcuffed = I
update_inv_handcuffed(redraw_mob)
update_inv_handcuffed()
if(slot_legcuffed)
legcuffed = I
update_inv_legcuffed(redraw_mob)
update_inv_legcuffed()
if(slot_l_hand)
l_hand = I
update_inv_l_hand(redraw_mob)
update_inv_l_hand()
if(slot_r_hand)
r_hand = I
update_inv_r_hand(redraw_mob)
update_inv_r_hand()
if(slot_belt)
belt = I
update_inv_belt(redraw_mob)
update_inv_belt()
if(slot_wear_id)
wear_id = I
if(hud_list.len)
sec_hud_set_ID()
update_inv_wear_id(redraw_mob)
update_inv_wear_id()
if(slot_wear_pda)
wear_pda = I
update_inv_wear_pda(redraw_mob)
update_inv_wear_pda()
if(slot_l_ear)
l_ear = I
if(l_ear.slot_flags & SLOT_TWOEARS)
@@ -245,7 +244,7 @@
r_ear = O
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
update_inv_ears(redraw_mob)
update_inv_ears()
if(slot_r_ear)
r_ear = I
if(r_ear.slot_flags & SLOT_TWOEARS)
@@ -254,7 +253,7 @@
l_ear = O
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
update_inv_ears(redraw_mob)
update_inv_ears()
if(slot_glasses)
glasses = I
var/obj/item/clothing/glasses/G = I
@@ -264,42 +263,42 @@
update_nearsighted_effects()
if(G.vision_flags || G.see_in_dark || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
update_inv_glasses(redraw_mob)
update_inv_glasses()
update_client_colour()
if(slot_gloves)
gloves = I
update_inv_gloves(redraw_mob)
update_inv_gloves()
if(slot_head)
head = I
if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR))
update_hair(redraw_mob) //rebuild hair
update_fhair(redraw_mob)
update_head_accessory(redraw_mob)
update_hair() //rebuild hair
update_fhair()
update_head_accessory()
// paper + bandanas
if(istype(I, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = I
if(hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha))
update_sight()
head_update(I)
update_inv_head(redraw_mob)
update_inv_head()
if(slot_shoes)
shoes = I
update_inv_shoes(redraw_mob)
update_inv_shoes()
if(slot_wear_suit)
wear_suit = I
update_inv_wear_suit(redraw_mob)
update_inv_wear_suit()
if(slot_w_uniform)
w_uniform = I
update_inv_w_uniform(redraw_mob)
update_inv_w_uniform()
if(slot_l_store)
l_store = I
update_inv_pockets(redraw_mob)
update_inv_pockets()
if(slot_r_store)
r_store = I
update_inv_pockets(redraw_mob)
update_inv_pockets()
if(slot_s_store)
s_store = I
update_inv_s_store(redraw_mob)
update_inv_s_store()
if(slot_in_backpack)
if(get_active_hand() == I)
unEquip(I)
@@ -313,6 +312,11 @@
/mob/living/carbon/human/put_in_hands(obj/item/I)
if(!I)
return FALSE
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
if(S.amount == 0)
qdel(I)
return FALSE
if(put_in_active_hand(I))
return TRUE
else if(put_in_inactive_hand(I))
+269 -288
View File
@@ -1,18 +1,26 @@
/mob/living/carbon/human/Life(seconds, times_fired)
set invisibility = 0
if(notransform)
return
. = ..()
if(QDELETED(src))
return FALSE
life_tick++
voice = GetVoice()
if(..())
if(.) //not dead
if(check_mutations)
domutcheck(src,null)
update_mutations()
check_mutations=0
check_mutations = FALSE
handle_pain()
handle_heartbeat()
handle_drunk()
dna.species.handle_life(src)
if(!client)
dna.species.handle_npc(src)
@@ -24,45 +32,45 @@
if(stat == DEAD)
handle_decay()
if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle
return //We go ahead and process them 5 times for HUD images and other stuff though.
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
pulse = handle_pulse(times_fired)
if(mind && mind.vampire)
if(mind?.vampire)
mind.vampire.handle_vampire()
if(life_tick == 1)
regenerate_icons() // Make sure the inventory updates
handle_ghosted()
handle_ssd()
if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
handle_ghosted()
if(player_logged > 0 && stat != DEAD && job)
handle_ssd()
if(stat != DEAD)
return TRUE
/mob/living/carbon/human/proc/handle_ghosted()
if(player_ghosted > 0 && stat == CONSCIOUS && job && !restrained())
if(key)
player_ghosted = 0
else
player_ghosted++
if(player_ghosted % 150 == 0)
force_cryo_human(src)
if(key)
player_ghosted = 0
else
player_ghosted++
if(player_ghosted % 150 == 0)
force_cryo_human(src)
/mob/living/carbon/human/proc/handle_ssd()
if(player_logged > 0 && stat != DEAD && job)
player_logged++
if(istype(loc, /obj/machinery/cryopod))
player_logged++
if(istype(loc, /obj/machinery/cryopod))
return
if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
var/turf/T = get_turf(src)
if(!is_station_level(T.z))
return
if(config.auto_cryo_ssd_mins && (player_logged >= (config.auto_cryo_ssd_mins * 30)) && player_logged % 30 == 0)
var/turf/T = get_turf(src)
if(!is_station_level(T.z))
return
var/area/A = get_area(src)
if(cryo_ssd(src))
var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40)
P.name = "NT SSD Teleportation Portal"
if(A.fast_despawn)
force_cryo_human(src)
var/area/A = get_area(src)
if(cryo_ssd(src))
var/obj/effect/portal/P = new /obj/effect/portal(T, null, null, 40)
P.name = "NT SSD Teleportation Portal"
if(A.fast_despawn)
force_cryo_human(src)
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
@@ -80,38 +88,35 @@
/mob/living/carbon/human/handle_disabilities()
if(disabilities & EPILEPSY)
if((prob(1) && paralysis < 1))
visible_message("<span class='danger'>[src] starts having a seizure!</span>","<span class='alert'>You have a seizure!</span>")
Paralyse(10)
Jitter(1000)
//Vision //god knows why this is here
var/obj/item/organ/vision
if(dna.species.vision_organ)
vision = get_int_organ(dna.species.vision_organ)
// If we have the gene for being crazy, have random events.
if(dna.GetSEState(GLOB.hallucinationblock))
if(prob(1))
Hallucinate(20)
if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
SetEyeBlind(0)
SetEyeBlurry(0)
if(disabilities & COUGHING)
if((prob(5) && paralysis <= 1))
drop_item()
emote("cough")
if(disabilities & TOURETTES)
if((prob(10) && paralysis <= 1))
Stun(10)
switch(rand(1, 3))
if(1)
emote("twitch")
if(2 to 3)
var/tourettes = pick("SHIT", "PISS", "FUCK", "CUNT", "COCKSUCKER", "MOTHERFUCKER", "TITS")
say("[prob(50) ? ";" : ""][tourettes]")
var/x_offset = pixel_x + rand(-2,2) //Should probably be moved into the twitch emote at some point.
var/y_offset = pixel_y + rand(-1,1)
animate(src, pixel_x = pixel_x + x_offset, pixel_y = pixel_y + y_offset, time = 1)
animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y), time = 1)
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
EyeBlind(2)
EyeBlurry(2)
if(disabilities & NERVOUS)
if(prob(10))
Stuttering(10)
else
//blindness
if(BLINDNESS in mutations) // Disabled-blind, doesn't get better on its own
else if(eye_blind) // Blindness, heals slowly over time
AdjustEyeBlind(-1)
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold) && eye_blurry) //resting your eyes with a blindfold heals blurry eyes faster
AdjustEyeBlurry(-3)
//blurry sight
if(vision.is_bruised()) // Vision organs impaired? Permablurry.
EyeBlurry(2)
if(eye_blurry) // Blurry eyes heal slowly
AdjustEyeBlurry(-1)
if(getBrainLoss() >= 60 && stat != DEAD)
if(prob(3))
@@ -192,7 +197,7 @@
if(!(RADIMMUNE in dna.species.species_traits))
if(radiation)
radiation = Clamp(radiation, 0, 200)
radiation = clamp(radiation, 0, 200)
var/autopsy_damage = 0
switch(radiation)
@@ -598,17 +603,16 @@
return 0 //godmode
if(!(NO_HUNGER in dna.species.species_traits))
//The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered.
if(CAN_BE_FAT in dna.species.species_traits)
if(FAT in mutations)
if(overeatduration < 100)
becomeSlim()
else
if(overeatduration > 500)
becomeFat()
if(FAT in mutations)
if(overeatduration < 100)
becomeSlim()
else
if(overeatduration > 500)
becomeFat()
// nutrition decrease
if(nutrition > 0 && stat != DEAD)
handle_nutrition_alerts()
// THEY HUNGER
var/hunger_rate = hunger_drain
if(satiety > 0)
@@ -631,7 +635,7 @@
else
overeatduration -= 2
if(!ismachine(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs
if(!ismachineperson(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs
var/datum/disease/D = new /datum/disease/critical/hypoglycemia
ForceContractDisease(D)
@@ -658,22 +662,25 @@
AdjustSleeping(1)
Paralyse(5)
AdjustConfused(-1)
if(confused)
AdjustConfused(-1)
// decrement dizziness counter, clamped to 0
if(resting)
AdjustDizzy(-15)
AdjustJitter(-15)
if(dizziness)
AdjustDizzy(-15)
if(jitteriness)
AdjustJitter(-15)
else
AdjustDizzy(-3)
AdjustJitter(-3)
if(dizziness)
AdjustDizzy(-3)
if(jitteriness)
AdjustJitter(-3)
if(NO_INTORGANS in dna.species.species_traits)
return
handle_trace_chems()
return //TODO: DEFERRED
/mob/living/carbon/human/handle_drunk()
var/slur_start = 30 //12u ethanol, 30u whiskey FOR HUMANS
var/confused_start = 40
@@ -685,55 +692,54 @@
var/collapse_start = 75
var/braindamage_start = 120
var/alcohol_strength = drunk
var/sober_str=!(SOBER in mutations)?1:2
var/sober_str =! (SOBER in mutations) ? 1 : 2
if(drunk)
alcohol_strength/=sober_str
alcohol_strength /= sober_str
var/obj/item/organ/internal/liver/L
if(!isSynthetic())
L = get_int_organ(/obj/item/organ/internal/liver)
var/obj/item/organ/internal/liver/L
if(!ismachineperson(src))
L = get_int_organ(/obj/item/organ/internal/liver)
if(L)
alcohol_strength *= L.alcohol_intensity
else
alcohol_strength *= 5
if(alcohol_strength >= slur_start) //slurring
Slur(drunk)
if(alcohol_strength >= brawl_start) //the drunken martial art
if(!istype(martial_art, /datum/martial_art/drunk_brawling))
var/datum/martial_art/drunk_brawling/F = new
F.teach(src, 1)
if(alcohol_strength < brawl_start) //removing the art
if(istype(martial_art, /datum/martial_art/drunk_brawling))
martial_art.remove(src)
if(alcohol_strength >= confused_start && prob(33)) //confused walking
if(!confused)
Confused(1)
AdjustConfused(3 / sober_str)
if(alcohol_strength >= blur_start) //blurry eyes
EyeBlurry(10 / sober_str)
if(!ismachineperson(src)) //stuff only for non-synthetics
if(alcohol_strength >= vomit_start) //vomiting
if(prob(8))
fakevomit()
if(alcohol_strength >= pass_out)
Paralyse(5 / sober_str)
Drowsy(30 / sober_str)
if(L)
alcohol_strength *= L.alcohol_intensity
else
alcohol_strength *= 5
if(alcohol_strength >= slur_start) //slurring
Slur(drunk)
if(alcohol_strength >= brawl_start) //the drunken martial art
if(!istype(martial_art, /datum/martial_art/drunk_brawling))
var/datum/martial_art/drunk_brawling/F = new
F.teach(src,1)
if(alcohol_strength < brawl_start) //removing the art
if(istype(martial_art, /datum/martial_art/drunk_brawling))
martial_art.remove(src)
if(alcohol_strength >= confused_start && prob(33)) //confused walking
if(!confused) Confused(1)
AdjustConfused(3/sober_str)
if(alcohol_strength >= blur_start) //blurry eyes
EyeBlurry(10/sober_str)
if(!isSynthetic()) //stuff only for non-synthetics
if(alcohol_strength >= vomit_start) //vomiting
if(prob(8))
fakevomit()
if(alcohol_strength >= pass_out)
Paralyse(5/sober_str)
Drowsy(30/sober_str)
if(L)
L.receive_damage(0.1, 1)
adjustToxLoss(0.1)
else //stuff only for synthetics
if(alcohol_strength >= spark_start && prob(25))
do_sparks(3, 1, src)
if(alcohol_strength >= collapse_start && prob(10))
emote("collapse")
do_sparks(3, 1, src)
if(alcohol_strength >= braindamage_start && prob(10))
adjustBrainLoss(1)
L.receive_damage(0.1, 1)
adjustToxLoss(0.1)
else //stuff only for synthetics
if(alcohol_strength >= spark_start && prob(25))
do_sparks(3, 1, src)
if(alcohol_strength >= collapse_start && prob(10))
emote("collapse")
do_sparks(3, 1, src)
if(alcohol_strength >= braindamage_start && prob(10))
adjustBrainLoss(1)
if(!has_booze())
AdjustDrunk(-0.5)
return
/mob/living/carbon/human/proc/has_booze() //checks if the human has ethanol or its subtypes inside
for(var/A in reagents.reagent_list)
@@ -742,178 +748,154 @@
return 1
return 0
/mob/living/carbon/human/handle_regular_status_updates()
/mob/living/carbon/human/handle_critical_condition()
if(status_flags & GODMODE)
return 0
. = ..()
var/guaranteed_death_threshold = health + (getOxyLoss() * 0.5) - (getFireLoss() * 0.67) - (getBruteLoss() * 0.67)
if(.) //alive
if(REGEN in mutations)
heal_overall_damage(0.1, 0.1)
if(getBrainLoss() >= 120 || (guaranteed_death_threshold) <= -500)
death()
return
if(paralysis)
stat = UNCONSCIOUS
if(getBrainLoss() >= 100) // braindeath
AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25)
Weaken(30)
else if(sleeping)
if(!check_death_method())
if(health <= HEALTH_THRESHOLD_DEAD)
var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01)
if(prob(deathchance))
death()
return
stat = UNCONSCIOUS
if(health <= HEALTH_THRESHOLD_CRIT)
if(prob(5))
emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver"))
AdjustStuttering(5, bound_lower = 0, bound_upper = 5)
EyeBlurry(5)
if(prob(7))
AdjustConfused(2)
if(prob(5))
Paralyse(2)
switch(health)
if(-INFINITY to -100)
adjustOxyLoss(1)
if(prob(health * -0.1))
if(ishuman(src))
var/mob/living/carbon/human/H = src
H.set_heartattack(TRUE)
if(prob(health * -0.2))
var/datum/disease/D = new /datum/disease/critical/heart_failure
ForceContractDisease(D)
Paralyse(5)
if(-99 to -80)
adjustOxyLoss(1)
if(prob(4))
to_chat(src, "<span class='userdanger'>Your chest hurts...</span>")
Paralyse(2)
var/datum/disease/D = new /datum/disease/critical/heart_failure
ForceContractDisease(D)
if(-79 to -50)
adjustOxyLoss(1)
if(prob(10))
var/datum/disease/D = new /datum/disease/critical/shock
ForceContractDisease(D)
if(prob(health * -0.08))
var/datum/disease/D = new /datum/disease/critical/heart_failure
ForceContractDisease(D)
if(prob(6))
to_chat(src, "<span class='userdanger'>You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!</span>")
Weaken(3)
if(prob(3))
Paralyse(2)
if(-49 to 0)
adjustOxyLoss(1)
if(prob(3))
var/datum/disease/D = new /datum/disease/critical/shock
ForceContractDisease(D)
if(prob(5))
to_chat(src, "<span class='userdanger'>You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!</span>")
Weaken(3)
if(mind)
if(mind.vampire)
if(istype(loc, /obj/structure/closet/coffin))
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
else if(status_flags & FAKEDEATH)
stat = UNCONSCIOUS
//Vision //god knows why this is here
var/obj/item/organ/vision
if(dna.species.vision_organ)
vision = get_int_organ(dna.species.vision_organ)
if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
SetEyeBlind(0)
SetEyeBlurry(0)
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
EyeBlind(2)
EyeBlurry(2)
else
//blindness
if(disabilities & BLIND) // Disabled-blind, doesn't get better on its own
else if(eye_blind) // Blindness, heals slowly over time
AdjustEyeBlind(-1)
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
AdjustEyeBlurry(-3)
//blurry sight
if(vision.is_bruised()) // Vision organs impaired? Permablurry.
EyeBlurry(2)
if(eye_blurry) // Blurry eyes heal slowly
AdjustEyeBlurry(-1)
if(flying)
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
// If you're dirty, your gloves will become dirty, too.
if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
handle_organs()
if(getBrainLoss() >= 120 || (health + (getOxyLoss() / 2)) <= -500)
death()
return
if(getBrainLoss() >= 100) // braindeath
AdjustLoseBreath(10, bound_lower = 0, bound_upper = 25)
Weaken(30)
if(!check_death_method())
if(health <= HEALTH_THRESHOLD_DEAD)
var/deathchance = min(99, ((getBrainLoss() * -5) + (health + (getOxyLoss() / 2))) * -0.01)
if(prob(deathchance))
death()
return
if(health <= HEALTH_THRESHOLD_CRIT)
if(prob(5))
emote(pick("faint", "collapse", "cry", "moan", "gasp", "shudder", "shiver"))
AdjustStuttering(5, bound_lower = 0, bound_upper = 5)
EyeBlurry(5)
if(prob(7))
AdjustConfused(2)
if(prob(5))
Paralyse(2)
switch(health)
if(-INFINITY to -100)
adjustOxyLoss(1)
if(prob(health * -0.1))
if(ishuman(src))
var/mob/living/carbon/human/H = src
H.set_heartattack(TRUE)
if(prob(health * -0.2))
var/datum/disease/D = new /datum/disease/critical/heart_failure
ForceContractDisease(D)
Paralyse(5)
if(-99 to -80)
adjustOxyLoss(1)
if(prob(4))
to_chat(src, "<span class='userdanger'>Your chest hurts...</span>")
Paralyse(2)
var/datum/disease/D = new /datum/disease/critical/heart_failure
ForceContractDisease(D)
if(-79 to -50)
adjustOxyLoss(1)
if(prob(10))
var/datum/disease/D = new /datum/disease/critical/shock
ForceContractDisease(D)
if(prob(health * -0.08))
var/datum/disease/D = new /datum/disease/critical/heart_failure
ForceContractDisease(D)
if(prob(6))
to_chat(src, "<span class='userdanger'>You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!</span>")
Weaken(3)
if(prob(3))
Paralyse(2)
if(-49 to 0)
adjustOxyLoss(1)
if(prob(3))
var/datum/disease/D = new /datum/disease/critical/shock
ForceContractDisease(D)
if(prob(5))
to_chat(src, "<span class='userdanger'>You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!</span>")
Weaken(3)
else //dead
SetSilence(0)
/mob/living/carbon/human/handle_vision()
if(machine)
if(!machine.check_eye(src))
reset_perspective(null)
/mob/living/carbon/human/update_health_hud()
if(!client)
return
if(dna.species.update_health_hud())
return
else
var/isRemoteObserve = 0
if((REMOTE_VIEW in mutations) && remoteview_target)
isRemoteObserve = 1
if(healths)
var/health_amount = get_perceived_trauma()
if(..(health_amount)) //not dead
switch(hal_screwyhud)
if(SCREWYHUD_CRIT)
healths.icon_state = "health6"
if(SCREWYHUD_DEAD)
healths.icon_state = "health7"
if(SCREWYHUD_HEALTHY)
healths.icon_state = "health0"
if(remoteview_target.stat != CONSCIOUS)
to_chat(src, "<span class='alert'>Your psy-connection grows too faint to maintain!</span>")
isRemoteObserve = 0
if(healthdoll)
if(stat == DEAD)
healthdoll.icon_state = "healthdoll_DEAD"
if(healthdoll.overlays.len)
healthdoll.overlays.Cut()
else
var/list/new_overlays = list()
var/list/cached_overlays = healthdoll.cached_healthdoll_overlays
// Use the dead health doll as the base, since we have proper "healthy" overlays now
healthdoll.icon_state = "healthdoll_DEAD"
for(var/obj/item/organ/external/O in bodyparts)
var/damage = O.burn_dam + O.brute_dam
var/comparison = (O.max_damage/5)
var/icon_num = 0
if(damage)
icon_num = 1
if(damage > (comparison))
icon_num = 2
if(damage > (comparison*2))
icon_num = 3
if(damage > (comparison*3))
icon_num = 4
if(damage > (comparison*4))
icon_num = 5
new_overlays += "[O.limb_name][icon_num]"
healthdoll.overlays += (new_overlays - cached_overlays)
healthdoll.overlays -= (cached_overlays - new_overlays)
healthdoll.cached_healthdoll_overlays = new_overlays
if(PSY_RESIST in remoteview_target.mutations)
to_chat(src, "<span class='alert'>Your mind is shut out!</span>")
isRemoteObserve = 0
/mob/living/carbon/human/proc/handle_nutrition_alerts() //This is a terrible abuse of the alert system; something like this should be a HUD element
if(NO_HUNGER in dna.species.species_traits)
return
if(mind?.vampire && (mind in SSticker.mode.vampires)) //Vampires
switch(nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
throw_alert("nutrition", /obj/screen/alert/fat/vampire)
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
throw_alert("nutrition", /obj/screen/alert/full/vampire)
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
throw_alert("nutrition", /obj/screen/alert/fed/vampire)
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
else
throw_alert("nutrition", /obj/screen/alert/starving/vampire)
// Not on the station or mining?
var/turf/temp_turf = get_turf(remoteview_target)
if(!temp_turf in config.contact_levels)
to_chat(src, "<span class='alert'>Your psy-connection grows too faint to maintain!</span>")
isRemoteObserve = 0
if(remote_view)
isRemoteObserve = 1
if(!isRemoteObserve && client && !client.adminobs)
remoteview_target = null
reset_perspective(null)
/mob/living/carbon/human/handle_hud_icons()
dna.species.handle_hud_icons(src)
/mob/living/carbon/human/handle_hud_icons_health()
dna.species.handle_hud_icons_health(src)
handle_hud_icons_health_overlay()
else //Any other non-vampires
switch(nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
throw_alert("nutrition", /obj/screen/alert/fat)
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
throw_alert("nutrition", /obj/screen/alert/full)
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
throw_alert("nutrition", /obj/screen/alert/well_fed)
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
throw_alert("nutrition", /obj/screen/alert/fed)
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
throw_alert("nutrition", /obj/screen/alert/hungry)
else
throw_alert("nutrition", /obj/screen/alert/starving)
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
@@ -942,15 +924,14 @@
clear_alert("embeddedobject")
/mob/living/carbon/human/handle_changeling()
if(mind)
if(mind.changeling)
mind.changeling.regenerate(src)
if(hud_used)
hud_used.lingchemdisplay.invisibility = 0
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
else
if(hud_used)
hud_used.lingchemdisplay.invisibility = 101
if(mind.changeling)
mind.changeling.regenerate(src)
if(hud_used)
hud_used.lingchemdisplay.invisibility = 0
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#dd66dd'>[round(mind.changeling.chem_charges)]</font></div>"
else
if(hud_used)
hud_used.lingchemdisplay.invisibility = 101
/mob/living/carbon/human/proc/handle_pulse(times_fired)
@@ -1123,4 +1104,4 @@
// Need this in species.
//#undef HUMAN_MAX_OXYLOSS
//#undef HUMAN_CRIT_MAX_OXYLOSS
//#undef HUMAN_CRIT_MAX_OXYLOSS
+1 -1
View File
@@ -7,7 +7,7 @@
species_exception = list(/datum/species/monkey)
/mob/living/carbon/human/monkey/punpun/Initialize(mapload)
..()
. = ..()
name = "Pun Pun"
real_name = name
equip_to_slot(new /obj/item/clothing/under/punpun(src), slot_w_uniform)
+2 -4
View File
@@ -134,11 +134,9 @@
S.message = "<span class='[span]'>[S.message]</span>"
verb = translator.speech_verb
return list("verb" = verb)
if(mind)
span = mind.speech_span
if((COMIC in mutations) \
|| (locate(/obj/item/organ/internal/cyberimp/brain/clown_voice) in internal_organs) \
|| GetComponent(/datum/component/jestosterone))
|| HAS_TRAIT(src, TRAIT_JESTER))
span = "sans"
if(WINGDINGS in mutations)
@@ -151,7 +149,7 @@
if(S.speaking && S.speaking.flags & NO_STUTTER)
continue
if(silent || (disabilities & MUTE))
if(silent || (MUTE in mutations))
S.message = ""
if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
@@ -53,7 +53,6 @@
var/stun_mod = 1 // If a species is more/less impacated by stuns/weakens/paralysis
var/speed_mod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
var/blood_damage_type = OXY //What type of damage does this species take if it's low on blood?
var/obj/item/mutanthands
var/total_health = 100
var/punchdamagelow = 0 //lowest possible punch damage
var/punchdamagehigh = 9 //highest possible punch damage
@@ -84,6 +83,7 @@
var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs
var/remains_type = /obj/effect/decal/remains/human //What sort of remains is left behind when the species dusts
var/base_color //Used when setting species.
var/list/inherent_factions
//Used in icon caching.
var/race_key = 0
@@ -272,8 +272,6 @@
if(H.status_flags & GOTTAGOFAST)
. -= 1
if(H.status_flags & GOTTAGOFAST_METH)
. -= 1
return .
/datum/species/proc/on_species_gain(mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
@@ -285,11 +283,19 @@
H.hud_used.update_locked_slots()
H.ventcrawler = ventcrawler
if(inherent_factions)
for(var/i in inherent_factions)
H.faction += i //Using +=/-= for this in case you also gain the faction from a different source.
/datum/species/proc/on_species_loss(mob/living/carbon/human/H)
if(H.butcher_results) //clear it out so we don't butcher a actual human.
H.butcher_results = null
H.ventcrawler = initial(H.ventcrawler)
if(inherent_factions)
for(var/i in inherent_factions)
H.faction -= i
/datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors.
return
@@ -339,30 +345,17 @@
switch(damagetype)
if(BRUTE)
H.damageoverlaytemp = 20
damage = damage * brute_mod
if(damage)
H.damageoverlaytemp = 20
if(organ.receive_damage(damage, 0, sharp, used_weapon))
H.UpdateDamageIcon()
if(H.LAssailant && ishuman(H.LAssailant)) //superheros still get the comical hit markers
var/mob/living/carbon/human/A = H.LAssailant
if(A.mind && A.mind in (SSticker.mode.superheroes || SSticker.mode.supervillains || SSticker.mode.greyshirts))
var/list/attack_bubble_recipients = list()
var/mob/living/user
for(var/mob/O in viewers(user, src))
if(O.client && O.has_vision(information_only=TRUE))
attack_bubble_recipients.Add(O.client)
spawn(0)
var/image/dmgIcon = image('icons/effects/hit_blips.dmi', src, "dmg[rand(1,2)]",MOB_LAYER+1)
dmgIcon.pixel_x = (!H.lying) ? rand(-3,3) : rand(-11,12)
dmgIcon.pixel_y = (!H.lying) ? rand(-11,9) : rand(-10,1)
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
if(BURN)
H.damageoverlaytemp = 20
damage = damage * burn_mod
if(damage)
H.damageoverlaytemp = 20
if(organ.receive_damage(0, damage, sharp, used_weapon))
H.UpdateDamageIcon()
@@ -436,6 +429,9 @@
else
target.LAssailant = user
target.lastattacker = user.real_name
target.lastattackerckey = user.ckey
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
damage += attack.damage
if(!damage)
@@ -609,13 +605,6 @@
if(!H.has_organ_for_slot(slot))
return FALSE
if(istype(I, /obj/item/clothing/under) || istype(I, /obj/item/clothing/suit))
if(FAT in H.mutations)
if(!(I.flags_size & ONESIZEFITSALL))
if(!disable_warning)
to_chat(H, "<span class='alert'>You're too fat to wear the [I].</span>")
return FALSE
switch(slot)
if(slot_l_hand)
return !H.l_hand && !H.incapacitated()
@@ -754,105 +743,8 @@
return FALSE //Unsupported slot
/datum/species/proc/get_perceived_trauma(mob/living/carbon/human/H)
return min(H.health, H.maxHealth - H.getStaminaLoss())
/datum/species/proc/handle_hud_icons(mob/living/carbon/human/H)
if(!H.client)
return
handle_hud_icons_health(H)
H.handle_hud_icons_health_overlay()
handle_hud_icons_nutrition(H)
/datum/species/proc/handle_hud_icons_health(mob/living/carbon/H)
if(!H.client)
return
handle_hud_icons_health_side(H)
handle_hud_icons_health_doll(H)
/datum/species/proc/handle_hud_icons_health_side(mob/living/carbon/human/H)
if(H.healths)
if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
H.healths.icon_state = "health7"
else
switch(H.hal_screwyhud)
if(SCREWYHUD_CRIT) H.healths.icon_state = "health6"
if(SCREWYHUD_DEAD) H.healths.icon_state = "health7"
if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0"
else
switch(get_perceived_trauma(H))
if(100 to INFINITY) H.healths.icon_state = "health0"
if(80 to 100) H.healths.icon_state = "health1"
if(60 to 80) H.healths.icon_state = "health2"
if(40 to 60) H.healths.icon_state = "health3"
if(20 to 40) H.healths.icon_state = "health4"
if(0 to 20) H.healths.icon_state = "health5"
else H.healths.icon_state = "health6"
/datum/species/proc/handle_hud_icons_health_doll(mob/living/carbon/human/H)
if(H.healthdoll)
if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
H.healthdoll.icon_state = "healthdoll_DEAD"
if(H.healthdoll.overlays.len)
H.healthdoll.overlays.Cut()
else
var/list/new_overlays = list()
var/list/cached_overlays = H.healthdoll.cached_healthdoll_overlays
// Use the dead health doll as the base, since we have proper "healthy" overlays now
H.healthdoll.icon_state = "healthdoll_DEAD"
for(var/obj/item/organ/external/O in H.bodyparts)
var/damage = O.burn_dam + O.brute_dam
var/comparison = (O.max_damage/5)
var/icon_num = 0
if(damage)
icon_num = 1
if(damage > (comparison))
icon_num = 2
if(damage > (comparison*2))
icon_num = 3
if(damage > (comparison*3))
icon_num = 4
if(damage > (comparison*4))
icon_num = 5
new_overlays += "[O.limb_name][icon_num]"
H.healthdoll.overlays += (new_overlays - cached_overlays)
H.healthdoll.overlays -= (cached_overlays - new_overlays)
H.healthdoll.cached_healthdoll_overlays = new_overlays
/datum/species/proc/handle_hud_icons_nutrition(mob/living/carbon/human/H)
if(NO_HUNGER in species_traits)
return FALSE
if(H.mind && H.mind.vampire && (H.mind in SSticker.mode.vampires)) //Vampires
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
H.throw_alert("nutrition", /obj/screen/alert/fat/vampire)
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
H.throw_alert("nutrition", /obj/screen/alert/full/vampire)
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
H.throw_alert("nutrition", /obj/screen/alert/well_fed/vampire)
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
H.throw_alert("nutrition", /obj/screen/alert/fed/vampire)
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
H.throw_alert("nutrition", /obj/screen/alert/hungry/vampire)
else
H.throw_alert("nutrition", /obj/screen/alert/starving/vampire)
return 1
else ///Any other non-vampires
switch(H.nutrition)
if(NUTRITION_LEVEL_FULL to INFINITY)
H.throw_alert("nutrition", /obj/screen/alert/fat)
if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL)
H.throw_alert("nutrition", /obj/screen/alert/full)
if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED)
H.throw_alert("nutrition", /obj/screen/alert/well_fed)
if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED)
H.throw_alert("nutrition", /obj/screen/alert/fed)
if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
H.throw_alert("nutrition", /obj/screen/alert/hungry)
else
H.throw_alert("nutrition", /obj/screen/alert/starving)
return 1
/datum/species/proc/update_health_hud(mob/living/carbon/human/H)
return FALSE
/*
Returns the path corresponding to the corresponding organ
@@ -963,7 +855,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
/datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/organ/external/affecting, intent, mob/living/carbon/human/H)
/proc/get_random_species(species_name = FALSE) // Returns a random non black-listed or hazardous species, either as a string or datum
var/static/list/random_species = list()
@@ -108,13 +108,4 @@
/datum/species/diona/pod //Same name and everything; we want the same limitations on them; we just want their regeneration to kick in at all times and them to have special factions
pod = TRUE
/datum/species/diona/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
C.faction |= "plants"
C.faction |= "vines"
/datum/species/diona/pod/on_species_loss(mob/living/carbon/C)
. = ..()
C.faction -= "plants"
C.faction -= "vines"
inherent_factions = list("plants", "vines")
@@ -474,7 +474,7 @@
if(P.is_reflectable)
H.visible_message("<span class='danger'>The [P.name] gets reflected by [H]'s glass skin!</span>", \
"<span class='userdanger'>The [P.name] gets reflected by [H]'s glass skin!</span>")
P.reflect_back(H)
return FALSE
@@ -534,7 +534,7 @@
if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP)
reactive_teleport(H)
/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/organ/external/affecting, intent, mob/living/carbon/human/H)
..()
if(world.time > last_teleport + teleport_cooldown && user != H)
reactive_teleport(H)
@@ -636,12 +636,11 @@
H.mutations.Add(COMIC)
H.equip_to_slot_or_del(new /obj/item/reagent_containers/food/drinks/bottle/bottleofbanana(H), slot_r_store)
H.equip_to_slot_or_del(new /obj/item/bikehorn(H), slot_l_store)
H.AddComponent(/datum/component/waddling)
H.AddElement(/datum/element/waddling)
/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C)
. = ..()
GET_COMPONENT_FROM(waddling, /datum/component/waddling, C)
waddling.Destroy()
C.RemoveElement(/datum/element/waddling)
/datum/species/golem/bananium/get_random_name()
var/clown_name = pick(GLOB.clown_names)
@@ -654,7 +653,7 @@
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
last_banana = world.time
/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/organ/external/affecting, intent, mob/living/carbon/human/H)
..()
if(world.time > last_banana + banana_cooldown && user != H)
new/obj/item/grown/bananapeel/specialpeel(get_turf(H))
@@ -21,7 +21,7 @@
default_genes = list(REMOTE_TALK)
species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT, CAN_WINGDINGS)
species_traits = list(LIPS, IS_WHITELISTED, CAN_WINGDINGS)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_BODY_MARKINGS
dietflags = DIET_HERB
@@ -5,7 +5,7 @@
deform = 'icons/mob/human_races/r_def_human.dmi'
primitive_form = /datum/species/monkey
language = "Sol Common"
species_traits = list(LIPS, CAN_BE_FAT)
species_traits = list(LIPS)
skinned_type = /obj/item/stack/sheet/animalhide/human
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS
@@ -18,4 +18,4 @@
reagent_tag = PROCESS_ORG
//Has standard darksight of 2.
@@ -121,7 +121,7 @@
return
if(!robohead.is_monitor) //If they've got a prosthetic head and it isn't a monitor, they've no screen to adjust. Instead, let them change the colour of their optics!
var/optic_colour = input(H, "Select optic colour", H.m_colours["head"]) as color|null
if(H.incapacitated())
if(H.incapacitated(TRUE, TRUE, TRUE))
to_chat(H, "<span class='warning'>You were interrupted while changing the colour of your optics.</span>")
return
if(optic_colour)
@@ -149,7 +149,7 @@
var/new_style = input(H, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair
var/new_color = input("Please select hair color.", "Monitor Color", head_organ.hair_colour) as null|color
if(H.incapacitated())
if(H.incapacitated(TRUE, TRUE, TRUE))
to_chat(H, "<span class='warning'>You were interrupted while changing your monitor display.</span>")
return
@@ -18,6 +18,7 @@
is_small = 1
has_fine_manipulation = 0
ventcrawler = VENTCRAWLER_NUDE
dietflags = DIET_OMNI
show_ssd = 0
eyes = "blank_eyes"
death_message = "lets out a faint chimper as it collapses and stops moving..."
@@ -5,6 +5,7 @@
icobase = 'icons/mob/human_races/r_shadow.dmi'
deform = 'icons/mob/human_races/r_shadow.dmi'
dangerous_existence = TRUE
inherent_factions = list("faithless")
unarmed_type = /datum/unarmed_attack/claws
@@ -38,10 +39,10 @@
/datum/action/innate/shadow/darkvision/Activate()
var/mob/living/carbon/human/H = owner
if(!H.vision_type)
H.vision_type = new /datum/vision_override/nightvision
H.set_sight(/datum/vision_override/nightvision)
to_chat(H, "<span class='notice'>You adjust your vision to pierce the darkness.</span>")
else
H.vision_type = null
H.set_sight(null)
to_chat(H, "<span class='notice'>You adjust your vision to recognize the shadows.</span>")
/datum/species/shadow/on_species_gain(mob/living/carbon/human/H)
@@ -49,14 +50,12 @@
if(grant_vision_toggle)
vision_toggle = new
vision_toggle.Grant(H)
H.faction |= "faithless"
/datum/species/shadow/on_species_loss(mob/living/carbon/human/H)
..()
if(grant_vision_toggle && vision_toggle)
H.vision_type = null
vision_toggle.Remove(H)
H.faction -= "faithless"
/datum/species/shadow/handle_life(mob/living/carbon/human/H)
var/light_amount = 0
@@ -13,6 +13,7 @@
icobase = 'icons/mob/human_races/r_slime.dmi'
deform = 'icons/mob/human_races/r_slime.dmi'
remains_type = /obj/effect/decal/remains/slime
inherent_factions = list("slime")
// More sensitive to the cold
cold_level_1 = 280
@@ -94,7 +95,7 @@
var/obj/item/organ/external/E = H.bodyparts_by_name[organname]
if(istype(E) && E.dna && istype(E.dna.species, /datum/species/slime))
E.sync_colour_to_human(H)
H.update_hair(0)
H.update_hair()
H.update_body()
..()
@@ -198,4 +199,4 @@
#undef SLIMEPERSON_HUNGERCOST
#undef SLIMEPERSON_MINHUNGER
#undef SLIMEPERSON_REGROWTHDELAY
#undef SLIMEPERSON_REGROWTHDELAY
@@ -24,7 +24,7 @@
primitive_form = /datum/species/monkey/tajaran
species_traits = list(LIPS, CAN_BE_FAT)
species_traits = list(LIPS)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
dietflags = DIET_OMNI
@@ -56,4 +56,4 @@
"is holding their breath!")
/datum/species/tajaran/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging(1)
H.stop_tail_wagging()
@@ -104,7 +104,7 @@
return
/datum/species/unathi/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging(1)
H.stop_tail_wagging()
/datum/species/unathi/ashwalker
name = "Ash Walker"
@@ -76,7 +76,7 @@
speciesbox = /obj/item/storage/box/survival_vox
/datum/species/vox/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging(1)
H.stop_tail_wagging()
/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H)
if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime")
@@ -50,4 +50,4 @@
"is holding their breath!")
/datum/species/vulpkanin/handle_death(gibbed, mob/living/carbon/human/H)
H.stop_tail_wagging(1)
H.stop_tail_wagging()
@@ -50,7 +50,7 @@
/datum/species/wryn/handle_death(gibbed, mob/living/carbon/human/H)
for(var/mob/living/carbon/C in GLOB.living_mob_list)
for(var/mob/living/carbon/C in GLOB.alive_mob_list)
if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode))
to_chat(C, "<span class='danger'><B>Your antennae tingle as you are overcome with pain...</B></span>")
to_chat(C, "<span class='danger'>It feels like part of you has died.</span>") // This is bullshit
@@ -1,102 +0,0 @@
#define REGENERATION_DELAY 60 // After taking damage, how long it takes for automatic regeneration to begin
/datum/species/zombie
// 1spooky
name = "High-Functioning Zombie"
name_plural = "High-Functioning Zombies"
icobase = 'icons/mob/human_races/r_zombie.dmi'
deform = 'icons/mob/human_races/r_def_zombie.dmi'
dies_at_threshold = TRUE
language = "Zombie"
species_traits = list(NO_BLOOD, NOZOMBIE, NOTRANSSTING, NO_BREATHE, RADIMMUNE, NO_SCAN)
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
warning_low_pressure = -1
hazard_low_pressure = -1
hazard_high_pressure = 999999999
warning_high_pressure = 999999999
cold_level_1 = -1
cold_level_2 = -1
cold_level_3 = -1
tox_mod = 0
flesh_color = "#00FF00" // for green examine text
bodyflags = HAS_SKIN_COLOR
dietflags = DIET_CARN
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes,
"ears" = /obj/item/organ/internal/ears)
/datum/species/zombie/infectious
name = "Infectious Zombie"
mutanthands = /obj/item/zombie_hand
icobase = 'icons/mob/human_races/r_zombie.dmi'
deform = 'icons/mob/human_races/r_def_zombie.dmi'
brute_mod = 0.8 // 120 damage to KO a zombie, which kills it
burn_mod = 0.8
clone_mod = 0.8
brain_mod = 0.8
stamina_mod = 0.8
speed_mod = 1.6
default_language = "Zombie"
var/heal_rate = 1
var/regen_cooldown = 0
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H, amount)
. = min(20, amount)
/datum/species/zombie/infectious/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, sharp = 0, obj/used_weapon = null)
. = ..()
if(damage)
regen_cooldown = world.time + REGENERATION_DELAY
/datum/species/zombie/infectious/handle_life(mob/living/carbon/human/H)
. = ..()
H.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
//Zombies never actually die, they just fall down until they regenerate enough to rise back up.
//They must be restrained, beheaded or gibbed to stop being a threat.
if(regen_cooldown < world.time)
var/heal_amt = heal_rate
if(H.InCritical())
heal_amt *= 2
H.heal_overall_damage(heal_amt,heal_amt)
H.adjustToxLoss(-heal_amt)
if(!H.InCritical() && prob(4))
playsound(H, pick(spooks), 50, TRUE, 10)
//Congrats you somehow died so hard you stopped being a zombie
/datum/species/zombie/infectious/handle_death(gibbed, mob/living/carbon/C)
. = ..()
var/obj/item/organ/internal/zombie_infection/infection
infection = C.get_organ_slot("zombie_infection")
if(infection)
qdel(infection)
/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
. = ..()
// Deal with the source of this zombie corruption
// Infection organ needs to be handled separately from mutant_organs
// because it persists through species transitions
if(mutanthands)
H.drop_l_hand()
H.drop_r_hand()
H.put_in_hands(new mutanthands())
H.put_in_hands(new mutanthands())
var/obj/item/organ/internal/zombie_infection/infection
infection = H.get_organ_slot("zombie_infection")
if(!infection)
infection = new()
infection.insert(H)
/datum/species/zombie/infectious/on_species_loss(mob/living/carbon/human/C, datum/species/old_species)
QDEL_NULL(C.r_hand)
QDEL_NULL(C.l_hand)
return ..()
#undef REGENERATION_DELAY
@@ -1,8 +1,8 @@
/*
Global associative list for caching humanoid icons.
Index format m or f, followed by a string of 0 and 1 to represent bodyparts followed by husk fat hulk skeleton 1 or 0.
Index format m or f, followed by a string of 0 and 1 to represent bodyparts followed by husk hulk skeleton 1 or 0.
TODO: Proper documentation
icon_key is [species.race_key][g][husk][fat][hulk][skeleton][s_tone]
icon_key is [species.race_key][g][husk][hulk][skeleton][s_tone]
*/
GLOBAL_LIST_EMPTY(human_icon_cache)
@@ -77,14 +77,14 @@ There are several things that need to be remembered:
If you wish to update several overlays at once, you can set the argument to 0 to disable the update and call
it manually:
e.g.
update_inv_head(0)
update_inv_l_hand(0)
update_inv_head()
update_inv_l_hand()
update_inv_r_hand() //<---calls update_icons()
or equivillantly:
update_inv_head(0)
update_inv_l_hand(0)
update_inv_r_hand(0)
update_inv_head()
update_inv_l_hand()
update_inv_r_hand()
update_icons()
> If you need to update all overlays you can use regenerate_icons(). it works exactly like update_clothing used to.
@@ -124,7 +124,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1)
/mob/living/carbon/human/UpdateDamageIcon()
// first check whether something actually changed about damage appearance
var/damage_appearance = ""
@@ -164,7 +164,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(var/update_icons=1, var/rebuild_base=0)
/mob/living/carbon/human/proc/update_body(rebuild_base = FALSE)
remove_overlay(BODY_LAYER)
remove_overlay(LIMBS_LAYER) // So we don't get the old species' sprite splatted on top of the new one's
remove_overlay(UNDERWEAR_LAYER)
@@ -273,27 +273,27 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[UNDERWEAR_LAYER] = mutable_appearance(underwear_standing, layer = -UNDERWEAR_LAYER)
apply_overlay(UNDERWEAR_LAYER)
if(lip_style && (LIPS in dna.species.species_traits))
var/icon/lips = icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "lips_[lip_style]_s")
lips.Blend(lip_color, ICON_ADD)
standing += mutable_appearance(lips, layer = -BODY_LAYER)
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lips = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]_s")
lips.color = lip_color
standing += lips
overlays_standing[BODY_LAYER] = standing
apply_overlay(BODY_LAYER)
//tail
update_tail_layer(0)
update_tail_layer()
update_int_organs()
//head accessory
update_head_accessory(0)
update_head_accessory()
//markings
update_markings(0)
update_markings()
//hair
update_hair(0)
update_fhair(0)
update_hair()
update_fhair()
//MARKINGS OVERLAY
/mob/living/carbon/human/proc/update_markings(var/update_icons=1)
/mob/living/carbon/human/proc/update_markings()
//Reset our markings.
remove_overlay(MARKINGS_LAYER)
@@ -325,7 +325,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(MARKINGS_LAYER)
//HEAD ACCESSORY OVERLAY
/mob/living/carbon/human/proc/update_head_accessory(var/update_icons=1)
/mob/living/carbon/human/proc/update_head_accessory()
//Reset our head accessory
remove_overlay(HEAD_ACCESSORY_LAYER)
remove_overlay(HEAD_ACC_OVER_LAYER)
@@ -362,7 +362,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//HAIR OVERLAY
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
/mob/living/carbon/human/proc/update_hair()
//Reset our hair
remove_overlay(HAIR_LAYER)
@@ -376,7 +376,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//base icons
var/icon/hair_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(ismachineperson(src))))
var/datum/sprite_accessory/hair/hair_style = GLOB.hair_styles_full_list[head_organ.h_style]
if(hair_style && hair_style.species_allowed)
if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
@@ -403,7 +403,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//FACIAL HAIR OVERLAY
/mob/living/carbon/human/proc/update_fhair(var/update_icons=1)
/mob/living/carbon/human/proc/update_fhair()
//Reset our facial hair
remove_overlay(FHAIR_LAYER)
remove_overlay(FHAIR_OVER_LAYER)
@@ -447,12 +447,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
/mob/living/carbon/human/update_mutations(var/update_icons=1)
/mob/living/carbon/human/update_mutations()
remove_overlay(MUTATIONS_LAYER)
var/fat
if(FAT in mutations)
fat = "fat"
var/mutable_appearance/standing = mutable_appearance('icons/effects/genetics.dmi', layer = -MUTATIONS_LAYER)
var/add_image = 0
var/g = "m"
@@ -463,7 +459,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
if(!gene.block)
continue
if(gene.is_active(src))
var/underlay = gene.OnDrawUnderlays(src, g, fat)
var/underlay = gene.OnDrawUnderlays(src, g)
if(underlay)
standing.underlays += underlay
add_image = 1
@@ -473,16 +469,16 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
standing.overlays += "lasereyes_s"
add_image = 1
if((COLDRES in mutations) && (HEATRES in mutations))
standing.underlays -= "cold[fat]_s"
standing.underlays -= "fire[fat]_s"
standing.underlays += "coldfire[fat]_s"
standing.underlays -= "cold_s"
standing.underlays -= "fire_s"
standing.underlays += "coldfire_s"
if(add_image)
overlays_standing[MUTATIONS_LAYER] = standing
apply_overlay(MUTATIONS_LAYER)
/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1)
/mob/living/carbon/human/proc/update_mutantrace()
//BS12 EDIT
var/skel = (SKELETON in mutations)
if(skel)
@@ -490,8 +486,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
else
skeleton = null
update_hair(0)
update_fhair(0)
update_hair()
update_fhair()
/mob/living/carbon/human/update_fire()
@@ -505,41 +501,42 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
..()
if(notransform) return
update_mutations(0)
update_body(0, 1) //Update the body and force limb icon regeneration.
update_hair(0)
update_head_accessory(0)
update_fhair(0)
update_mutantrace(0)
update_inv_w_uniform(0,0)
update_inv_wear_id(0)
update_inv_gloves(0,0)
update_inv_glasses(0)
update_inv_ears(0)
update_inv_shoes(0,0)
update_inv_s_store(0)
update_inv_wear_mask(0)
update_inv_head(0,0)
update_inv_belt(0)
update_inv_back(0)
update_inv_wear_suit(0)
update_inv_r_hand(0)
update_inv_l_hand(0)
update_inv_handcuffed(0)
update_inv_legcuffed(0)
update_inv_pockets(0)
update_inv_wear_pda(0)
UpdateDamageIcon(0)
if(notransform)
return
update_mutations()
update_body(TRUE) //Update the body and force limb icon regeneration.
update_hair()
update_head_accessory()
update_fhair()
update_mutantrace()
update_inv_w_uniform()
update_inv_wear_id()
update_inv_gloves()
update_inv_glasses()
update_inv_ears()
update_inv_shoes()
update_inv_s_store()
update_inv_wear_mask()
update_inv_head()
update_inv_belt()
update_inv_back()
update_inv_wear_suit()
update_inv_r_hand()
update_inv_l_hand()
update_inv_handcuffed()
update_inv_legcuffed()
update_inv_pockets()
update_inv_wear_pda()
UpdateDamageIcon()
force_update_limbs()
update_tail_layer(0)
update_tail_layer()
overlays.Cut() // Force all overlays to regenerate
update_fire()
update_icons()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1)
/mob/living/carbon/human/update_inv_w_uniform()
remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_w_uniform]
@@ -557,13 +554,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
t_color = icon_state
var/mutable_appearance/standing = mutable_appearance('icons/mob/uniform.dmi', "[t_color]_s", layer = -UNIFORM_LAYER)
if(FAT in mutations)
if(w_uniform.flags_size & ONESIZEFITSALL)
standing.icon = 'icons/mob/uniform_fat.dmi'
else
to_chat(src, "<span class='warning'>You burst out of \the [w_uniform]!</span>")
unEquip(w_uniform)
return
if(w_uniform.icon_override)
standing.icon = w_uniform.icon_override
@@ -575,7 +565,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. // oh my god kys whoever made this if statement jfc :gun:
if(w_uniform.accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. // oh my god kys whoever made this if statement jfc :gun:
for(var/obj/item/clothing/accessory/A in w_uniform:accessories)
var/tie_color = A.item_color
if(!tie_color)
@@ -604,7 +594,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
thing.plane = initial(thing.plane)
apply_overlay(UNIFORM_LAYER)
/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1)
/mob/living/carbon/human/update_inv_wear_id()
remove_overlay(ID_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_id]
@@ -620,7 +610,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[ID_LAYER] = mutable_appearance('icons/mob/mob.dmi', "id", layer = -ID_LAYER)
apply_overlay(ID_LAYER)
/mob/living/carbon/human/update_inv_gloves(var/update_icons=1)
/mob/living/carbon/human/update_inv_gloves()
remove_overlay(GLOVES_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
@@ -657,7 +647,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(GLOVES_LAYER)
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
/mob/living/carbon/human/update_inv_glasses()
remove_overlay(GLASSES_LAYER)
remove_overlay(GLASSES_OVER_LAYER)
remove_overlay(OVER_MASK_LAYER)
@@ -698,7 +688,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
update_misc_effects()
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
/mob/living/carbon/human/update_inv_ears()
remove_overlay(EARS_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_l_ear]
@@ -746,7 +736,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER)
apply_overlay(EARS_LAYER)
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
/mob/living/carbon/human/update_inv_shoes()
remove_overlay(SHOES_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_shoes]
@@ -782,7 +772,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[SHOES_LAYER] = bloodsies
apply_overlay(SHOES_LAYER)
/mob/living/carbon/human/update_inv_s_store(var/update_icons=1)
/mob/living/carbon/human/update_inv_s_store()
remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_s_store]
@@ -803,7 +793,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(SUIT_STORE_LAYER)
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
/mob/living/carbon/human/update_inv_head()
..()
remove_overlay(HEAD_LAYER)
if(client && hud_used)
@@ -829,7 +819,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[HEAD_LAYER] = standing
apply_overlay(HEAD_LAYER)
/mob/living/carbon/human/update_inv_belt(var/update_icons=1)
/mob/living/carbon/human/update_inv_belt()
remove_overlay(BELT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt]
@@ -855,7 +845,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(BELT_LAYER)
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
/mob/living/carbon/human/update_inv_wear_suit()
remove_overlay(SUIT_LAYER)
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_suit]
@@ -873,13 +863,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
standing = mutable_appearance(wear_suit.icon_override, "[wear_suit.icon_state]", layer = -SUIT_LAYER)
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name])
standing = mutable_appearance(wear_suit.sprite_sheets[dna.species.name], "[wear_suit.icon_state]", layer = -SUIT_LAYER)
else if(FAT in mutations)
if(wear_suit.flags_size & ONESIZEFITSALL)
standing = mutable_appearance('icons/mob/suit_fat.dmi', "[wear_suit.icon_state]", layer = -SUIT_LAYER)
else
to_chat(src, "<span class='warning'>You burst out of \the [wear_suit]!</span>")
unEquip(wear_suit)
return
else
standing = mutable_appearance('icons/mob/suit.dmi', "[wear_suit.icon_state]", layer = -SUIT_LAYER)
@@ -903,8 +886,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[SUIT_LAYER] = standing
apply_overlay(SUIT_LAYER)
update_tail_layer(0)
update_collar(0)
update_tail_layer()
update_collar()
/mob/living/carbon/human/update_inv_pockets()
if(client && hud_used)
@@ -937,7 +920,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
client.screen += wear_pda
wear_pda.screen_loc = ui_pda
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons = 1)
/mob/living/carbon/human/update_inv_wear_mask()
..()
remove_overlay(FACEMASK_LAYER)
if(client && hud_used)
@@ -973,7 +956,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(FACEMASK_LAYER)
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
/mob/living/carbon/human/update_inv_back()
..()
remove_overlay(BACK_LAYER)
if(back)
@@ -996,7 +979,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[BACK_LAYER] = standing
apply_overlay(BACK_LAYER)
/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
/mob/living/carbon/human/update_inv_handcuffed()
remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
if(istype(handcuffed, /obj/item/restraints/handcuffs/pinkcuffs))
@@ -1005,7 +988,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
overlays_standing[HANDCUFF_LAYER] = mutable_appearance('icons/mob/mob.dmi', "handcuff1", layer = -HANDCUFF_LAYER)
apply_overlay(HANDCUFF_LAYER)
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
/mob/living/carbon/human/update_inv_legcuffed()
remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
@@ -1018,7 +1001,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(LEGCUFF_LAYER)
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
/mob/living/carbon/human/update_inv_r_hand()
..()
remove_overlay(R_HAND_LAYER)
if(r_hand)
@@ -1037,7 +1020,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(R_HAND_LAYER)
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
/mob/living/carbon/human/update_inv_l_hand()
..()
remove_overlay(L_HAND_LAYER)
if(l_hand)
@@ -1078,7 +1061,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
client.screen += I
/mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1)
/mob/living/carbon/human/proc/update_tail_layer()
remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER.
remove_overlay(TAIL_LAYER) /* This will be one of two things:
If the species' tail is overlapped by limbs, this will be only the N direction icon so tails
@@ -1153,7 +1136,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(TAIL_LAYER)
apply_overlay(TAIL_UNDERLIMBS_LAYER)
/mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1)
/mob/living/carbon/human/proc/start_tail_wagging()
remove_overlay(TAIL_UNDERLIMBS_LAYER) // SEW direction icons, overlayed by LIMBS_LAYER.
remove_overlay(TAIL_LAYER) /* This will be one of two things:
If the species' tail is overlapped by limbs, this will be only the N direction icon so tails
@@ -1229,10 +1212,10 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(TAIL_LAYER)
apply_overlay(TAIL_UNDERLIMBS_LAYER)
/mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1)
/mob/living/carbon/human/proc/stop_tail_wagging()
remove_overlay(TAIL_UNDERLIMBS_LAYER)
remove_overlay(TAIL_LAYER)
update_tail_layer(update_icons) //just trigger a full update for normal stationary sprites
update_tail_layer() //just trigger a full update for normal stationary sprites
/mob/living/carbon/human/proc/update_int_organs()
remove_overlay(INTORGAN_LAYER)
@@ -1254,7 +1237,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
//Adds a collar overlay above the helmet layer if the suit has one
// Suit needs an identically named sprite in icons/mob/collar.dmi
// For suits with sprite_sheets, an identically named sprite needs to exist in a file like this icons/mob/species/[species_name_here]/collar.dmi.
/mob/living/carbon/human/proc/update_collar(var/update_icons=1)
/mob/living/carbon/human/proc/update_collar()
remove_overlay(COLLAR_LAYER)
var/icon/C = new('icons/mob/collar.dmi')
var/mutable_appearance/standing = null
@@ -1290,20 +1273,17 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
apply_overlay(MISC_LAYER)
/mob/living/carbon/human/admin_Freeze(client/admin, skip_overlays = TRUE)
. = ..()
overlays_standing[FROZEN_LAYER] = mutable_appearance(frozen, layer = -FROZEN_LAYER)
apply_overlay(FROZEN_LAYER)
/mob/living/carbon/human/admin_unFreeze(client/admin, skip_overlays = TRUE)
. = ..()
remove_overlay(FROZEN_LAYER)
/mob/living/carbon/human/admin_Freeze(client/admin, skip_overlays = TRUE, mech = null)
if(..())
overlays_standing[FROZEN_LAYER] = mutable_appearance(frozen, layer = -FROZEN_LAYER)
apply_overlay(FROZEN_LAYER)
else
remove_overlay(FROZEN_LAYER)
/mob/living/carbon/human/proc/force_update_limbs()
for(var/obj/item/organ/external/O in bodyparts)
O.sync_colour_to_human(src)
update_body(0)
update_body()
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
var/list/out = new
@@ -1316,7 +1296,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
/mob/living/carbon/human/proc/generate_icon_render_key()
var/husk = (HUSK in mutations)
var/fat = (FAT in mutations)
var/hulk = (HULK in mutations)
var/skeleton = (SKELETON in mutations)
@@ -1349,4 +1328,4 @@ GLOBAL_LIST_EMPTY(damage_icon_parts)
if(part.s_tone)
. += "[part.s_tone]"
. = "[.][!!husk][!!fat][!!hulk][!!skeleton]"
. = "[.][!!husk][!!hulk][!!skeleton]"
@@ -12,7 +12,7 @@
/mob/living/carbon/human/update_nearsighted_effects()
var/obj/item/clothing/glasses/G = glasses
if((disabilities & NEARSIGHTED) && (!istype(G) || !G.prescription))
if((NEARSIGHTED in mutations) && (!istype(G) || !G.prescription))
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
else
clear_fullscreen("nearsighted")
+104 -55
View File
@@ -1,24 +1,39 @@
/mob/living/carbon/Life(seconds, times_fired)
set invisibility = 0
set background = BACKGROUND_ENABLED
if(notransform)
return
if(!loc)
if(damageoverlaytemp)
damageoverlaytemp = 0
update_damage_hud()
if(stat != DEAD)
handle_organs()
//stuff in the stomach
if(LAZYLEN(stomach_contents))
handle_stomach(times_fired)
. = ..()
if(QDELETED(src))
return
if(..())
. = 1
if(.) //not dead
handle_blood()
for(var/obj/item/organ/internal/O in internal_organs)
O.on_life()
handle_changeling()
if(LAZYLEN(processing_patches))
handle_patches()
if(mind)
handle_changeling()
handle_wetness(times_fired)
// Increase germ_level regularly
if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
germ_level++
handle_germs()
if(stat != DEAD)
return TRUE
///////////////
@@ -111,7 +126,7 @@
var/O2_partialpressure = (breath.oxygen/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath.toxins/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath.carbon_dioxide/breath.total_moles())*breath_pressure
var/SA_partialpressure = (breath.sleeping_agent/breath.total_moles())*breath_pressure
//OXYGEN
if(O2_partialpressure < safe_oxy_min) //Not enough oxygen
@@ -151,22 +166,20 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath.toxins/safe_tox_max) * 10
adjustToxLoss(Clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//TRACE GASES
if(breath.trace_gases.len)
for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
var/SA_partialpressure = (SA.moles/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Paralyse(3)
if(SA_partialpressure > SA_sleep_min)
AdjustSleeping(2, bound_lower = 0, bound_upper = 10)
else if(SA_partialpressure > 0.01)
if(prob(20))
emote(pick("giggle","laugh"))
if(breath.sleeping_agent)
if(SA_partialpressure > SA_para_min)
Paralyse(3)
if(SA_partialpressure > SA_sleep_min)
AdjustSleeping(2, bound_lower = 0, bound_upper = 10)
else if(SA_partialpressure > 0.01)
if(prob(20))
emote(pick("giggle","laugh"))
//BREATH TEMPERATURE
handle_breath_temperature(breath)
@@ -191,6 +204,11 @@
else
update_action_buttons_icon()
/mob/living/carbon/proc/handle_organs()
for(var/thing in internal_organs)
var/obj/item/organ/internal/O = thing
O.on_life()
/mob/living/carbon/handle_diseases()
for(var/thing in viruses)
var/datum/disease/D = thing
@@ -229,26 +247,26 @@
adjustToxLoss(3)
updatehealth("handle mutations and radiation(75-100)")
radiation = Clamp(radiation, 0, 100)
radiation = clamp(radiation, 0, 100)
/mob/living/carbon/handle_chemicals_in_body()
if(reagents)
reagents.metabolize(src)
reagents.metabolize(src)
/mob/living/carbon/proc/handle_wetness(times_fired)
if(times_fired % 20==2) //dry off a bit once every 20 ticks or so
wetlevel = max(wetlevel - 1,0)
/mob/living/carbon/handle_stomach(times_fired)
for(var/mob/living/M in stomach_contents)
/mob/living/carbon/proc/handle_stomach(times_fired)
for(var/thing in stomach_contents)
var/mob/living/M = thing
if(M.loc != src)
stomach_contents.Remove(M)
LAZYREMOVE(stomach_contents, M)
continue
if(stat != DEAD)
if(M.stat == DEAD)
stomach_contents.Remove(M)
LAZYREMOVE(stomach_contents, M)
qdel(M)
continue
if(times_fired % 3 == 1)
@@ -261,7 +279,9 @@
if(stam_regen_start_time <= world.time)
if(stam_paralyzed)
update_stamina()
setStaminaLoss(0, FALSE)
if(staminaloss)
setStaminaLoss(0, FALSE)
update_health_hud()
var/restingpwr = 1 + 4 * resting
@@ -319,8 +339,17 @@
AdjustHallucinate(-2)
// Keep SSD people asleep
if(player_logged)
Sleeping(2)
/mob/living/carbon/handle_sleeping()
if(..())
if(mind?.vampire)
if(istype(loc, /obj/structure/closet/coffin))
adjustBruteLoss(-1, FALSE)
adjustFireLoss(-1, FALSE)
adjustToxLoss(-1)
handle_dreams()
adjustStaminaLoss(-10)
var/comfort = 1
@@ -336,44 +365,42 @@
comfort += 1 //Aren't naps SO much better when drunk?
AdjustDrunk(-0.2*comfort) //reduce drunkenness while sleeping.
if(comfort > 1 && prob(3))//You don't heal if you're just sleeping on the floor without a blanket.
adjustBruteLoss(-1*comfort)
adjustFireLoss(-1*comfort)
adjustBruteLoss(-1 * comfort, FALSE)
adjustFireLoss(-1 * comfort)
if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT)
emote("snore")
// Keep SSD people asleep
if(player_logged)
Sleeping(2)
return sleeping
/mob/living/carbon/handle_hud_icons()
return
/mob/living/carbon/handle_hud_icons_health()
/mob/living/carbon/update_health_hud(shown_health_amount)
if(!client)
return
if(healths)
if(stat != DEAD)
switch(health)
if(100 to INFINITY)
healths.icon_state = "health0"
if(80 to 100)
healths.icon_state = "health1"
if(60 to 80)
healths.icon_state = "health2"
if(40 to 60)
healths.icon_state = "health3"
if(20 to 40)
healths.icon_state = "health4"
if(0 to 20)
healths.icon_state = "health5"
else
healths.icon_state = "health6"
. = TRUE
if(shown_health_amount == null)
shown_health_amount = health
if(shown_health_amount >= maxHealth)
healths.icon_state = "health0"
else if(shown_health_amount > maxHealth * 0.8)
healths.icon_state = "health1"
else if(shown_health_amount > maxHealth * 0.6)
healths.icon_state = "health2"
else if(shown_health_amount > maxHealth * 0.4)
healths.icon_state = "health3"
else if(shown_health_amount > maxHealth * 0.2)
healths.icon_state = "health4"
else if(shown_health_amount > 0)
healths.icon_state = "health5"
else
healths.icon_state = "health6"
else
healths.icon_state = "health7"
handle_hud_icons_health_overlay()
/mob/living/carbon/proc/handle_hud_icons_health_overlay()
/mob/living/carbon/update_damage_hud()
if(!client)
return
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
if(check_death_method())
var/severity = 0
@@ -438,3 +465,25 @@
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
/mob/living/carbon/proc/handle_patches()
var/multiple_patch_multiplier = processing_patches.len > 1 ? (processing_patches.len * 1.5) : 1
var/applied_amount = 0.35 * multiple_patch_multiplier
for(var/patch in processing_patches)
var/obj/item/reagent_containers/food/pill/patch/P = patch
if(P.reagents && P.reagents.total_volume)
var/fractional_applied_amount = applied_amount / P.reagents.total_volume
P.reagents.reaction(src, REAGENT_TOUCH, fractional_applied_amount, P.needs_to_apply_reagents)
P.needs_to_apply_reagents = FALSE
P.reagents.trans_to(src, applied_amount * 0.5)
P.reagents.remove_any(applied_amount * 0.5)
else
if(!P.reagents || P.reagents.total_volume <= 0)
LAZYREMOVE(processing_patches, P)
qdel(P)
/mob/living/carbon/proc/handle_germs()
if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
germ_level++
@@ -2,12 +2,10 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
// if(health <= min_health)
if(health <= HEALTH_THRESHOLD_DEAD && check_death_method())
death()
create_debug_log("died of damage, trigger reason: [reason]")
return
// if(paralysis || sleeping || getOxyLoss() > low_oxy_ko || (status_flags & FAKEDEATH) || health <= crit_health)
if(paralysis || sleeping || (check_death_method() && getOxyLoss() > 50) || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT && check_death_method())
if(stat == CONSCIOUS)
KnockOut()
@@ -16,6 +14,9 @@
if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
update_damage_hud()
update_health_hud()
med_hud_set_status()
/mob/living/carbon/update_stamina()
var/stam = getStaminaLoss()
@@ -24,7 +25,6 @@
else if(stam_paralyzed)
stam_paralyzed = FALSE
update_canmove()
handle_hud_icons_health()
/mob/living/carbon/can_hear()
. = FALSE
+2
View File
@@ -269,6 +269,7 @@
if(amount > 0)
stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME
if(updating)
update_health_hud()
update_stamina()
/mob/living/proc/setStaminaLoss(amount, updating = TRUE)
@@ -284,6 +285,7 @@
if(amount > 0)
stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME
if(updating)
update_health_hud()
update_stamina()
/mob/living/proc/getMaxHealth()
+5 -1
View File
@@ -61,10 +61,13 @@
if(mind && suiciding)
mind.suicided = TRUE
reset_perspective(null)
clear_fullscreens()
update_sight()
update_action_buttons_icon()
update_damage_hud()
update_health_hud()
med_hud_set_health()
med_hud_set_status()
if(!gibbed && !QDELETED(src))
@@ -81,8 +84,9 @@
update_canmove()
timeofdeath = world.time
create_log(ATTACK_LOG, "died[gibbed ? " (Gibbed)": ""]")
GLOB.living_mob_list -= src
GLOB.alive_mob_list -= src
GLOB.dead_mob_list += src
if(mind)
mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
+98 -112
View File
@@ -1,12 +1,10 @@
/mob/living/Life(seconds, times_fired)
/mob/living/proc/Life(seconds, times_fired)
set waitfor = FALSE
set invisibility = 0
set background = BACKGROUND_ENABLED
if(notransform)
return FALSE
if(!loc)
return FALSE
var/datum/gas_mixture/environment = loc.return_air()
if(flying) //TODO: Better floating
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING)
if(client || registered_z) // This is a temporary error tracker to make sure we've caught everything
var/turf/T = get_turf(src)
@@ -17,51 +15,83 @@
else if (!client && registered_z)
log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.")
update_z(null)
if(notransform)
return FALSE
if(!loc)
return FALSE
if(stat != DEAD)
//Chemicals in the body
handle_chemicals_in_body()
if(reagents)
handle_chemicals_in_body()
if(QDELETED(src)) // some chems can gib mobs
return
if(stat != DEAD)
//Mutations and radiation
handle_mutations_and_radiation()
if(stat != DEAD)
//Breathing, if applicable
handle_breathing(times_fired)
if(stat != DEAD)
//Random events (vomiting etc)
handle_random_events()
. = 1
if(LAZYLEN(viruses))
handle_diseases()
handle_diseases()
if(QDELETED(src)) // diseases can qdel the mob via transformations
return
//Heart Attack, if applicable
if(stat != DEAD)
handle_heartattack()
//Handle temperature/pressure differences between body and environment
var/datum/gas_mixture/environment = loc.return_air()
if(environment)
handle_environment(environment)
handle_fire()
//stuff in the stomach
handle_stomach(times_fired)
update_gravity(mob_has_gravity())
update_pulling()
if(pulling)
update_pulling()
for(var/obj/item/grab/G in src)
G.process()
if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc.
if(stat != DEAD)
handle_critical_condition()
if(stat != DEAD) // Status & health update, are we dead or alive etc.
handle_disabilities() // eye, ear, brain damages
if(stat != DEAD)
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
if(client)
handle_regular_hud_updates()
if(stat != DEAD)
if(forced_look)
if(!isnum(forced_look))
var/atom/A = locateUID(forced_look)
if(istype(A))
var/view = client ? client.view : world.view
if(get_dist(src, A) > view || !(src in viewers(view, A)))
forced_look = null
to_chat(src, "<span class='notice'>Your direction target has left your view, you are no longer facing anything.</span>")
return
setDir()
..()
if(machine)
machine.check_eye(src)
if(stat != DEAD)
return TRUE
/mob/living/proc/handle_breathing(times_fired)
return
@@ -71,7 +101,6 @@
/mob/living/proc/handle_mutations_and_radiation()
radiation = 0 //so radiation don't accumulate in simple animals
return
/mob/living/proc/handle_chemicals_in_body()
return
@@ -85,126 +114,55 @@
/mob/living/proc/handle_environment(datum/gas_mixture/environment)
return
/mob/living/proc/handle_stomach(times_fired)
return
/mob/living/proc/update_pulling()
if(pulling)
if(incapacitated())
stop_pulling()
//This updates the health and status of the mob (conscious, unconscious, dead)
/mob/living/proc/handle_regular_status_updates()
return stat != DEAD
if(incapacitated())
stop_pulling()
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
/mob/living/proc/handle_status_effects()
handle_stunned()
handle_weakened()
handle_stuttering()
handle_silent()
handle_drugged()
handle_slurring()
handle_paralysed()
handle_sleeping()
handle_slowed()
handle_drunk()
handle_cultslurring()
/mob/living/proc/handle_stunned()
/mob/living/proc/handle_status_effects() // We check for the status effect in this proc as opposed to the procs below to avoid excessive proc call overhead
if(stunned)
AdjustStunned(-1, updating = 1, force = 1)
if(!stunned)
update_icons()
return stunned
/mob/living/proc/handle_weakened()
if(weakened)
AdjustWeakened(-1, updating = 1, force = 1)
if(!weakened)
update_icons()
return weakened
/mob/living/proc/handle_stuttering()
if(stuttering)
stuttering = max(stuttering-1, 0)
return stuttering
/mob/living/proc/handle_silent()
stuttering = max(stuttering - 1, 0)
if(silent)
AdjustSilence(-1)
return silent
/mob/living/proc/handle_drugged()
if(druggy)
AdjustDruggy(-1)
return druggy
/mob/living/proc/handle_slurring()
if(slurring)
AdjustSlur(-1)
return slurring
/mob/living/proc/handle_cultslurring()
if(cultslurring)
AdjustCultSlur(-1)
return cultslurring
/mob/living/proc/handle_paralysed()
if(paralysis)
AdjustParalysis(-1, updating = 1, force = 1)
return paralysis
/mob/living/proc/handle_sleeping()
if(sleeping)
AdjustSleeping(-1)
throw_alert("asleep", /obj/screen/alert/asleep)
else
clear_alert("asleep")
return sleeping
/mob/living/proc/handle_slowed()
handle_sleeping()
if(slowed)
AdjustSlowed(-1)
return slowed
if(drunk)
handle_drunk()
if(cultslurring)
AdjustCultSlur(-1)
/mob/living/proc/update_damage_hud()
return
/mob/living/proc/handle_sleeping()
AdjustSleeping(-1)
return sleeping
/mob/living/proc/handle_drunk()
if(drunk)
AdjustDrunk(-1)
AdjustDrunk(-1)
return drunk
/mob/living/proc/handle_disabilities()
//Eyes
if(disabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own
if((BLINDNESS in mutations) || stat) //blindness from disability or unconsciousness doesn't get better on its own
EyeBlind(1)
else if(eye_blind) //blindness, heals slowly over time
AdjustEyeBlind(-1)
else if(eye_blurry) //blurry eyes heal slowly
AdjustEyeBlurry(-1)
//this handles hud updates. Calls update_vision() and handle_hud_icons()
/mob/living/proc/handle_regular_hud_updates()
if(!client) return 0
handle_vision()
handle_hud_icons()
return 1
/mob/living/proc/handle_vision()
update_sight()
if(stat == DEAD)
return
if(machine)
if(!machine.check_eye(src))
reset_perspective(null)
else
if(!remote_view && !client.adminobs)
reset_perspective(null)
// Gives a mob the vision of being dead
/mob/living/proc/grant_death_vision()
sight |= SEE_TURFS
@@ -215,9 +173,37 @@
see_invisible = SEE_INVISIBLE_OBSERVER
sync_lighting_plane_alpha()
/mob/living/proc/handle_hud_icons()
handle_hud_icons_health()
/mob/living/proc/handle_critical_condition()
return
/mob/living/proc/handle_hud_icons_health()
return
/mob/living/update_health_hud()
if(!client)
return
if(healths)
var/severity = 0
var/healthpercent = (health / maxHealth) * 100
switch(healthpercent)
if(100 to INFINITY)
healths.icon_state = "health0"
if(80 to 100)
healths.icon_state = "health1"
severity = 1
if(60 to 80)
healths.icon_state = "health2"
severity = 2
if(40 to 60)
healths.icon_state = "health3"
severity = 3
if(20 to 40)
healths.icon_state = "health4"
severity = 4
if(1 to 20)
healths.icon_state = "health5"
severity = 5
else
healths.icon_state = "health7"
severity = 6
if(severity > 0)
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
+16 -16
View File
@@ -3,13 +3,13 @@
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medhud.add_to_hud(src)
faction += "\ref[src]"
GLOB.mob_living_list += src
/mob/living/prepare_huds()
..()
prepare_data_huds()
/mob/living/proc/prepare_data_huds()
..()
med_hud_set_health()
med_hud_set_status()
@@ -18,7 +18,7 @@
if(ranged_ability)
ranged_ability.remove_ranged_ability(src)
remove_from_all_data_huds()
GLOB.mob_living_list -= src
if(LAZYLEN(status_effects))
for(var/s in status_effects)
var/datum/status_effect/S = s
@@ -286,8 +286,9 @@
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
update_stat("updatehealth([reason])")
handle_hud_icons_health()
med_hud_set_health()
med_hud_set_status()
update_health_hud()
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
@@ -375,7 +376,7 @@
return 0
// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general.
/mob/living/proc/can_inject()
/mob/living/proc/can_inject(mob/user, error_msg, target_zone, penetrate_thick)
return TRUE
/mob/living/is_injectable(mob/user, allowmobs = TRUE)
@@ -407,6 +408,8 @@
QDEL_LIST(C.reagents.addiction_list)
C.reagents.addiction_threshold_accumulated.Cut()
QDEL_LIST(C.processing_patches)
// rejuvenate: Called by `revive` to get the mob into a revivable state
// the admin "rejuvenate" command calls `revive`, not this proc.
/mob/living/proc/rejuvenate()
@@ -512,7 +515,7 @@
return
/mob/living/Move(atom/newloc, direct)
/mob/living/Move(atom/newloc, direct, movetime)
if(buckled && buckled.loc != newloc) //not updating position
if(!buckled.anchored)
return buckled.Move(newloc, direct)
@@ -545,7 +548,7 @@
var/mob/living/M = pulling
if(M.lying && !M.buckled && (prob(M.getBruteLoss() * 200 / M.maxHealth)))
M.makeTrail(T)
pulling.Move(T, get_dir(pulling, T)) // the pullee tries to reach our previous position
pulling.Move(T, get_dir(pulling, T), movetime) // the pullee tries to reach our previous position
if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up
stop_pulling()
@@ -679,9 +682,6 @@
*/////////////////////
/mob/living/proc/resist_grab()
var/resisting = 0
for(var/obj/O in requests)
qdel(O)
resisting++
for(var/X in grabbed_by)
var/obj/item/grab/G = X
resisting++
@@ -737,7 +737,8 @@
clear_alert("weightless")
else
throw_alert("weightless", /obj/screen/alert/weightless)
float(!has_gravity)
if(!flying)
float(!has_gravity)
/mob/living/proc/float(on)
if(throwing)
@@ -758,7 +759,7 @@
//called when the mob receives a bright flash
/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND)))
if(check_eye_prot() < intensity && (override_blindness_check || !(BLINDNESS in mutations)))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return 1
@@ -801,7 +802,7 @@
if(do_mob(src, who, what.put_on_delay))
if(what && Adjacent(who) && !(what.flags & NODROP))
unEquip(what)
who.equip_to_slot_if_possible(what, where, 0, 1)
who.equip_to_slot_if_possible(what, where, FALSE, TRUE)
add_attack_logs(src, who, "Equipped [what]")
/mob/living/singularity_act()
@@ -822,8 +823,7 @@
spawn_dust()
gib()
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
end_pixel_y = get_standard_pixel_y_offset(lying)
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!used_item)
used_item = get_active_hand()
..()
@@ -1024,9 +1024,9 @@
if("stat")
if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life
GLOB.dead_mob_list -= src
GLOB.living_mob_list += src
GLOB.alive_mob_list += src
if((stat < DEAD) && (var_value == DEAD))//Kill he
GLOB.living_mob_list -= src
GLOB.alive_mob_list -= src
GLOB.dead_mob_list += src
. = ..()
switch(var_name)
+5 -8
View File
@@ -73,16 +73,15 @@
return shock_damage
/mob/living/emp_act(severity)
var/list/L = src.get_contents()
for(var/obj/O in L)
O.emp_act(severity)
..()
for(var/obj/O in contents)
O.emp_act(severity)
/obj/item/proc/get_volume_by_throwforce_and_or_w_class()
if(throwforce && w_class)
return Clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
return clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
else if(w_class)
return Clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
return clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
else
return 0
@@ -176,7 +175,7 @@
return
/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person
fire_stacks = Clamp(fire_stacks + add_fire_stacks, -20, 20)
fire_stacks = clamp(fire_stacks + add_fire_stacks, -20, 20)
if(on_fire && fire_stacks <= 0)
ExtinguishMob()
@@ -261,8 +260,6 @@
add_attack_logs(user, src, "Grabbed passively", ATKLOG_ALL)
var/obj/item/grab/G = new /obj/item/grab(user, src)
if(buckled)
to_chat(user, "<span class='notice'>You cannot grab [src]; [p_they()] [p_are()] buckled in!</span>")
if(!G) //the grab will delete itself in New if src is anchored
return 0
user.put_in_active_hand(G)
@@ -28,13 +28,11 @@
var/on_fire = 0 //The "Are we on fire?" var
var/fire_stacks = 0 //Tracks how many stacks of fire we have on, max is usually 20
var/implanting = 0 //Used for the mind-slave implant
var/floating = 0
var/mob_size = MOB_SIZE_HUMAN
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
var/digestion_ratio = 1 //controls how quickly reagents metabolize; largely governered by species attributes.
var/bloodcrawl = 0 //0 No blood crawling, 1 blood crawling, 2 blood crawling+mob devour
var/holder = null //The holder for blood crawling
var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always
@@ -61,7 +59,6 @@
var/list/say_log = list() //a log of what we've said, plain text, no spans or junk, essentially just each individual "message"
var/list/emote_log = list() //like say_log but for emotes
var/list/recent_tastes = list()
var/blood_volume = 0 //how much blood the mob has
hud_possible = list(HEALTH_HUD,STATUS_HUD,SPECIALROLE_HUD)
+20 -20
View File
@@ -61,7 +61,7 @@ proc/get_radio_key_from_channel(var/channel)
return default_language
/mob/living/proc/handle_speech_problems(list/message_pieces, var/verb)
var/robot = isSynthetic()
var/robot = ismachineperson(src)
for(var/datum/multilingual_say_piece/S in message_pieces)
if(S.speaking && S.speaking.flags & NO_STUTTER)
continue
@@ -172,11 +172,18 @@ proc/get_radio_key_from_channel(var/channel)
var/list/hsp = handle_speech_problems(message_pieces, verb)
verb = hsp["verb"]
// Do this so it gets logged for all types of communication
var/log_message = "[message_mode ? "([message_mode])" : ""] '[message]'"
create_log(SAY_LOG, log_message)
var/list/used_radios = list()
if(handle_message_mode(message_mode, message_pieces, verb, used_radios))
return 1
// Log of what we've said, plain message, no spans or junk
// handle_message_mode should have logged this already if it handled it
say_log += log_message
log_say(log_message, src)
var/list/handle_v = handle_speech_sound()
var/sound/speech_sound = handle_v[1]
@@ -262,22 +269,18 @@ proc/get_radio_key_from_channel(var/channel)
M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol, sound_frequency)
if(M.client)
speech_bubble_recipients.Add(M.client)
spawn(0)
if(loc && !isturf(loc))
var/atom/A = loc //Non-turf, let it handle the speech bubble
A.speech_bubble("hR[speech_bubble_test]", A, speech_bubble_recipients)
else //Turf, leave speech bubbles to the mob
speech_bubble("h[speech_bubble_test]", src, speech_bubble_recipients)
if(loc && !isturf(loc))
var/atom/A = loc //Non-turf, let it handle the speech bubble
A.speech_bubble("[A.bubble_icon][speech_bubble_test]", A, speech_bubble_recipients)
else //Turf, leave speech bubbles to the mob
speech_bubble("[bubble_icon][speech_bubble_test]", src, speech_bubble_recipients)
for(var/obj/O in listening_obj)
spawn(0)
if(O) //It's possible that it could be deleted in the meantime.
O.hear_talk(src, message_pieces, verb)
//Log of what we've said, plain message, no spans or junk
say_log += message
create_log(SAY_LOG, message) // TODO after #13047: Include the channel
log_say(message, src)
return 1
/obj/effect/speech_bubble
@@ -333,7 +336,8 @@ proc/get_radio_key_from_channel(var/channel)
var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
S.speaking.broadcast(src, S.message)
return 1
// Log it here since it skips the default way say handles it
create_log(SAY_LOG, "(whisper) '[message]'")
whisper_say(message_pieces)
// for weird circumstances where you're inside an atom that is also you, like pai's
@@ -362,7 +366,6 @@ proc/get_radio_key_from_channel(var/channel)
say_log += "whisper: [message]"
log_whisper(message, src)
create_log(SAY_LOG, "WHISPER: [message]")
var/message_range = 1
var/eavesdropping_range = 2
var/watching_range = 5
@@ -459,10 +462,7 @@ proc/get_radio_key_from_channel(var/channel)
if(M.client)
speech_bubble_recipients.Add(M.client)
spawn(0)
var/image/I = image('icons/mob/talk.dmi', src, "h[speech_bubble_test]", MOB_LAYER + 1)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
flick_overlay(I, speech_bubble_recipients, 30)
speech_bubble("[bubble_icon][speech_bubble_test]", src, speech_bubble_recipients)
if(watching.len)
var/rendered = "<span class='game say'><span class='name'>[name]</span> [not_heard].</span>"
@@ -471,7 +471,7 @@ proc/get_radio_key_from_channel(var/channel)
return 1
/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, MOB_LAYER + 1)
/mob/living/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list())
var/image/I = image('icons/mob/talk.dmi', bubble_loc, bubble_state, FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
flick_overlay(I, bubble_recipients, 30)
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, bubble_recipients, 30)
+16 -20
View File
@@ -63,6 +63,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
//MALFUNCTION
var/datum/module_picker/malf_picker
var/datum/action/innate/ai/choose_modules/modules_action
var/list/datum/AI_Module/current_modules = list()
var/can_dominate_mechs = 0
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
@@ -243,7 +244,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/show_borg_info()
stat(null, text("Connected cyborgs: [connected_robots.len]"))
for(var/mob/living/silicon/robot/R in connected_robots)
for(var/thing in connected_robots)
var/mob/living/silicon/robot/R = thing
var/robot_status = "Nominal"
if(R.stat || !R.client)
robot_status = "OFFLINE"
@@ -251,8 +253,9 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
robot_status = "DEPOWERED"
// Name, Health, Battery, Module, Area, and Status! Everything an AI wants to know about its borgies!
var/area/A = get_area(R)
var/area_name = A ? sanitize(A.name) : "Unknown"
stat(null, text("[R.name] | S.Integrity: [R.health]% | Cell: [R.cell ? "[R.cell.charge] / [R.cell.maxcharge]" : "Empty"] | \
Module: [R.designation] | Loc: [sanitize(A.name)] | Status: [robot_status]"))
Module: [R.designation] | Loc: [area_name] | Status: [robot_status]"))
/mob/living/silicon/ai/rename_character(oldname, newname)
if(!..(oldname, newname))
@@ -571,13 +574,13 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return FALSE
/mob/living/silicon/ai/emp_act(severity)
..()
if(prob(30))
switch(pick(1,2))
if(1)
view_core()
if(2)
ai_call_shuttle()
..()
/mob/living/silicon/ai/ex_act(severity)
..()
@@ -849,13 +852,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "<span class='notice'>Switched to [network] camera network.</span>")
//End of code by Mord_Sith
/mob/living/silicon/ai/proc/choose_modules()
set category = "Malfunction"
set name = "Choose Module"
malf_picker.use(src)
/mob/living/silicon/ai/proc/ai_statuschange()
set category = "AI Commands"
set name = "AI Status"
@@ -1026,15 +1022,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
return
/mob/living/silicon/ai/proc/corereturn()
set category = "Malfunction"
set name = "Return to Main Core"
var/obj/machinery/power/apc/apc = loc
if(!istype(apc))
to_chat(src, "<span class='notice'>You are already in your Main Core.</span>")
return
apc.malfvacate()
//Toggles the luminosity and applies it by re-entereing the camera.
/mob/living/silicon/ai/proc/toggle_camera_light()
@@ -1242,8 +1229,17 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
to_chat(src, "In the top right corner of the screen you will find the Malfunctions tab, where you can purchase various abilities, from upgraded surveillance to station ending doomsday devices.")
to_chat(src, "You are also capable of hacking APCs, which grants you more points to spend on your Malfunction powers. The drawback is that a hacked APC will give you away if spotted by the crew. Hacking an APC takes 60 seconds.")
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
verbs += /mob/living/silicon/ai/proc/choose_modules
malf_picker = new /datum/module_picker
modules_action = new(malf_picker)
modules_action.Grant(src)
///Removes all malfunction-related /datum/action's from the target AI.
/mob/living/silicon/ai/proc/remove_malf_abilities()
QDEL_NULL(modules_action)
for(var/datum/AI_Module/AM in current_modules)
for(var/datum/action/A in actions)
if(istype(A, initial(AM.power_type)))
qdel(A)
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
if(!istype(target))
+1 -1
View File
@@ -34,7 +34,7 @@
spawn(10)
explosion(src.loc, 3, 6, 12, 15)
for(var/obj/machinery/ai_status_display/O in world) //change status
for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
O.mode = 2
if(istype(loc, /obj/item/aicard))
@@ -67,9 +67,6 @@
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
/datum/camerachunk/proc/update()
set background = BACKGROUND_ENABLED
var/list/newVisibleTurfs = list()
for(var/camera in cameras)
@@ -1,15 +1,5 @@
GLOBAL_LIST_EMPTY(empty_playable_ai_cores)
/hook/roundstart/proc/spawn_empty_ai()
for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
if(S.name != "AI")
continue
if(locate(/mob/living) in S.loc)
continue
GLOB.empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(S))
return 1
/mob/living/silicon/ai/verb/wipe_core()
set name = "Wipe Core"
set category = "OOC"
+2 -2
View File
@@ -37,7 +37,8 @@
else
adjustOxyLoss(-1)
handle_stunned()
if(stunned)
AdjustStunned(-1, updating = 1, force = 1)
var/area/my_area = get_area(src)
@@ -140,7 +141,6 @@
else
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
update_stat("updatehealth([reason])")
diag_hud_set_status()
diag_hud_set_health()
+1 -1
View File
@@ -1,6 +1,6 @@
/mob/living/silicon/ai/Logout()
..()
for(var/obj/machinery/ai_status_display/O in world) //change status
for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
O.mode = 0
src.view_core()
return
@@ -9,7 +9,7 @@
else if(stat == UNCONSCIOUS)
WakeUp()
create_debug_log("woke up, trigger reason: [reason]")
//diag_hud_set_status()
diag_hud_set_status()
/mob/living/silicon/ai/has_vision(information_only = FALSE)
return ..() && !lacks_power()
@@ -4,7 +4,7 @@
if(!.)
return FALSE
icon_state = "ai-crash"
for(var/obj/machinery/ai_status_display/O in world) //change status
for(var/obj/machinery/ai_status_display/O in GLOB.machines) //change status
if(atoms_share_level(O, src))
O.mode = 2
gib()
+12 -16
View File
@@ -1,22 +1,18 @@
/mob/living/silicon/pai/Life(seconds, times_fired)
. = ..()
if(.)
//if(secHUD == 1)
// process_sec_hud(src, 1)
////if(medHUD == 1)
// process_med_hud(src, 1)
if(silence_time)
if(world.timeofday >= silence_time)
silence_time = null
to_chat(src, "<font color=green>Communication circuit reinitialized. Speech and messaging functionality restored.</font>")
if(QDELETED(src) || stat == DEAD)
return
if(silence_time)
if(world.timeofday >= silence_time)
silence_time = null
to_chat(src, "<font color=green>Communication circuit reinitialized. Speech and messaging functionality restored.</font>")
if(cable)
if(get_dist(src, cable) > 1)
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='warning'>The data cable rapidly retracts back into its spool.</span>", 3, "<span class='warning'>You hear a click and the sound of wire spooling rapidly.</span>", 2)
qdel(src.cable)
cable = null
if(cable)
if(get_dist(src, cable) > 1)
var/turf/T = get_turf_or_move(loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='warning'>The data cable rapidly retracts back into its spool.</span>", 3, "<span class='warning'>You hear a click and the sound of wire spooling rapidly.</span>", 2)
QDEL_NULL(cable)
/mob/living/silicon/pai/updatehealth(reason = "none given")
if(status_flags & GODMODE)
@@ -1,6 +1,6 @@
// Recruiting observers to play as pAIs
GLOBAL_DATUM(paiController, /datum/paiController) // Global handler for pAI candidates
GLOBAL_DATUM_INIT(paiController, /datum/paiController, new) // Global handler for pAI candidates
/datum/paiCandidate
var/name
@@ -10,12 +10,6 @@ GLOBAL_DATUM(paiController, /datum/paiController) // Global handler for pAI cand
var/comments
var/ready = 0
/hook/startup/proc/paiControllerSetup()
GLOB.paiController = new /datum/paiController()
return 1
/datum/paiController
var/list/pai_candidates = list()
var/list/asked = list()
@@ -13,19 +13,6 @@ GLOBAL_LIST_INIT(pai_emotions, list(
GLOBAL_LIST_EMPTY(pai_software_by_key)
GLOBAL_LIST_EMPTY(default_pai_software)
/hook/startup/proc/populate_pai_software_list()
var/r = 1 // I would use ., but it'd sacrifice runtime detection
for(var/type in subtypesof(/datum/pai_software))
var/datum/pai_software/P = new type()
if(GLOB.pai_software_by_key[P.id])
var/datum/pai_software/O = GLOB.pai_software_by_key[P.id]
to_chat(world, "<span class='warning'>pAI software module [P.name] has the same key as [O.name]!</span>")
r = 0
continue
GLOB.pai_software_by_key[P.id] = P
if(P.default)
GLOB.default_pai_software[P.id] = P
return r
/mob/living/silicon/pai/New()
..()
@@ -382,14 +382,6 @@
return 1
/mob/living/silicon/pai/proc/hackloop()
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
if(!T || !is_station_contact(T.z))
break
if(T.loc)
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress in [T.loc].</b></font>")
else
to_chat(AI, "<font color = red><b>Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location.</b></font>")
var/obj/machinery/door/D = cable.machine
if(!istype(D))
hack_aborted = 1
@@ -227,7 +227,7 @@
throw_speed = 5
throw_range = 10
origin_tech = "magnets=1;biotech=1"
var/mode = 1;
var/mode = 1
/obj/item/robotanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
if(( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
@@ -253,7 +253,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
to_chat(user, "<span class='warning'>You can't analyze non-robotic things!</span>")
return
switch(scan_type)
if("robot")
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
@@ -269,7 +269,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
to_chat(user, "<span class='notice'>Localized Damage:</span>")
if(!LAZYLEN(damaged) && !LAZYLEN(missing))
to_chat(user, "<span class='notice'>\t Components are OK.</span>")
else
else
if(LAZYLEN(damaged))
for(var/datum/robot_component/org in damaged)
user.show_message(text("<span class='notice'>\t []: [][] - [] - [] - []</span>", \
@@ -282,7 +282,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
if(LAZYLEN(missing))
for(var/datum/robot_component/org in missing)
user.show_message("<span class='warning'>\t [capitalize(org.name)]: MISSING</span>")
if(H.emagged && prob(5))
to_chat(user, "<span class='warning'>\t ERROR: INTERNAL SYSTEMS COMPROMISED</span>")
@@ -313,7 +313,7 @@ proc/robot_healthscan(mob/user, mob/living/M)
if(!organ_found)
to_chat(user, "<span class='warning'>No prosthetics located.</span>")
if(H.isSynthetic())
if(ismachineperson(H))
to_chat(user, "<span class='notice'>Internal Fluid Level:[H.blood_volume]/[H.max_blood]</span>")
if(H.bleed_rate)
to_chat(user, "<span class='warning'>Warning:External component leak detected!</span>")
@@ -18,7 +18,7 @@
flick("gibbed-r", animation)
robogibs(loc)
GLOB.living_mob_list -= src
GLOB.alive_mob_list -= src
GLOB.dead_mob_list -= src
QDEL_IN(animation, 15)
QDEL_IN(src, 15)
@@ -6,6 +6,7 @@
icon_state = "repairbot"
maxHealth = 35
health = 35
bubble_icon = "machine"
universal_speak = 0
universal_understand = 1
gender = NEUTER
@@ -13,11 +14,14 @@
braintype = "Robot"
lawupdate = 0
density = 0
has_camera = FALSE
req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS)
ventcrawler = 2
magpulse = 1
mob_size = MOB_SIZE_SMALL
modules_break = FALSE
// We need to keep track of a few module items so we don't need to do list operations
// every time we need them. These get set in New() after the module is chosen.
var/obj/item/stack/sheet/metal/cyborg/stack_metal = null
@@ -48,7 +52,7 @@
if(radio)
radio.wires.CutWireIndex(RADIO_WIRE_TRANSMIT)
if(camera && "Robots" in camera.network)
if(camera && ("Robots" in camera.network))
camera.network.Add("Engineering")
//They are unable to be upgraded, so let's give them a bit of a better battery.
@@ -79,7 +83,7 @@
scanner.Grant(src)
update_icons()
/mob/living/silicon/robot/drone/init()
/mob/living/silicon/robot/drone/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/drone()
connected_ai = null
@@ -142,7 +146,7 @@
user.visible_message("<span class='warning'>\the [user] swipes [user.p_their()] ID card through [src], attempting to reboot it.</span>", "<span class='warning'>You swipe your ID card through [src], attempting to reboot it.</span>")
last_reboot = world.time / 10
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.key && D.client)
drones++
if(drones < config.max_maint_drones)
@@ -350,3 +354,20 @@
/mob/living/simple_animal/drone/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
if(affect_silicon)
return ..()
/mob/living/silicon/robot/drone/decompile_act(obj/item/matter_decompiler/C, mob/user)
if(!client && istype(user, /mob/living/silicon/robot/drone))
to_chat(user, "<span class='warning'>You begin decompiling the other drone.</span>")
if(!do_after(user, 5 SECONDS, target = loc))
to_chat(user, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
return
if(QDELETED(src) || QDELETED(user))
return ..()
to_chat(user, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
C.stored_comms["metal"] += 15
C.stored_comms["glass"] += 15
C.stored_comms["wood"] += 5
qdel(src)
return TRUE
return ..()
@@ -34,7 +34,7 @@
var/dat
dat += "<B>Maintenance Units</B><BR>"
for(var/mob/living/silicon/robot/drone/D in world)
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE" : "<font color='green'>ACTIVE"]</FONT>)"
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
dat += "<BR>Currently located in: [get_area(D)]."
@@ -74,7 +74,7 @@
else if(href_list["ping"])
to_chat(usr, "<span class='notice'>You issue a maintenance request for all active drones, highlighting [drone_call_area].</span>")
for(var/mob/living/silicon/robot/drone/D in world)
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.client && D.stat == 0)
to_chat(D, "-- Maintenance drone presence requested in: [drone_call_area].")
@@ -30,29 +30,22 @@
/obj/item/circuitboard,
/obj/item/stack/tile/light,
/obj/item/stack/ore/bluespace_crystal
)
)
//Item currently being held.
var/obj/item/wrapped = null
/obj/item/gripper/paperwork
name = "paperwork gripper"
desc = "A simple grasping tool for clerical work."
can_hold = list(
/obj/item/clipboard,
/obj/item/paper,
/obj/item/card/id
)
var/obj/item/gripped_item = null
/obj/item/gripper/medical
name = "medical gripper"
desc = "A grasping tool used to help patients up once surgery is complete."
can_hold = list()
/obj/item/gripper/medical/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
/obj/item/gripper/medical/attack_self(mob/user)
return
/obj/item/gripper/medical/afterattack(atom/target, mob/living/user, proximity, params)
var/mob/living/carbon/human/H
if(!wrapped && proximity && target && ishuman(target))
if(!gripped_item && proximity && target && ishuman(target))
H = target
if(H.lying)
H.AdjustSleeping(-5)
@@ -71,98 +64,69 @@
..()
can_hold = typecacheof(can_hold)
/obj/item/gripper/attack_self(mob/user as mob)
if(wrapped)
wrapped.attack_self(user)
/obj/item/gripper/verb/drop_item()
/obj/item/gripper/verb/drop_item_gripped()
set name = "Drop Gripped Item"
set desc = "Release an item from your magnetic gripper."
set category = "Drone"
drop_item_p()
drop_gripped_item()
// The "p" stands for proc, since I was having annoying weird stuff happening with this in the verb
// when trying to have default values for arguments and stuff
/obj/item/gripper/proc/drop_item_p(var/silent = 0)
/obj/item/gripper/attack_self(mob/user)
if(gripped_item)
gripped_item.attack_self(user)
else
to_chat(user, "<span class='warning'>[src] is empty.</span>")
if(!wrapped)
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
for(var/obj/item/thing in src.contents)
thing.forceMove(get_turf(src))
return
/obj/item/gripper/proc/drop_gripped_item(silent = FALSE)
if(gripped_item)
if(!silent)
to_chat(loc, "<span class='warning'>You drop [gripped_item].</span>")
gripped_item.forceMove(get_turf(src))
gripped_item = null
if(wrapped.loc != src)
wrapped = null
return
if(!silent)
to_chat(src.loc, "<span class='warning'>You drop \the [wrapped].</span>")
wrapped.forceMove(get_turf(src))
wrapped = null
/obj/item/gripper/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
/obj/item/gripper/attack(mob/living/carbon/M, mob/living/carbon/user)
return
/obj/item/gripper/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
/// Grippers are snowflakey so this is needed to to prevent forceMoving grippers after `if(!user.drop_item())` checks done in certain attackby's.
/obj/item/gripper/forceMove(atom/destination)
return
/obj/item/gripper/afterattack(atom/target, mob/living/user, proximity, params)
if(!target || !proximity) //Target is invalid or we are not adjacent.
return
return FALSE
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
if(!wrapped)
for(var/obj/item/thing in src.contents)
wrapped = thing
break
if(gripped_item) //Already have an item.
if(wrapped) //Already have an item.
//Temporary put wrapped into user so target's attackby() checks pass.
wrapped.forceMove(user)
//Pass the attack on to the target. This might delete/relocate wrapped.
if(!target.attackby(wrapped, user, params) && target && wrapped)
// If the attackby didn't resolve or delete the target or wrapped, afterattack
//Pass the attack on to the target. This might delete/relocate gripped_item.
if(!target.attackby(gripped_item, user, params))
// If the attackby didn't resolve or delete the target or gripped_item, afterattack
// (Certain things, such as mountable frames, rely on afterattack)
wrapped.afterattack(target, user, 1, params)
gripped_item?.afterattack(target, user, 1, params)
//If wrapped did neither get deleted nor put into target, put it back into the gripper.
if(wrapped && user && (wrapped.loc == user))
wrapped.forceMove(src)
else
wrapped = null
return
else if(istype(target,/obj/item)) //Check that we're not pocketing a mob.
//...and that the item is not in a container.
if(!isturf(target.loc))
return
//If gripped_item either didn't get deleted, or it failed to be transfered to its target
if(!gripped_item && contents.len)
gripped_item = contents[1]
return FALSE
else if(gripped_item && !contents.len)
gripped_item = null
else if(istype(target, /obj/item)) //Check that we're not pocketing a mob.
var/obj/item/I = target
//Check if the item is blacklisted.
var/grab = 0
if(can_hold.len)
if(is_type_in_typecache(I, can_hold))
grab = 1
//We can grab the item, finally.
if(grab)
to_chat(user, "You collect \the [I].")
if(is_type_in_typecache(I, can_hold)) // Make sure the item is something the gripper can hold
to_chat(user, "<span class='notice'>You collect [I].</span>")
I.forceMove(src)
wrapped = I
return
gripped_item = I
else
to_chat(user, "<span class='warning'>Your gripper cannot hold \the [target].</span>")
to_chat(user, "<span class='warning'>Your gripper cannot hold [target].</span>")
return FALSE
else if(istype(target,/obj/machinery/power/apc))
var/obj/machinery/power/apc/A = target
if(A.opened)
if(A.cell)
wrapped = A.cell
gripped_item = A.cell
A.cell.add_fingerprint(user)
A.cell.update_icon()
@@ -173,6 +137,7 @@
A.update_icon()
user.visible_message("<span class='warning'>[user] removes the power cell from [A]!</span>", "You remove the power cell.")
return TRUE
//TODO: Matter decompiler.
/obj/item/matter_decompiler
@@ -186,15 +151,13 @@
var/list/stored_comms = list(
"metal" = 0,
"glass" = 0,
"wood" = 0,
"plastic" = 0
"wood" = 0
)
/obj/item/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
return
/obj/item/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
/obj/item/matter_decompiler/afterattack(atom/target, mob/living/user, proximity, params)
if(!proximity) return //Not adjacent.
//We only want to deal with using this on turfs. Specific items aren't important.
@@ -203,101 +166,11 @@
return
//Used to give the right message.
var/grabbed_something = 0
var/grabbed_something = FALSE
for(var/mob/M in T)
if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse))
src.loc.visible_message("<span class='notice'>[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.</span>","<span class='warning'>It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.</span>")
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
qdel(M)
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
return
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
var/mob/living/silicon/robot/drone/D = src.loc
if(!istype(D))
return
to_chat(D, "<span class='warning'>You begin decompiling the other drone.</span>")
if(!do_after(D, 50, target = target))
to_chat(D, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
return
if(!M || !D) return
to_chat(D, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
qdel(M)
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
stored_comms["metal"] += 15
stored_comms["glass"] += 15
stored_comms["wood"] += 5
stored_comms["plastic"] += 5
return
else
continue
for(var/obj/W in T)
//Different classes of items give different commodities.
if(istype(W,/obj/item/cigbutt))
stored_comms["plastic"]++
else if(istype(W,/obj/structure/spider/spiderling))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
else if(istype(W,/obj/item/light))
var/obj/item/light/L = W
if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
stored_comms["metal"]++
stored_comms["glass"]++
else
continue
else if(istype(W,/obj/effect/decal/remains/robot))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/trash))
stored_comms["metal"]++
stored_comms["plastic"]++
stored_comms["plastic"]++
else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
stored_comms["metal"]++
stored_comms["metal"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/ammo_casing))
stored_comms["metal"]++
else if(istype(W,/obj/item/shard))
stored_comms["glass"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/reagent_containers/food/snacks/grown))
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["wood"]++
stored_comms["wood"]++
else if(istype(W,/obj/item/broken_bottle))
stored_comms["glass"]++
stored_comms["glass"]++
stored_comms["glass"]++
else if(istype(W,/obj/item/light/tube) || istype(W,/obj/item/light/bulb))
stored_comms["glass"]++
else
continue
qdel(W)
grabbed_something = 1
for(var/atom/movable/A in T)
if(A.decompile_act(src, user)) // Each decompileable mob or obj needs to have this defined
grabbed_something = TRUE
if(grabbed_something)
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
@@ -388,11 +261,5 @@
stack_wood = new /obj/item/stack/sheet/wood(src.module)
stack_wood.amount = 1
stack = stack_wood
if("plastic")
if(!stack_plastic)
stack_plastic = new /obj/item/stack/sheet/plastic(src.module)
stack_plastic.amount = 1
stack = stack_plastic
stack.amount++
decompiler.stored_comms[type]--
@@ -52,7 +52,7 @@
/obj/machinery/drone_fabricator/proc/count_drones()
var/drones = 0
for(var/mob/living/silicon/robot/drone/D in world)
for(var/mob/living/silicon/robot/drone/D in GLOB.silicon_mob_list)
if(D.key && D.client)
drones++
return drones
@@ -142,7 +142,7 @@
if(alert("Are you sure you want to respawn as a drone?", "Are you sure?", "Yes", "No") != "Yes")
return
for(var/obj/machinery/drone_fabricator/DF in world)
for(var/obj/machinery/drone_fabricator/DF in GLOB.machines)
if(DF.stat & NOPOWER || !DF.produce_drones)
continue
@@ -4,7 +4,7 @@
/mob/living/silicon/robot/drone/update_stat(reason = "none given")
if(status_flags & GODMODE)
return
if(health <= -35 && stat != DEAD)
if(health <= -maxHealth && stat != DEAD)
gib()
create_debug_log("died of damage, trigger reason: [reason]")
return
@@ -78,6 +78,7 @@
set_actions(O)
else
to_chat(src, "You need to disable a module first!")
check_module_damage(FALSE)
update_icons()
/mob/living/silicon/robot/proc/set_actions(obj/item/I)
@@ -115,11 +116,11 @@
return 0
/mob/living/silicon/robot/drop_item()
var/obj/item/I = get_active_hand()
if(istype(I, /obj/item/gripper))
var/obj/item/gripper/G = I
G.drop_item_p(silent = 1)
return
var/obj/item/gripper/G = get_active_hand()
if(istype(G))
G.drop_gripped_item(silent = TRUE)
return TRUE // The gripper is special because it has a normal item inside that we can drop.
return FALSE // All robot inventory items have NODROP, so they should return FALSE.
//Helper procs for cyborg modules on the UI.
//These are hackish but they help clean up code elsewhere.
+22 -57
View File
@@ -1,23 +1,20 @@
/mob/living/silicon/robot/Life(seconds, times_fired)
set invisibility = 0
set background = BACKGROUND_ENABLED
if(src.notransform)
if(notransform)
return
//Status updates, death etc.
clamp_values()
. = ..()
if(..())
handle_equipment()
// if Alive
if(.)
handle_robot_hud_updates()
handle_robot_cell()
process_locks()
update_items()
process_queued_alarms()
/mob/living/silicon/robot/proc/clamp_values()
SetStunned(min(stunned, 30))
SetParalysis(min(paralysis, 30))
SetWeakened(min(weakened, 20))
SetSleeping(0)
/mob/living/silicon/robot/proc/handle_robot_cell()
if(stat != DEAD)
@@ -39,7 +36,7 @@
if(is_component_functioning("power cell") && cell.charge)
if(cell.charge <= 100)
uneq_all()
var/amt = Clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
var/amt = clamp((lamp_intensity - 2) * 2,1,cell.charge) //Always try to use at least one charge per tick, but allow it to completely drain the cell.
cell.use(amt) //Usage table: 1/tick if off/lowest setting, 4 = 4/tick, 6 = 8/tick, 8 = 12/tick, 10 = 16/tick
else
uneq_all()
@@ -47,36 +44,13 @@
update_headlamp()
diag_hud_set_borgcell()
/mob/living/silicon/robot/handle_regular_status_updates()
. = ..()
/mob/living/silicon/robot/proc/handle_equipment()
if(camera && !scrambledcodes)
if(stat == DEAD || wires.IsCameraCut())
camera.status = 0
else
camera.status = 1
if(sleeping)
AdjustSleeping(-1)
if(.) //alive
if(!istype(src, /mob/living/silicon/robot/drone))
if(health < 50) //Gradual break down of modules as more damage is sustained
if(uneq_module(module_state_3))
to_chat(src, "<span class='warning'>SYSTEM ERROR: Module 3 OFFLINE.</span>")
if(health < 0)
if(uneq_module(module_state_2))
to_chat(src, "<span class='warning'>SYSTEM ERROR: Module 2 OFFLINE.</span>")
if(health < -50)
if(uneq_module(module_state_1))
to_chat(src, "<span class='warning'>CRITICAL ERROR: All modules OFFLINE.</span>")
diag_hud_set_health()
diag_hud_set_status()
//update the state of modules and components here
if(stat != CONSCIOUS)
uneq_all()
@@ -86,18 +60,21 @@
else
radio.on = 1
return 1
/mob/living/silicon/robot/handle_hud_icons()
update_items()
update_cell()
/mob/living/silicon/robot/proc/SetEmagged(new_state)
emagged = new_state
update_icons()
if(emagged)
throw_alert("hacked", /obj/screen/alert/hacked)
else
clear_alert("hacked")
..()
/mob/living/silicon/robot/handle_hud_icons_health()
/mob/living/silicon/robot/proc/handle_robot_hud_updates()
if(!client)
return
update_cell_hud_icon()
/mob/living/silicon/robot/update_health_hud()
if(healths)
if(stat != DEAD)
if(health >= maxHealth)
@@ -115,19 +92,7 @@
else
healths.icon_state = "health7"
switch(bodytemperature) //310.055 optimal body temp
if(335 to INFINITY)
throw_alert("temp", /obj/screen/alert/hot/robot, 2)
if(320 to 335)
throw_alert("temp", /obj/screen/alert/hot/robot, 1)
if(300 to 320)
clear_alert("temp")
if(260 to 300)
throw_alert("temp", /obj/screen/alert/cold/robot, 1)
else
throw_alert("temp", /obj/screen/alert/cold/robot, 2)
/mob/living/silicon/robot/proc/update_cell()
/mob/living/silicon/robot/proc/update_cell_hud_icon()
if(cell)
var/cellcharge = cell.charge/cell.maxcharge
switch(cellcharge)
@@ -146,7 +111,7 @@
/mob/living/silicon/robot/proc/update_items()
/mob/living/silicon/robot/proc/update_items() // What in the Sam hell is this?
if(client)
for(var/obj/I in get_all_slots())
client.screen |= I
+169 -88
View File
@@ -9,6 +9,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
icon_state = "robot"
maxHealth = 100
health = 100
bubble_icon = "robot"
universal_understand = 1
deathgasp_on_death = TRUE
@@ -16,8 +17,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/custom_name = ""
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
//Hud stuff
//Hud stuff
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
@@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
//3 Modules can be activated at any one time.
//3 Modules can be activated at any one time.
var/obj/item/robot_module/module = null
var/module_active = null
var/module_state_1 = null
@@ -57,6 +57,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/is_emaggable = TRUE
var/eye_protection = 0
var/ear_protection = 0
var/damage_protection = 0
var/emp_protection = FALSE
var/xeno_disarm_chance = 85
var/list/force_modules = list()
var/allow_rename = TRUE
@@ -82,11 +85,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
var/lockcharge //Used when locking down a borg to preserve cell charge
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/has_camera = TRUE
var/pdahide = 0 //Used to hide the borg from the messenger list
var/tracking_entities = 0 //The number of known entities currently accessing the internal camera
var/braintype = "Cyborg"
var/base_icon = ""
var/crisis = 0
var/modules_break = TRUE
var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
@@ -96,6 +100,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
hud_possible = list(SPECIALROLE_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD)
var/default_cell_type = /obj/item/stock_parts/cell/high
var/magpulse = 0
var/ionpulse = 0 // Jetpack-like effect.
var/ionpulse_on = 0 // Jetpack-like effect.
@@ -107,7 +112,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/mob/living/silicon/robot/get_cell()
return cell
/mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0)
/mob/living/silicon/robot/New(loc, syndie = FALSE, unfinished = FALSE, alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -129,9 +134,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
radio = new /obj/item/radio/borg(src)
common_radio = radio
init()
init(ai_to_sync_to = ai_to_sync_to)
if(!scrambledcodes && !camera)
if(has_camera && !camera)
camera = new /obj/machinery/camera(src)
camera.c_tag = real_name
camera.network = list("SS13","Robots")
@@ -143,7 +148,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
mmi.icon_state = "boris"
if(!cell) // Make sure a new cell gets created *before* executing initialize_components(). The cell component needs an existing cell for it to get set up properly
cell = new /obj/item/stock_parts/cell/high(src)
cell = new default_cell_type(src)
initialize_components()
//if(!unfinished)
@@ -167,14 +172,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
scanner = new(src)
scanner.Grant(src)
/mob/living/silicon/robot/proc/init(var/alien=0)
/mob/living/silicon/robot/proc/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
make_laws()
additional_law_channels["Binary"] = ":b "
var/new_ai = select_active_ai_with_fewest_borgs()
if(new_ai)
var/found_ai = ai_to_sync_to
if(!found_ai)
found_ai = select_active_ai_with_fewest_borgs()
if(found_ai)
lawupdate = 1
connect_to_ai(new_ai)
connect_to_ai(found_ai)
else
lawupdate = 0
@@ -234,7 +241,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(custom_name)
return 0
if(!allow_rename)
to_chat(src, "<span class='warning'>Rename functionality is not enabled on this unit.</span>");
to_chat(src, "<span class='warning'>Rename functionality is not enabled on this unit.</span>")
return 0
rename_self(braintype, 1)
@@ -287,12 +294,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
/mob/living/silicon/robot/proc/pick_module()
if(module)
return
var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
var/list/modules = list("Generalist", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
if(islist(force_modules) && force_modules.len)
modules = force_modules.Copy()
if(GLOB.security_level == (SEC_LEVEL_GAMMA || SEC_LEVEL_EPSILON) || crisis)
to_chat(src, "<span class='warning'>Crisis mode active. The combat module is now available.</span>")
modules += "Combat"
if(mmi != null && mmi.alien)
modules = list("Hunter")
modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
@@ -305,9 +309,9 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
return
switch(modtype)
if("Standard")
if("Generalist")
module = new /obj/item/robot_module/standard(src)
module.channels = list("Service" = 1)
module.channels = list("Engineering" = 1, "Medical" = 1, "Security" = 1, "Service" = 1)
module_sprites["Basic"] = "robot_old"
module_sprites["Android"] = "droid"
module_sprites["Default"] = "Standard"
@@ -328,7 +332,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if("Miner")
module = new /obj/item/robot_module/miner(src)
module.channels = list("Supply" = 1)
if(camera && "Robots" in camera.network)
if(camera && ("Robots" in camera.network))
camera.network.Add("Mining Outpost")
module_sprites["Basic"] = "Miner_old"
module_sprites["Advanced Droid"] = "droid-miner"
@@ -336,11 +340,12 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
module_sprites["Standard"] = "Standard-Mine"
module_sprites["Noble-DIG"] = "Noble-DIG"
module_sprites["Cricket"] = "Cricket-MINE"
module_sprites["Lavaland"] = "lavaland"
if("Medical")
module = new /obj/item/robot_module/medical(src)
module.channels = list("Medical" = 1)
if(camera && "Robots" in camera.network)
if(camera && ("Robots" in camera.network))
camera.network.Add("Medical")
module_sprites["Basic"] = "Medbot"
module_sprites["Surgeon"] = "surgeon"
@@ -352,6 +357,17 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
status_flags &= ~CANPUSH
if("Security")
if(!weapons_unlock)
var/count_secborgs = 0
for(var/mob/living/silicon/robot/R in GLOB.alive_mob_list)
if(R && R.stat != DEAD && R.module && istype(R.module, /obj/item/robot_module/security))
count_secborgs++
var/max_secborgs = 2
if(GLOB.security_level == SEC_LEVEL_GREEN)
max_secborgs = 1
if(count_secborgs >= max_secborgs)
to_chat(src, "<span class='warning'>There are too many Security cyborgs active. Please choose another module.</span>")
return
module = new /obj/item/robot_module/security(src)
module.channels = list("Security" = 1)
module_sprites["Basic"] = "secborg"
@@ -366,7 +382,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if("Engineering")
module = new /obj/item/robot_module/engineering(src)
module.channels = list("Engineering" = 1)
if(camera && "Robots" in camera.network)
if(camera && ("Robots" in camera.network))
camera.network.Add("Engineering")
module_sprites["Basic"] = "Engineering"
module_sprites["Antique"] = "engineerrobot"
@@ -386,10 +402,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
module_sprites["Noble-CLN"] = "Noble-CLN"
module_sprites["Cricket"] = "Cricket-JANI"
if("Combat")
module = new /obj/item/robot_module/combat(src)
if("Destroyer") // Rolling Borg
module = new /obj/item/robot_module/destroyer(src)
module.channels = list("Security" = 1)
icon_state = "droidcombat"
status_flags &= ~CANPUSH
if("Combat") // Gamma ERT
module = new /obj/item/robot_module/combat(src)
icon_state = "ertgamma"
status_flags &= ~CANPUSH
if("Hunter")
module = new /obj/item/robot_module/alien/hunter(src)
@@ -441,6 +463,8 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
ionpulse = FALSE
magpulse = FALSE
add_language("Robot Talk", 1)
if("lava" in weather_immunities) // Remove the lava-immunity effect given by a printable upgrade
weather_immunities -= "lava"
status_flags |= CANPUSH
@@ -840,7 +864,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
return
else
sleep(6)
emagged = 1
SetEmagged(TRUE)
SetLockdown(1) //Borgs were getting into trouble because they would attack the emagger before the new laws were shown
if(src.hud_used)
src.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open.
@@ -915,7 +939,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
return 0
/mob/living/silicon/robot/update_icons()
overlays.Cut()
if(stat != DEAD && !(paralysis || stunned || IsWeakened() || low_power_mode)) //Not dead, not stunned.
if(custom_panel in custom_eye_names)
@@ -924,36 +947,24 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
overlays += "eyes-[icon_state]"
else
overlays -= "eyes"
if(opened)
var/panelprefix = "ov"
if(custom_sprite) //Custom borgs also have custom panels, heh
panelprefix = "[ckey]"
if(custom_panel in custom_panel_names) //For default borgs with different panels
panelprefix = custom_panel
if(wiresexposed)
overlays += "[panelprefix]-openpanel +w"
else if(cell)
overlays += "[panelprefix]-openpanel +c"
else
overlays += "[panelprefix]-openpanel -c"
var/combat = list("Combat")
if(modtype in combat)
if(base_icon == "")
base_icon = icon_state
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
icon_state = "[base_icon]-roll"
else
icon_state = base_icon
if(module)
for(var/obj/item/borg/combat/shield/S in module.modules)
if(activated(S))
overlays += "[base_icon]-shield"
borg_icons()
update_fire()
/mob/living/silicon/robot/proc/borg_icons() // Exists so that robot/destroyer can override it
return
/mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock)
to_chat(src, "<span class='warning'>Weapon lock active, unable to use modules! Count:[weaponlock_time]</span>")
@@ -1133,13 +1144,13 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(!updating)
updating = 1
spawn(BORG_CAMERA_BUFFER)
if(oldLoc != src.loc)
if(camera && oldLoc != src.loc)
GLOB.cameranet.updatePortableCamera(src.camera)
updating = 0
if(module)
if(module.type == /obj/item/robot_module/janitor)
var/turf/tile = loc
if(isturf(tile))
if(stat != DEAD && isturf(tile))
var/floor_only = TRUE
for(var/A in tile)
if(istype(A, /obj/effect))
@@ -1157,16 +1168,16 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
if(cleaned_human.lying)
if(cleaned_human.head)
cleaned_human.head.clean_blood()
cleaned_human.update_inv_head(0,0)
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
cleaned_human.wear_suit.clean_blood()
cleaned_human.update_inv_wear_suit(0,0)
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
cleaned_human.w_uniform.clean_blood()
cleaned_human.update_inv_w_uniform(0,0)
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
cleaned_human.shoes.clean_blood()
cleaned_human.update_inv_shoes(0,0)
cleaned_human.update_inv_shoes()
cleaned_human.clean_blood()
to_chat(cleaned_human, "<span class='danger'>[src] cleans your face!</span>")
if(floor_only)
@@ -1308,56 +1319,52 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
..()
update_module_icon()
/mob/living/silicon/robot/emp_act(severity)
if(emp_protection)
return
..()
switch(severity)
if(1)
disable_component("comms", 160)
if(2)
disable_component("comms", 60)
/mob/living/silicon/robot/deathsquad
base_icon = "nano_bloodhound"
icon_state = "nano_bloodhound"
designation = "SpecOps"
lawupdate = 0
scrambledcodes = 1
has_camera = FALSE
req_one_access = list(ACCESS_CENT_SPECOPS)
ionpulse = 1
magpulse = 1
pdahide = 1
eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
ear_protection = 1 // Immunity to the audio part of flashbangs
damage_protection = 10 // Reduce all incoming damage by this number
xeno_disarm_chance = 20
allow_rename = FALSE
modtype = "Commando"
faction = list("nanotrasen")
is_emaggable = FALSE
default_cell_type = /obj/item/stock_parts/cell/bluespace
/mob/living/silicon/robot/deathsquad/New(loc)
..()
cell = new /obj/item/stock_parts/cell/hyper(src)
/mob/living/silicon/robot/deathsquad/init()
/mob/living/silicon/robot/deathsquad/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/deathsquad
module = new /obj/item/robot_module/deathsquad(src)
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
radio = new /obj/item/radio/borg/deathsquad(src)
radio.recalculateChannels()
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/combat
base_icon = "droidcombat"
icon_state = "droidcombat"
modtype = "Combat"
designation = "Combat"
/mob/living/silicon/robot/deathsquad/bullet_act(var/obj/item/projectile/P)
if(istype(P) && P.is_reflectable && P.starting)
visible_message("<span class='danger'>The [P.name] gets reflected by [src]!</span>", "<span class='userdanger'>The [P.name] gets reflected by [src]!</span>")
P.reflect_back(src)
return -1
return ..(P)
/mob/living/silicon/robot/combat/init()
..()
module = new /obj/item/robot_module/combat(src)
module.channels = list("Security" = 1)
//languages
module.add_languages(src)
//subsystems
module.add_subsystems_and_actions(src)
status_flags &= ~CANPUSH
radio.config(module.channels)
notify_ai(2)
/mob/living/silicon/robot/ert
designation = "ERT"
@@ -1365,24 +1372,24 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
scrambledcodes = 1
req_one_access = list(ACCESS_CENT_SPECOPS)
ionpulse = 1
force_modules = list("Engineering", "Medical", "Security")
static_radio_channels = 1
allow_rename = FALSE
weapons_unlock = TRUE
default_cell_type = /obj/item/stock_parts/cell/super
var/eprefix = "Amber"
/mob/living/silicon/robot/ert/init()
/mob/living/silicon/robot/ert/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
laws = new /datum/ai_laws/ert_override
radio = new /obj/item/radio/borg/ert(src)
radio.recalculateChannels()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
/mob/living/silicon/robot/ert/New(loc, cyborg_unlock)
/mob/living/silicon/robot/ert/New(loc)
..(loc)
cell = new /obj/item/stock_parts/cell/hyper(src)
var/rnum = rand(1,1000)
var/borgname = "ERT [rnum]"
var/borgname = "[eprefix] ERT [rnum]"
name = borgname
custom_name = borgname
real_name = name
@@ -1391,22 +1398,64 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
mind.original = src
mind.assigned_role = SPECIAL_ROLE_ERT
mind.special_role = SPECIAL_ROLE_ERT
if(cyborg_unlock)
crisis = 1
if(!(mind in SSticker.minds))
SSticker.minds += mind
SSticker.mode.ert += mind
/mob/living/silicon/robot/ert/gamma
crisis = 1
/mob/living/silicon/robot/emp_act(severity)
/mob/living/silicon/robot/ert/red
eprefix = "Red"
default_cell_type = /obj/item/stock_parts/cell/hyper
/mob/living/silicon/robot/ert/gamma
default_cell_type = /obj/item/stock_parts/cell/bluespace
force_modules = list("Combat", "Engineering", "Medical")
damage_protection = 5 // Reduce all incoming damage by this number
eprefix = "Gamma"
magpulse = 1
xeno_disarm_chance = 40
/mob/living/silicon/robot/destroyer
// admin-only borg, the seraph / special ops officer of borgs
base_icon = "droidcombat"
icon_state = "droidcombat"
modtype = "Destroyer"
designation = "Destroyer"
lawupdate = 0
scrambledcodes = 1
has_camera = FALSE
req_one_access = list(ACCESS_CENT_SPECOPS)
ionpulse = 1
magpulse = 1
pdahide = 1
eye_protection = 2 // Immunity to flashes and the visual part of flashbangs
ear_protection = 1 // Immunity to the audio part of flashbangs
emp_protection = TRUE // Immunity to EMP, due to heavy shielding
damage_protection = 20 // Reduce all incoming damage by this number. Very high in the case of /destroyer borgs, since it is an admin-only borg.
xeno_disarm_chance = 10
default_cell_type = /obj/item/stock_parts/cell/bluespace
/mob/living/silicon/robot/destroyer/init(alien = FALSE, mob/living/silicon/ai/ai_to_sync_to = null)
..()
switch(severity)
if(1)
disable_component("comms", 160)
if(2)
disable_component("comms", 60)
module = new /obj/item/robot_module/destroyer(src)
module.add_languages(src)
module.add_subsystems_and_actions(src)
status_flags &= ~CANPUSH
if(radio)
qdel(radio)
radio = new /obj/item/radio/borg/ert/specops(src)
radio.recalculateChannels()
/mob/living/silicon/robot/destroyer/borg_icons()
if(base_icon == "")
base_icon = icon_state
if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
icon_state = "[base_icon]-roll"
else
icon_state = base_icon
overlays += "[base_icon]-shield"
/mob/living/silicon/robot/extinguish_light()
update_headlamp(1, 150)
@@ -1472,3 +1521,35 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
/// Used in `robot_bindings.dm` when the user presses "A" if on AZERTY mode, or "Q" on QWERTY mode.
/mob/living/silicon/robot/proc/on_drop_hotkey_press()
var/obj/item/gripper/G = get_active_hand()
if(istype(G) && G.gripped_item)
G.drop_gripped_item() // if the active module is a gripper, try to drop its held item.
else
uneq_active() // else unequip the module and put it back into the robot's inventory.
return
/mob/living/silicon/robot/proc/check_module_damage(makes_sound = TRUE)
if(modules_break)
if(health < 50) //Gradual break down of modules as more damage is sustained
if(uneq_module(module_state_3))
if(makes_sound)
audible_message("<span class='warning'>[src] sounds an alarm! \"SYSTEM ERROR: Module 3 OFFLINE.\"</span>")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 50, TRUE)
to_chat(src, "<span class='userdanger'>SYSTEM ERROR: Module 3 OFFLINE.</span>")
if(health < 0)
if(uneq_module(module_state_2))
if(makes_sound)
audible_message("<span class='warning'>[src] sounds an alarm! \"SYSTEM ERROR: Module 2 OFFLINE.\"</span>")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 60, TRUE)
to_chat(src, "<span class='userdanger'>SYSTEM ERROR: Module 2 OFFLINE.</span>")
if(health < -50)
if(uneq_module(module_state_1))
if(makes_sound)
audible_message("<span class='warning'>[src] sounds an alarm! \"CRITICAL ERROR: All modules OFFLINE.\"</span>")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE)
to_chat(src, "<span class='userdanger'>CRITICAL ERROR: All modules OFFLINE.</span>")
@@ -1,12 +1,6 @@
/mob/living/silicon/robot/updatehealth(reason = "none given")
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
return
health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())
update_stat("updatehealth([reason])")
handle_hud_icons_health()
diag_hud_set_health()
..(reason)
check_module_damage()
/mob/living/silicon/robot/getBruteLoss(repairable_only = FALSE)
var/amount = 0
@@ -72,7 +66,7 @@
/mob/living/silicon/robot/heal_organ_damage(brute, burn, updating_health = TRUE)
var/list/datum/robot_component/parts = get_damaged_components(brute, burn)
if(!LAZYLEN(parts))
if(!LAZYLEN(parts))
return
var/datum/robot_component/picked = pick(parts)
picked.heal_damage(brute, burn, updating_health)
@@ -82,29 +76,6 @@
if(!LAZYLEN(components))
return
//Combat shielding absorbs a percentage of damage directly into the cell.
var/obj/item/borg/combat/shield/shield
if(module_state_1 && istype(module_state_1, /obj/item/borg/combat/shield))
shield = module_state_1
else if(module_state_2 && istype(module_state_2, /obj/item/borg/combat/shield))
shield = module_state_2
else if(module_state_3 && istype(module_state_3, /obj/item/borg/combat/shield))
shield = module_state_3
if(shield)
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute * shield.shield_level
var/absorb_burn = burn * shield.shield_level
var/cost = (absorb_brute+absorb_burn) * 100
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
to_chat(src, "<span class='warning'>Your shield has overloaded!</span>")
else
brute -= absorb_brute
burn -= absorb_burn
to_chat(src, "<span class='warning'>Your shield absorbs some of the impact!</span>")
var/datum/robot_component/armour/A = get_armour()
if(A)
A.take_damage(brute, burn, sharp, updating_health)
@@ -133,32 +104,15 @@
updatehealth("heal overall damage")
/mob/living/silicon/robot/take_overall_damage(brute = 0, burn = 0, updating_health = TRUE, used_weapon = null, sharp = 0)
if(status_flags & GODMODE) return //godmode
if(status_flags & GODMODE)
return
if(damage_protection)
brute = clamp(brute - damage_protection, 0, brute)
burn = clamp(burn - damage_protection, 0, burn)
var/list/datum/robot_component/parts = get_damageable_components()
//Combat shielding absorbs a percentage of damage directly into the cell.
var/obj/item/borg/combat/shield/shield
if(module_state_1 && istype(module_state_1, /obj/item/borg/combat/shield))
shield = module_state_1
else if(module_state_2 && istype(module_state_2, /obj/item/borg/combat/shield))
shield = module_state_2
else if(module_state_3 && istype(module_state_3, /obj/item/borg/combat/shield))
shield = module_state_3
if(shield)
//Shields absorb a certain percentage of damage based on their power setting.
var/absorb_brute = brute * shield.shield_level
var/absorb_burn = burn * shield.shield_level
var/cost = (absorb_brute+absorb_burn) * 100
cell.charge -= cost
if(cell.charge <= 0)
cell.charge = 0
to_chat(src, "<span class='warning'>Your shield has overloaded!</span>")
else
brute -= absorb_brute
burn -= absorb_burn
to_chat(src, "<span class='warning'>Your shield absorbs some of the impact!</span>")
var/datum/robot_component/armour/A = get_armour()
if(A)
A.take_damage(brute, burn, sharp)
@@ -2,7 +2,7 @@
if(M.a_intent == INTENT_DISARM)
if(!lying)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if(prob(85))
if(prob(xeno_disarm_chance))
Stun(7)
step(src, get_dir(M,src))
spawn(5)
@@ -73,24 +73,7 @@
/obj/item/borg
var/powerneeded // Percentage of power remaining required to run item
/obj/item/borg/combat/shield
name = "personal shielding"
desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
powerneeded = 25
var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
/obj/item/borg/combat/shield/verb/set_shield_level()
set name = "Set shield level"
set category = "Object"
set src in range(0)
var/N = input("How much damage should the shield absorb?") in list("5","10","25","50","75","100")
if(N)
shield_level = text2num(N)/100
/obj/item/borg/combat/mobility
/obj/item/borg/destroyer/mobility
name = "mobility module"
desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
icon = 'icons/obj/decals.dmi'
@@ -118,20 +118,48 @@
return
/obj/item/robot_module/standard
name = "standard robot module"
// if station is fine, assist with constructing station goal room, cleaning, and repairing cables chewed by rats
// if medical crisis, assist by providing basic healthcare, retrieving corpses, and monitoring crew lifesigns
// if eng crisis, assist by helping repair hull breaches
// if sec crisis, assist by opening doors for sec and providing backup zipties on patrols
name = "generalist robot module"
module_type = "Standard"
subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor, /mob/living/silicon/proc/subsystem_crew_monitor)
stacktypes = list(
/obj/item/stack/sheet/metal/cyborg = 50,
/obj/item/stack/cable_coil/cyborg = 50,
/obj/item/stack/rods/cyborg = 60,
/obj/item/stack/tile/plasteel = 20
)
/obj/item/robot_module/standard/New()
..()
modules += new /obj/item/melee/baton/loaded(src)
modules += new /obj/item/extinguisher(src)
modules += new /obj/item/wrench/cyborg(src)
// sec
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
// janitorial
modules += new /obj/item/soap/nanotrasen(src)
modules += new /obj/item/lightreplacer/cyborg(src)
// eng
modules += new /obj/item/crowbar/cyborg(src)
modules += new /obj/item/wrench/cyborg(src)
modules += new /obj/item/extinguisher(src) // for firefighting, and propulsion in space
modules += new /obj/item/weldingtool/largetank/cyborg(src)
// mining
modules += new /obj/item/pickaxe(src)
modules += new /obj/item/t_scanner/adv_mining_scanner(src)
modules += new /obj/item/storage/bag/ore/cyborg(src)
// med
modules += new /obj/item/healthanalyzer(src)
modules += new /obj/item/reagent_containers/borghypo/basic(src)
modules += new /obj/item/roller_holder(src) // for taking the injured to medbay without worsening their injuries or leaving a blood trail the whole way
emag = new /obj/item/melee/energy/sword/cyborg(src)
for(var/G in stacktypes)
var/obj/item/stack/sheet/M = new G(src)
M.amount = stacktypes[G]
modules += M
fix_modules()
/obj/item/robot_module/medical
name = "medical robot module"
module_type = "Medical"
@@ -230,7 +258,7 @@
/obj/item/robot_module/engineering/handle_death()
var/obj/item/gripper/G = locate(/obj/item/gripper) in modules
if(G)
G.drop_item()
G.drop_gripped_item(silent = TRUE)
/obj/item/robot_module/security
name = "security robot module"
@@ -259,6 +287,7 @@
modules += new /obj/item/mop/advanced/cyborg(src)
modules += new /obj/item/lightreplacer/cyborg(src)
modules += new /obj/item/holosign_creator(src)
modules += new /obj/item/extinguisher/mini(src)
emag = new /obj/item/reagent_containers/spray(src)
emag.reagents.add_reagent("lube", 250)
@@ -483,25 +512,44 @@
fix_modules()
/obj/item/robot_module/combat
name = "combat robot module"
/obj/item/robot_module/destroyer
name = "destroyer robot module"
module_type = "Malf"
module_actions = list(
/datum/action/innate/robot_sight/thermal,
)
/obj/item/robot_module/destroyer/New()
..()
modules += new /obj/item/gun/energy/immolator/multi/cyborg(src) // See comments on /robot_module/combat below
modules += new /obj/item/melee/baton/loaded(src) // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
modules += new /obj/item/pickaxe/drill/jackhammer(src) // for breaking walls to execute flanking moves
modules += new /obj/item/borg/destroyer/mobility(src)
emag = null
fix_modules()
/obj/item/robot_module/combat
name = "combat robot module"
module_type = "Malf"
module_actions = list()
/obj/item/robot_module/combat/New()
..()
modules += new /obj/item/gun/energy/immolator/multi/cyborg(src) // primary weapon, strong at close range (ie: against blob/terror/xeno), but consumes a lot of energy per shot.
// Borg gets 40 shots of this weapon. Gamma Sec ERT gets 10.
// So, borg has way more burst damage, but also takes way longer to recharge / get back in the fight once depleted. Has to find a borg recharger and sit in it for ages.
// Organic gamma sec ERT carries alternate weapons, including a box of flashbangs, and can load up on a huge number of guns from science. Borg cannot do either.
// Overall, gamma borg has higher skill floor but lower skill ceiling.
modules += new /obj/item/melee/baton/loaded(src) // secondary weapon, for things immune to burn, immune to ranged weapons, or for arresting low-grade threats
modules += new /obj/item/restraints/handcuffs/cable/zipties/cyborg(src)
modules += new /obj/item/gun/energy/gun/cyborg(src)
modules += new /obj/item/pickaxe/drill/jackhammer(src)
modules += new /obj/item/borg/combat/shield(src)
modules += new /obj/item/borg/combat/mobility(src)
modules += new /obj/item/wrench/cyborg(src)
emag = new /obj/item/gun/energy/lasercannon/cyborg(src)
modules += new /obj/item/pickaxe/drill/jackhammer(src) // for breaking walls to execute flanking moves
emag = null
fix_modules()
/obj/item/robot_module/alien/hunter
name = "alien hunter module"
module_type = "Standard"
@@ -578,7 +626,7 @@
/obj/item/robot_module/drone/handle_death()
var/obj/item/gripper/G = locate(/obj/item/gripper) in modules
if(G)
G.drop_item()
G.drop_gripped_item(silent = TRUE)
//checks whether this item is a module of the robot it is located in.
/obj/item/proc/is_robot_module()
@@ -9,7 +9,7 @@
/mob/living/silicon/robot/movement_delay()
. = ..()
. += speed
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
if(module_active && istype(module_active,/obj/item/borg/destroyer/mobility))
. -= 3
. += config.robot_delay

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