mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-25 21:19:00 +01:00
Merge remote-tracking branch 'upstream/master' into logging-improvements-V2
This commit is contained in:
@@ -14,3 +14,8 @@
|
||||
|
||||
/mob/camera/experience_pressure_difference()
|
||||
return
|
||||
|
||||
/mob/camera/forceMove(atom/destination)
|
||||
var/oldloc = loc
|
||||
loc = destination
|
||||
Moved(oldloc, NONE)
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
var/atom/movable/mob_container
|
||||
mob_container = M
|
||||
mob_container.forceMove(get_turf(src))
|
||||
M.reset_perspective()
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user