12/21 modernizations from TG live (#103)
* sync (#3) * shuttle auto call * Merge /vore into /master (#39) * progress * Compile errors fixed No idea if it's test worthy tho as conflicts with race overhaul and narky removal. * Update admins.txt * efforts continue Fuck grab code, seriously * grab code is cancer * Execute the Narkism Do not hesitate. Show no mercy. * holy shit grab code is awful * have I bitched about grab code My bitching, let me show you it * código de agarre es una mierda No really it is * yeah I don't even know anymore. * Lolnope. Fuck grab code * I'm not even sure what to fix anymore * Self eating is not an acceptable fate * Taste the void, son. * My code doesn't pass it's own sanity check. Maybe it's a sign of things to come. * uncommented and notes * It Works and I Don't Know Why (#38) * shuttle auto call * it works and I don't know why * Subsystem 12/21 Most Recent TG subsystem folder * globalvars 12/21 Tossed out the flavor_misc and parallax files * Onclick 12/21 as well as .dme updates * _defines 12/21 ommited old _MC.dm * _HELPERS 12/21 Preserved snowflake placement of furry sprites * _defeines/genetics reapplied narkism holdover for snowflake races. * Oops forgot mutant colors * modules porting 12/21 + Sounds/icons Admin, Client and most of mob life files ommitted * enviroment file * Admin optimizations ahelp log system kept * Mob ports 12/21 Flavor text preserved * datums ported 12/21 * Game ported 12/21 * batch of duplicate fixes/dogborg work Dogborgs need to be modernized to refractored borg standards. * moar fixes * Maps and futher compile fixes
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
ghost_others = client.prefs.ghost_others
|
||||
var/preferred_form = null
|
||||
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
if(IsAdminGhost(src))
|
||||
has_unlimited_silicon_privilege = 1
|
||||
|
||||
if(client.prefs.unlock_content)
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
/mob/dead/observer/Logout()
|
||||
if (client)
|
||||
client.images -= ghost_darkness_images
|
||||
if(observetarget)
|
||||
if(ismob(observetarget))
|
||||
var/mob/target = observetarget
|
||||
if(target.observers)
|
||||
target.observers -= src
|
||||
UNSETEMPTY(target.observers)
|
||||
observetarget = null
|
||||
..()
|
||||
spawn(0)
|
||||
if(src && !key) //we've transferred to another mob. This ghost should be deleted.
|
||||
|
||||
@@ -31,6 +31,7 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
|
||||
var/image/ghostimage_simple = null //this mob with the simple white ghost sprite
|
||||
var/ghostvision = 1 //is the ghost able to see things humans can't?
|
||||
var/seedarkness = 1
|
||||
var/mob/observetarget = null //The target mob that the ghost is observing. Used as a reference in logout()
|
||||
var/ghost_hud_enabled = 1 //did this ghost disable the on-screen HUD?
|
||||
var/data_huds_on = 0 //Are data HUDs currently enabled?
|
||||
var/list/datahuds = list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC) //list of data HUDs shown to ghosts.
|
||||
@@ -57,10 +58,10 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
|
||||
|
||||
/mob/dead/observer/New(mob/body)
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
|
||||
|
||||
if(global.cross_allowed)
|
||||
verbs += /mob/dead/observer/proc/server_hop
|
||||
|
||||
|
||||
ghostimage = image(src.icon,src,src.icon_state)
|
||||
if(icon_state in ghost_forms_with_directions_list)
|
||||
ghostimage_default = image(src.icon,src,src.icon_state + "_nodir")
|
||||
@@ -89,10 +90,10 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
|
||||
mind = body.mind //we don't transfer the mind but we keep a reference to it.
|
||||
if(ishuman(body))
|
||||
var/mob/living/carbon/human/body_human = body
|
||||
if(HAIR in body_human.dna.species.specflags)
|
||||
if(HAIR in body_human.dna.species.species_traits)
|
||||
hair_style = body_human.hair_style
|
||||
hair_color = brighten_color(body_human.hair_color)
|
||||
if(FACEHAIR in body_human.dna.species.specflags)
|
||||
if(FACEHAIR in body_human.dna.species.species_traits)
|
||||
facial_hair_style = body_human.facial_hair_style
|
||||
facial_hair_color = brighten_color(body_human.facial_hair_color)
|
||||
|
||||
@@ -117,11 +118,13 @@ var/list/image/ghost_images_simple = list() //this is a list of all ghost images
|
||||
var/old_color = color
|
||||
color = "#960000"
|
||||
animate(src, color = old_color, time = 10)
|
||||
addtimer(src, "update_atom_colour", 10)
|
||||
|
||||
/mob/dead/observer/ratvar_act()
|
||||
var/old_color = color
|
||||
color = "#FAE48C"
|
||||
animate(src, color = old_color, time = 10)
|
||||
addtimer(src, "update_atom_colour", 10)
|
||||
|
||||
/mob/dead/observer/Destroy()
|
||||
ghost_images_full -= ghostimage
|
||||
@@ -256,11 +259,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
if(mental_dominator)
|
||||
src << "<span class='warning'>This body's force of will is too strong! You can't break it enough to force them into a catatonic state.</span>"
|
||||
if(mind_control_holder)
|
||||
mind_control_holder << "<span class='userdanger'>Through tremendous force of will, you stop a catatonia attempt!</span>"
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
succumb()
|
||||
if(stat == DEAD)
|
||||
@@ -280,7 +278,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
loc = NewLoc
|
||||
for(var/obj/effect/step_trigger/S in NewLoc)
|
||||
S.Crossed(src)
|
||||
|
||||
update_parallax_contents()
|
||||
return
|
||||
loc = get_turf(src) //Get out of closets and such as a ghost
|
||||
if((direct & NORTH) && y < world.maxy)
|
||||
@@ -302,11 +300,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Station Time: [worldtime2text()]")
|
||||
if(ticker)
|
||||
if(ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(ticker && ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(istype(ticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = ticker.mode
|
||||
if(B.message_sent)
|
||||
stat(null, "Blobs to Blob Win: [blobs_legit.len]/[B.blobwincount]")
|
||||
|
||||
/mob/dead/observer/verb/reenter_corpse()
|
||||
set category = "Ghost"
|
||||
@@ -336,9 +337,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
A.icon = ui_style2icon(client.prefs.UI_style)
|
||||
A.desc = message
|
||||
var/old_layer = source.layer
|
||||
var/old_plane = source.plane
|
||||
source.layer = FLOAT_LAYER
|
||||
source.plane = FLOAT_PLANE
|
||||
A.add_overlay(source)
|
||||
source.layer = old_layer
|
||||
source.plane = old_plane
|
||||
src << "<span class='ghostalert'><a href=?src=\ref[src];reenter=1>(Click to re-enter)</a></span>"
|
||||
if(sound)
|
||||
src << sound(sound)
|
||||
@@ -347,7 +351,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set category = "Ghost"
|
||||
set name = "Teleport"
|
||||
set desc= "Teleport to a location"
|
||||
if(!istype(usr, /mob/dead/observer))
|
||||
if(!isobserver(usr))
|
||||
usr << "Not when you're not dead!"
|
||||
return
|
||||
var/A
|
||||
@@ -364,6 +368,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
usr << "No area available."
|
||||
|
||||
usr.loc = pick(L)
|
||||
update_parallax_contents()
|
||||
|
||||
/mob/dead/observer/verb/follow()
|
||||
set category = "Ghost"
|
||||
@@ -385,7 +390,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
var/orbitsize = (I.Width()+I.Height())*0.5
|
||||
orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
|
||||
|
||||
if(orbiting != target)
|
||||
if(orbiting && orbiting.orbiting != target)
|
||||
src << "<span class='notice'>Now orbiting [target].</span>"
|
||||
|
||||
var/rot_seg
|
||||
@@ -405,20 +410,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
orbit(target,orbitsize, FALSE, 20, rot_seg)
|
||||
|
||||
/mob/dead/observer/orbit()
|
||||
setDir(2 )//reset dir so the right directional sprites show up
|
||||
setDir(2)//reset dir so the right directional sprites show up
|
||||
..()
|
||||
|
||||
/mob/dead/observer/stop_orbit()
|
||||
..()
|
||||
//restart our floating animation after orbit is done.
|
||||
sleep 2 //orbit sets up a 2ds animation when it finishes, so we wait for that to end
|
||||
if (!orbiting) //make sure another orbit hasn't started
|
||||
pixel_y = 0
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
pixel_y = 0
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
|
||||
/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"
|
||||
set desc = "Teleport to a mob"
|
||||
|
||||
if(istype(usr, /mob/dead/observer)) //Make sure they're an observer!
|
||||
if(isobserver(usr)) //Make sure they're an observer!
|
||||
|
||||
|
||||
var/list/dest = list() //List of possible destinations (mobs)
|
||||
@@ -436,6 +442,7 @@ 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.loc = T
|
||||
A.update_parallax_contents()
|
||||
else
|
||||
A << "This mob is not located in the game world."
|
||||
|
||||
@@ -490,13 +497,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
updateghostimages()
|
||||
|
||||
/proc/updateallghostimages()
|
||||
listclearnulls(ghost_images_full)
|
||||
listclearnulls(ghost_images_default)
|
||||
listclearnulls(ghost_images_simple)
|
||||
listclearnulls(ghost_darkness_images)
|
||||
|
||||
for (var/mob/dead/observer/O in player_list)
|
||||
O.updateghostimages()
|
||||
|
||||
/mob/dead/observer/proc/updateghostimages()
|
||||
if (!client)
|
||||
return
|
||||
|
||||
|
||||
if(lastsetting)
|
||||
switch(lastsetting) //checks the setting we last came from, for a little efficiency so we don't try to delete images from the client that it doesn't have anyway
|
||||
if(GHOST_OTHERS_THEIR_SETTING)
|
||||
@@ -543,7 +555,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(!target)
|
||||
return 0
|
||||
|
||||
if(istype (target, /mob/living/simple_animal/hostile/megafauna))
|
||||
if(ismegafauna(target))
|
||||
src << "<span class='warning'>This creature is too powerful for you to possess!</span>"
|
||||
return 0
|
||||
|
||||
@@ -555,6 +567,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return 0
|
||||
|
||||
target.key = key
|
||||
target.faction = list("neutral")
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/proc/server_hop()
|
||||
@@ -563,7 +576,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set desc= "Jump to the other server"
|
||||
if (alert(src, "Jump to server running at [global.cross_address]?", "Server Hop", "Yes", "No") != "Yes")
|
||||
return 0
|
||||
if (client && global.cross_allowed)
|
||||
if (client && global.cross_allowed)
|
||||
src << "<span class='notice'>Sending you to [global.cross_address].</span>"
|
||||
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
|
||||
client << link(global.cross_address)
|
||||
@@ -656,10 +669,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(client.prefs.be_random_body)
|
||||
client.prefs.random_character(gender)
|
||||
|
||||
if(HAIR in client.prefs.pref_species.specflags)
|
||||
if(HAIR in client.prefs.pref_species.species_traits)
|
||||
hair_style = client.prefs.hair_style
|
||||
hair_color = brighten_color(client.prefs.hair_color)
|
||||
if(FACEHAIR in client.prefs.pref_species.specflags)
|
||||
if(FACEHAIR in client.prefs.pref_species.species_traits)
|
||||
facial_hair_style = client.prefs.facial_hair_style
|
||||
facial_hair_color = brighten_color(client.prefs.facial_hair_color)
|
||||
|
||||
@@ -673,7 +686,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/dead/observer/is_literate()
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/on_varedit(var_name)
|
||||
/mob/dead/observer/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
switch(var_name)
|
||||
if("icon")
|
||||
@@ -691,3 +704,56 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
else
|
||||
verbs -= /mob/dead/observer/verb/boo
|
||||
verbs -= /mob/dead/observer/verb/possess
|
||||
|
||||
/mob/dead/observer/reset_perspective(atom/A)
|
||||
if(client)
|
||||
if(ismob(client.eye) && (client.eye != src))
|
||||
var/mob/target = client.eye
|
||||
observetarget = null
|
||||
if(target.observers)
|
||||
target.observers -= src
|
||||
UNSETEMPTY(target.observers)
|
||||
if(..())
|
||||
if(hud_used)
|
||||
client.screen = list()
|
||||
hud_used.show_hud(hud_used.hud_version)
|
||||
|
||||
/mob/dead/observer/verb/observe()
|
||||
set name = "Observe"
|
||||
set category = "OOC"
|
||||
|
||||
var/list/creatures = getpois()
|
||||
|
||||
reset_perspective(null)
|
||||
|
||||
var/eye_name = null
|
||||
|
||||
eye_name = input("Please, select a player!", "Observe", null, null) as null|anything in creatures
|
||||
|
||||
if (!eye_name)
|
||||
return
|
||||
|
||||
var/mob/mob_eye = creatures[eye_name]
|
||||
//Istype so we filter out points of interest that are not mobs
|
||||
if(client && mob_eye && istype(mob_eye))
|
||||
client.eye = mob_eye
|
||||
client.screen = list()
|
||||
if(mob_eye.hud_used)
|
||||
LAZYINITLIST(mob_eye.observers)
|
||||
mob_eye.observers |= src
|
||||
mob_eye.hud_used.show_hud(1,src)
|
||||
observetarget = mob_eye
|
||||
|
||||
/mob/dead/observer/verb/register_pai_candidate()
|
||||
set category = "Ghost"
|
||||
set name = "pAI Setup"
|
||||
set desc = "Upload a fragment of your personality to the global pAI databanks"
|
||||
|
||||
register_pai()
|
||||
|
||||
/mob/dead/observer/proc/register_pai()
|
||||
if(istype(src, /mob/dead/observer))
|
||||
if(SSpai)
|
||||
SSpai.recruitWindow(src)
|
||||
else
|
||||
usr << "Can't become a pAI candidate while not dead!"
|
||||
|
||||
@@ -6,25 +6,13 @@
|
||||
|
||||
log_say("Ghost/[src.key] : [message]")
|
||||
|
||||
if(jobban_isbanned(src, "OOC"))
|
||||
src << "<span class='danger'>You have been banned from deadchat.</span>"
|
||||
return
|
||||
|
||||
if (src.client)
|
||||
if(src.client.prefs.muted & MUTE_DEADCHAT)
|
||||
src << "<span class='danger'>You cannot talk in deadchat (muted).</span>"
|
||||
return
|
||||
|
||||
if (src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
. = src.say_dead(message)
|
||||
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
if(radio_freq)
|
||||
var/atom/movable/virtualspeaker/V = speaker
|
||||
|
||||
if(istype(V.source, /mob/living/silicon/ai))
|
||||
if(isAI(V.source))
|
||||
var/mob/living/silicon/ai/S = V.source
|
||||
speaker = S.eyeobj
|
||||
else
|
||||
|
||||
+100
-81
@@ -72,6 +72,9 @@
|
||||
var/forceProcess = 0
|
||||
var/processTime = 8
|
||||
var/lastProc = 0
|
||||
var/walkdebug = 0 //causes sparks in our path target. used for debugging
|
||||
var/debugexamine = 0 //If we show debug info in our examine
|
||||
var/showexaminetext = 1 //If we show our telltale examine text
|
||||
|
||||
var/list/knownStrings = list()
|
||||
|
||||
@@ -136,13 +139,14 @@
|
||||
retal = 1
|
||||
retal_target = user
|
||||
|
||||
/mob/living/carbon/human/interactive/bullet_act(var/obj/item/projectile/P)
|
||||
/mob/living/carbon/human/interactive/bullet_act(obj/item/projectile/P, def_zone)
|
||||
var/potentialAssault = locate(/mob/living) in view(2,P.starting)
|
||||
if(potentialAssault)
|
||||
retal = 1
|
||||
retal_target = potentialAssault
|
||||
..()
|
||||
|
||||
|
||||
/client/proc/resetSNPC(var/mob/A in SSnpc.botPool_l)
|
||||
set name = "Reset SNPC"
|
||||
set desc = "Reset the SNPC"
|
||||
@@ -295,11 +299,9 @@
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/4))
|
||||
BP.change_bodypart_status(ORGAN_ROBOTIC)
|
||||
BP.change_bodypart_status(BODYPART_ROBOTIC)
|
||||
update_icons()
|
||||
update_damage_overlays(0)
|
||||
|
||||
hand = 0
|
||||
update_damage_overlays()
|
||||
functions = list("nearbyscan","combat","shitcurity","chatter") // stop customize adding multiple copies of a function
|
||||
//job specific favours
|
||||
switch(myjob.title)
|
||||
@@ -374,8 +376,8 @@
|
||||
var/datum/objective_item/steal/S = new A
|
||||
traitorTarget = locate(S.targetitem) in world
|
||||
if(SNPC_MARTYR) // MY LIFE FOR SPESZUL
|
||||
var/targetType = pick(/obj/structure/particle_accelerator,/obj/machinery/gravity_generator/main,/obj/machinery/power/smes)
|
||||
traitorTarget = locate(targetType) in world
|
||||
var/targetType = pick(/obj/machinery/gravity_generator/main/station,/obj/machinery/power/smes/engineering,/obj/machinery/telecomms/hub)
|
||||
traitorTarget = locate(targetType) in machines
|
||||
if(SNPC_PSYCHO) // YOU'RE LIKE A FLESH BICYLE AND I WANT TO DISMANTLE YOU
|
||||
traitorTarget = null
|
||||
|
||||
@@ -409,9 +411,9 @@
|
||||
var/mob/living/carbon/human/M = target
|
||||
if(target)
|
||||
if(health > 0)
|
||||
if(M.a_intent == "help")
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
chatter()
|
||||
if(M.a_intent == "harm")
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
retal = 1
|
||||
retal_target = target
|
||||
|
||||
@@ -423,10 +425,6 @@
|
||||
if(C)
|
||||
retalTarget(C)
|
||||
|
||||
/mob/living/carbon/human/interactive/bullet_act(obj/item/projectile/P, def_zone)
|
||||
..(P,def_zone)
|
||||
retalTarget(P.firer)
|
||||
|
||||
/mob/living/carbon/human/interactive/attack_hand(mob/living/carbon/human/M)
|
||||
..(M)
|
||||
retalTarget(M)
|
||||
@@ -490,28 +488,35 @@
|
||||
if(other_hand)
|
||||
if(other_hand.loc != src)
|
||||
other_hand = null
|
||||
if(hand)
|
||||
if(!l_hand)
|
||||
|
||||
var/obj/item/L = get_item_for_held_index(1) //just going to hardcode SNPCs to 2 hands, for now.
|
||||
var/obj/item/R = get_item_for_held_index(2) //they're just VERY assume-y about 2 hands.
|
||||
if(active_hand_index == 1)
|
||||
if(!L)
|
||||
main_hand = null
|
||||
if(r_hand)
|
||||
if(R)
|
||||
swap_hands()
|
||||
else
|
||||
if(!r_hand)
|
||||
if(!R)
|
||||
main_hand = null
|
||||
if(l_hand)
|
||||
if(L)
|
||||
swap_hands()
|
||||
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/swap_hands()
|
||||
hand = !hand
|
||||
var/obj/item/T = other_hand
|
||||
main_hand = other_hand
|
||||
other_hand = T
|
||||
var/oindex = active_hand_index
|
||||
if(active_hand_index == 1)
|
||||
active_hand_index = 2
|
||||
else
|
||||
active_hand_index = 1
|
||||
main_hand = get_active_held_item()
|
||||
other_hand = get_item_for_held_index(oindex)
|
||||
update_hands = 1
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/take_to_slot(obj/item/G, var/hands=0)
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_l_hand,"right hand" = slot_r_hand)
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_hands,"right hand" = slot_hands)
|
||||
if(hands)
|
||||
slots = list ("left hand" = slot_l_hand,"right hand" = slot_r_hand)
|
||||
slots = list ("left hand" = slot_hands,"right hand" = slot_hands)
|
||||
G.loc = src
|
||||
if(G.force && G.force > best_force)
|
||||
best_force = G.force
|
||||
@@ -519,7 +524,7 @@
|
||||
update_hands = 1
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/insert_into_backpack()
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_l_hand,"right hand" = slot_r_hand)
|
||||
var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_hands,"right hand" = slot_hands)
|
||||
var/obj/item/I = get_item_by_slot(pick(slots))
|
||||
var/obj/item/weapon/storage/BP = get_item_by_slot(slot_back)
|
||||
if(back && BP && I)
|
||||
@@ -603,14 +608,16 @@
|
||||
D.open()
|
||||
|
||||
if(update_hands)
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
var/obj/item/r_hand = get_item_for_held_index(2)
|
||||
if(l_hand || r_hand)
|
||||
if(l_hand)
|
||||
hand = 1
|
||||
active_hand_index = 1
|
||||
main_hand = l_hand
|
||||
if(r_hand)
|
||||
other_hand = r_hand
|
||||
else if(r_hand)
|
||||
hand = 0
|
||||
active_hand_index = 2
|
||||
main_hand = r_hand
|
||||
if(l_hand) //this technically shouldnt occur, but its a redundancy
|
||||
other_hand = l_hand
|
||||
@@ -619,7 +626,7 @@
|
||||
|
||||
if(pulledby)
|
||||
if(Adjacent(pulledby))
|
||||
a_intent = "disarm"
|
||||
a_intent = INTENT_DISARM
|
||||
pulledby.attack_hand(src)
|
||||
inactivity_period = 10
|
||||
|
||||
@@ -658,12 +665,12 @@
|
||||
if(istype(TARGET, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = TARGET
|
||||
if(W.force >= best_force || prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2))
|
||||
if(!l_hand || !r_hand)
|
||||
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
|
||||
put_in_hands(W)
|
||||
else
|
||||
insert_into_backpack()
|
||||
else
|
||||
if(!l_hand || !r_hand)
|
||||
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
|
||||
put_in_hands(TARGET)
|
||||
else
|
||||
insert_into_backpack()
|
||||
@@ -753,8 +760,8 @@
|
||||
spawn(0)
|
||||
call(src,Proc)(src)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget)
|
||||
if(restrictedJob) // we're a job that has to stay in our home
|
||||
/mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget, override = 0)
|
||||
if(restrictedJob && !override) // we're a job that has to stay in our home
|
||||
if(!(get_turf(inTarget) in get_area_turfs(job2area(myjob))))
|
||||
TARGET = null
|
||||
return
|
||||
@@ -796,6 +803,13 @@
|
||||
if(!target)
|
||||
return 0
|
||||
|
||||
if(walkdebug)
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
|
||||
spark_system.set_up(5, 0, target)
|
||||
spark_system.attach(target)
|
||||
spark_system.start()
|
||||
|
||||
|
||||
if(myPath.len <= 0)
|
||||
myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, MAX_RANGE_FIND + 1, 250,1, id=Path_ID)
|
||||
|
||||
@@ -1065,27 +1079,27 @@
|
||||
if(change)
|
||||
HP.attackby(internalBeaker,src)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/GF = locate(/obj/item/weapon/reagent_containers/food/snacks/grown) in view(12,src)
|
||||
if(GF)
|
||||
if(!Adjacent(GF))
|
||||
tryWalk(get_turf(GF))
|
||||
else
|
||||
GF.attackby(internalBag,src)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/grown/GF = locate(/obj/item/weapon/reagent_containers/food/snacks/grown) in view(12,src)
|
||||
if(GF)
|
||||
if(!Adjacent(GF))
|
||||
tryWalk(get_turf(GF))
|
||||
else
|
||||
GF.attackby(internalBag,src)
|
||||
|
||||
if(internalBag.contents.len > 0)
|
||||
var/obj/machinery/smartfridge/SF = locate(/obj/machinery/smartfridge) in range(12,src)
|
||||
if(!Adjacent(SF))
|
||||
tryWalk(get_turf(SF))
|
||||
else
|
||||
customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], upending the [internalBag]'s contents all over the [SF]!")
|
||||
//smartfridges call updateUsrDialog when you call attackby, so we're going to have to cheese-magic-space this
|
||||
for(var/obj/toLoad in internalBag.contents)
|
||||
if(contents.len >= SF.max_n_of_items)
|
||||
break
|
||||
if(SF.accept_check(toLoad))
|
||||
SF.load(toLoad)
|
||||
else
|
||||
qdel(toLoad) // destroy everything we dont need
|
||||
if(internalBag.contents.len > 0)
|
||||
var/obj/machinery/smartfridge/SF = locate(/obj/machinery/smartfridge) in range(12,src)
|
||||
if(!Adjacent(SF))
|
||||
tryWalk(get_turf(SF), 1)
|
||||
else
|
||||
customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], upending the [internalBag]'s contents all over the [SF]!")
|
||||
//smartfridges call updateUsrDialog when you call attackby, so we're going to have to cheese-magic-space this
|
||||
for(var/obj/toLoad in internalBag.contents)
|
||||
if(contents.len >= SF.max_n_of_items)
|
||||
break
|
||||
if(SF.accept_check(toLoad))
|
||||
SF.load(toLoad)
|
||||
else
|
||||
qdel(toLoad) // destroy everything we dont need
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/bartend(obj)
|
||||
if(shouldModulePass())
|
||||
@@ -1144,11 +1158,11 @@
|
||||
var/mob/living/carbon/human/clownTarget
|
||||
var/list/clownPriority = list()
|
||||
|
||||
var/obj/item/weapon/reagent_containers/spray/S
|
||||
if(!locate(/obj/item/weapon/reagent_containers/spray) in allContents)
|
||||
new/obj/item/weapon/reagent_containers/spray(src)
|
||||
else
|
||||
S = locate(/obj/item/weapon/reagent_containers/spray) in allContents
|
||||
var/obj/item/weapon/reagent_containers/spray/S = locate(/obj/item/weapon/reagent_containers/spray) in allContents
|
||||
|
||||
if(!S)
|
||||
S = new/obj/item/weapon/reagent_containers/spray(src)
|
||||
S.amount_per_transfer_from_this = 10
|
||||
|
||||
for(var/mob/living/carbon/human/C in rangeCheck)
|
||||
var/pranksNearby = 100
|
||||
@@ -1211,27 +1225,25 @@
|
||||
|
||||
if(shouldTryHeal == 1)
|
||||
for(var/mob/living/carbon/human/C in nearby)
|
||||
if(istype(C,/mob/living/carbon/human)) //I haven't the foggiest clue why this is turning up non-carbons but sure here whatever
|
||||
if(C.health <= 75)
|
||||
if(get_dist(src,C) <= 2)
|
||||
src.say("Wait, [C], let me heal you!")
|
||||
M.attack(C,src)
|
||||
sleep(25)
|
||||
else
|
||||
tryWalk(get_turf(C))
|
||||
if(C.health <= 75)
|
||||
if(get_dist(src,C) <= 2)
|
||||
src.say("Wait, [C], let me heal you!")
|
||||
M.attack(C,src)
|
||||
sleep(25)
|
||||
else
|
||||
tryWalk(get_turf(C))
|
||||
else if(shouldTryHeal == 2)
|
||||
if(HPS)
|
||||
if(HPS.reagents.total_volume <= 0)
|
||||
HPS.reagents.add_reagent("tricordrazine",30)
|
||||
for(var/mob/living/carbon/human/C in nearby)
|
||||
if(istype(C,/mob/living/carbon/human))
|
||||
if(C.health <= 75 && C.reagents.get_reagent_amount("tricordrazine") <= 0) // make sure they wont be overdosing
|
||||
if(get_dist(src,C) <= 2)
|
||||
src.say("Wait, [C], let me heal you!")
|
||||
HPS.attack(C,src)
|
||||
sleep(25)
|
||||
else
|
||||
tryWalk(get_turf(C))
|
||||
if(C.health <= 75 && C.reagents.get_reagent_amount("tricordrazine") <= 0) // make sure they wont be overdosing
|
||||
if(get_dist(src,C) <= 2)
|
||||
src.say("Wait, [C], let me heal you!")
|
||||
HPS.attack(C,src)
|
||||
sleep(25)
|
||||
else
|
||||
tryWalk(get_turf(C))
|
||||
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/dojanitor(obj)
|
||||
@@ -1260,8 +1272,7 @@
|
||||
sleep(25)
|
||||
|
||||
/mob/living/carbon/human/interactive/proc/customEmote(var/text)
|
||||
for(var/mob/living/carbon/M in view(src))
|
||||
M.show_message("<span class='notice'>[text]</span>", 2)
|
||||
visible_message("<span class='notice'>[text]</span>")
|
||||
|
||||
// START COOKING MODULE
|
||||
/mob/living/carbon/human/interactive/proc/cookingwithmagic(var/obj/item/weapon/reagent_containers/food/snacks/target)
|
||||
@@ -1318,7 +1329,7 @@
|
||||
if(SF)
|
||||
if(SF.contents.len > 0)
|
||||
if(!Adjacent(SF))
|
||||
tryWalk(get_turf(SF))
|
||||
tryWalk(get_turf(SF),1)
|
||||
else
|
||||
customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in it's mouth!")
|
||||
for(var/obj/item/A in SF.contents)
|
||||
@@ -1458,7 +1469,7 @@
|
||||
if(canmove)
|
||||
if((graytide || (TRAITS & TRAIT_MEAN)) || retal)
|
||||
interest += targetInterestShift
|
||||
a_intent = "harm"
|
||||
a_intent = INTENT_HARM
|
||||
zone_selected = pick("chest","r_leg","l_leg","r_arm","l_arm","head")
|
||||
doing |= FIGHTING
|
||||
if(retal)
|
||||
@@ -1509,7 +1520,7 @@
|
||||
|
||||
if((TARGET && (doing & FIGHTING))) // this is a redundancy check
|
||||
var/mob/living/M = TARGET
|
||||
if(istype(M,/mob/living))
|
||||
if(isliving(M))
|
||||
if(M.health > 1)
|
||||
//THROWING OBJECTS
|
||||
for(var/A in allContents)
|
||||
@@ -1536,8 +1547,8 @@
|
||||
if(istype(main_hand,/obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/G = main_hand
|
||||
if(G.can_trigger_gun(src))
|
||||
if(istype(main_hand,/obj/item/weapon/gun/projectile))
|
||||
var/obj/item/weapon/gun/projectile/P = main_hand
|
||||
if(istype(main_hand,/obj/item/weapon/gun/ballistic))
|
||||
var/obj/item/weapon/gun/ballistic/P = main_hand
|
||||
if(!P.chambered)
|
||||
P.chamber_round()
|
||||
P.update_icon()
|
||||
@@ -1578,7 +1589,7 @@
|
||||
tryWalk(TARGET)
|
||||
else
|
||||
if(Adjacent(TARGET))
|
||||
a_intent = pick("disarm","harm")
|
||||
a_intent = pick(INTENT_DISARM, INTENT_HARM)
|
||||
M.attack_hand(src)
|
||||
timeout++
|
||||
else if(timeout >= 10 || !(targetRange(M) > 14))
|
||||
@@ -1622,3 +1633,11 @@
|
||||
faction += "bot_grey"
|
||||
graytide = 1
|
||||
..()
|
||||
|
||||
//Walk softly and carry a big stick
|
||||
/mob/living/carbon/human/interactive/robust/New()
|
||||
TRAITS |= TRAIT_FRIENDLY
|
||||
TRAITS |= TRAIT_ROBUST
|
||||
TRAITS |= TRAIT_SMART
|
||||
faction += "bot_power"
|
||||
..()
|
||||
|
||||
+323
-189
@@ -1,278 +1,369 @@
|
||||
//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc
|
||||
//These procs handle putting s tuff in your hands
|
||||
//as they handle all relevant stuff like adding it to the player's screen and updating their overlays.
|
||||
|
||||
//Returns the thing in our active hand
|
||||
/mob/proc/get_active_hand()
|
||||
if(hand)
|
||||
return l_hand
|
||||
else
|
||||
return r_hand
|
||||
//Returns the thing we're currently holding
|
||||
/mob/proc/get_active_held_item()
|
||||
return get_item_for_held_index(active_hand_index)
|
||||
|
||||
|
||||
//Returns the thing in our inactive hand
|
||||
/mob/proc/get_inactive_hand()
|
||||
if(hand)
|
||||
return r_hand
|
||||
//Finds the opposite limb for the active one (eg: upper left arm will find the item in upper right arm)
|
||||
//So we're treating each "pair" of limbs as a team, so "both" refers to them
|
||||
/mob/proc/get_inactive_held_item()
|
||||
return get_item_for_held_index(get_inactive_hand_index())
|
||||
|
||||
|
||||
//Finds the opposite index for the active one (eg: upper left arm will find the item in upper right arm)
|
||||
//So we're treating each "pair" of limbs as a team, so "both" refers to them
|
||||
/mob/proc/get_inactive_hand_index()
|
||||
var/other_hand = 0
|
||||
if(!(active_hand_index % 2))
|
||||
other_hand = active_hand_index-1 //finding the matching "left" limb
|
||||
else
|
||||
return l_hand
|
||||
other_hand = active_hand_index+1 //finding the matching "right" limb
|
||||
if(other_hand < 0 || other_hand > held_items.len)
|
||||
other_hand = 0
|
||||
return other_hand
|
||||
|
||||
|
||||
/mob/proc/get_item_for_held_index(i)
|
||||
if(i > 0 && i <= held_items.len)
|
||||
return held_items[i]
|
||||
return FALSE
|
||||
|
||||
|
||||
//Odd = left. Even = right
|
||||
/mob/proc/held_index_to_dir(i)
|
||||
if(!(i % 2))
|
||||
return "r"
|
||||
return "l"
|
||||
|
||||
|
||||
//Check we have an organ for this hand slot (Dismemberment), Only relevant for humans
|
||||
/mob/proc/has_hand_for_held_index(i)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Check we have an organ for our active hand slot (Dismemberment),Only relevant for humans
|
||||
/mob/proc/has_active_hand()
|
||||
return has_hand_for_held_index(active_hand_index)
|
||||
|
||||
|
||||
//Finds the first available (null) index OR all available (null) indexes in held_items based on a side.
|
||||
//Lefts: 1, 3, 5, 7...
|
||||
//Rights:2, 4, 6, 8...
|
||||
/mob/proc/get_empty_held_index_for_side(side = "left", all = FALSE)
|
||||
var/start = 0
|
||||
var/static/list/lefts = list("l" = TRUE,"L" = TRUE,"LEFT" = TRUE,"left" = TRUE)
|
||||
var/static/list/rights = list("r" = TRUE,"R" = TRUE,"RIGHT" = TRUE,"right" = TRUE) //"to remain silent"
|
||||
if(lefts[side])
|
||||
start = 1
|
||||
else if(rights[side])
|
||||
start = 2
|
||||
if(!start)
|
||||
return FALSE
|
||||
var/list/empty_indexes
|
||||
for(var/i in start to held_items.len step 2)
|
||||
if(!held_items[i])
|
||||
if(!all)
|
||||
return i
|
||||
if(!empty_indexes)
|
||||
empty_indexes = list()
|
||||
empty_indexes += i
|
||||
return empty_indexes
|
||||
|
||||
|
||||
//Same as the above, but returns the first or ALL held *ITEMS* for the side
|
||||
/mob/proc/get_held_items_for_side(side = "left", all = FALSE)
|
||||
var/start = 0
|
||||
var/static/list/lefts = list("l" = TRUE,"L" = TRUE,"LEFT" = TRUE,"left" = TRUE)
|
||||
var/static/list/rights = list("r" = TRUE,"R" = TRUE,"RIGHT" = TRUE,"right" = TRUE) //"to remain silent"
|
||||
if(lefts[side])
|
||||
start = 1
|
||||
else if(rights[side])
|
||||
start = 2
|
||||
if(!start)
|
||||
return FALSE
|
||||
var/list/holding_items
|
||||
for(var/i in start to held_items.len step 2)
|
||||
var/obj/item/I = held_items[i]
|
||||
if(I)
|
||||
if(!all)
|
||||
return I
|
||||
if(!holding_items)
|
||||
holding_items = list()
|
||||
holding_items += I
|
||||
return holding_items
|
||||
|
||||
|
||||
/mob/proc/get_empty_held_indexes()
|
||||
var/list/L
|
||||
for(var/i in 1 to held_items.len)
|
||||
if(!held_items[i])
|
||||
if(!L)
|
||||
L = list()
|
||||
L += i
|
||||
return L
|
||||
|
||||
/mob/proc/get_held_index_of_item(obj/item/I)
|
||||
return held_items.Find(I)
|
||||
|
||||
|
||||
//Sad that this will cause some overhead, but the alias seems necessary
|
||||
//*I* may be happy with a million and one references to "indexes" but others won't be
|
||||
/mob/proc/is_holding(obj/item/I)
|
||||
return get_held_index_of_item(I)
|
||||
|
||||
|
||||
//Checks if we're holding an item of type: typepath
|
||||
/mob/proc/is_holding_item_of_type(typepath)
|
||||
for(var/obj/item/I in held_items)
|
||||
if(istype(I, typepath))
|
||||
return I
|
||||
return FALSE
|
||||
|
||||
|
||||
//To appropriately fluff things like "they are holding [I] in their [get_held_index_name(get_held_index_of_item(I))]"
|
||||
//Can be overriden to pass off the fluff to something else (eg: science allowing people to add extra robotic limbs, and having this proc react to that
|
||||
// with say "they are holding [I] in their Nanotrasen Brand Utility Arm - Right Edition" or w/e
|
||||
/mob/proc/get_held_index_name(i)
|
||||
var/list/hand = list()
|
||||
if(i > 2)
|
||||
hand += "upper "
|
||||
var/num = 0
|
||||
if(!(i % 2))
|
||||
num = i-2
|
||||
hand += "right hand"
|
||||
else
|
||||
num = i-1
|
||||
hand += "left hand"
|
||||
num -= (num*0.5)
|
||||
if(num > 1) //"upper left hand #1" seems weird, but "upper left hand #2" is A-ok
|
||||
hand += " #[num]"
|
||||
return hand.Join()
|
||||
|
||||
|
||||
|
||||
//Returns if a certain item can be equipped to a certain slot.
|
||||
// Currently invalid for two-handed items - call obj/item/mob_can_equip() instead.
|
||||
/mob/proc/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
return 0
|
||||
|
||||
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_l_hand(obj/item/W)
|
||||
if(!put_in_hand_check(W))
|
||||
return 0
|
||||
if(!has_left_hand())
|
||||
return 0
|
||||
if(!l_hand)
|
||||
var/atom/old_loc = W.loc
|
||||
W.loc = src //TODO: move to equipped?
|
||||
W.Moved(old_loc, 0) // MSO told me to do this!
|
||||
l_hand = W
|
||||
W.layer = ABOVE_HUD_LAYER //TODO: move to equipped?
|
||||
W.equipped(src,slot_l_hand)
|
||||
if(W.pulledby)
|
||||
W.pulledby.stop_pulling()
|
||||
update_inv_l_hand()
|
||||
W.pixel_x = initial(W.pixel_x)
|
||||
W.pixel_y = initial(W.pixel_y)
|
||||
return 1
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
//Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_r_hand(obj/item/W)
|
||||
if(!put_in_hand_check(W))
|
||||
return 0
|
||||
if(!has_right_hand())
|
||||
return 0
|
||||
if(!r_hand)
|
||||
var/atom/old_loc = W.loc
|
||||
W.loc = src
|
||||
W.Moved(old_loc, 0) // MSO told me to do this!
|
||||
r_hand = W
|
||||
W.layer = ABOVE_HUD_LAYER
|
||||
W.equipped(src,slot_r_hand)
|
||||
if(W.pulledby)
|
||||
W.pulledby.stop_pulling()
|
||||
update_inv_r_hand()
|
||||
W.pixel_x = initial(W.pixel_x)
|
||||
W.pixel_y = initial(W.pixel_y)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/proc/put_in_hand_check(obj/item/W)
|
||||
if(lying && !(W.flags&ABSTRACT))
|
||||
return 0
|
||||
if(!istype(W))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//Puts the item into our active hand if possible. returns 1 on success.
|
||||
/mob/proc/put_in_active_hand(obj/item/W)
|
||||
if(hand)
|
||||
return put_in_l_hand(W)
|
||||
else
|
||||
return put_in_r_hand(W)
|
||||
/mob/proc/put_in_hand(obj/item/I, hand_index)
|
||||
if(!put_in_hand_check(I))
|
||||
return FALSE
|
||||
if(!has_hand_for_held_index(hand_index))
|
||||
return FALSE
|
||||
var/obj/item/curr = held_items[hand_index]
|
||||
if(!curr)
|
||||
I.loc = src
|
||||
held_items[hand_index] = I
|
||||
I.layer = ABOVE_HUD_LAYER
|
||||
I.plane = ABOVE_HUD_PLANE
|
||||
I.equipped(src, slot_hands)
|
||||
if(I.pulledby)
|
||||
I.pulledby.stop_pulling()
|
||||
update_inv_hands()
|
||||
I.pixel_x = initial(I.pixel_x)
|
||||
I.pixel_y = initial(I.pixel_y)
|
||||
return hand_index || TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
//Puts the item into our inactive hand if possible. returns 1 on success.
|
||||
/mob/proc/put_in_inactive_hand(obj/item/W)
|
||||
if(hand)
|
||||
return put_in_r_hand(W)
|
||||
else
|
||||
return put_in_l_hand(W)
|
||||
//Puts the item into the first available left hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_l_hand(obj/item/I)
|
||||
return put_in_hand(I, get_empty_held_index_for_side("l"))
|
||||
|
||||
|
||||
//Puts the item our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success.
|
||||
//If both fail it drops it on the floor and returns 0.
|
||||
//Puts the item into the first available right hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_r_hand(obj/item/I)
|
||||
return put_in_hand(I, get_empty_held_index_for_side("r"))
|
||||
|
||||
|
||||
/mob/proc/put_in_hand_check(obj/item/I)
|
||||
if(lying && !(I.flags&ABSTRACT))
|
||||
return FALSE
|
||||
if(!istype(I))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
//Puts the item into our active hand if possible. returns TRUE on success.
|
||||
/mob/proc/put_in_active_hand(obj/item/I)
|
||||
return put_in_hand(I, active_hand_index)
|
||||
|
||||
|
||||
//Puts the item into our inactive hand if possible, returns TRUE on success
|
||||
/mob/proc/put_in_inactive_hand(obj/item/I)
|
||||
return put_in_hand(I, get_inactive_hand_index())
|
||||
|
||||
|
||||
//Puts the item our active hand if possible. Failing that it tries other hands. Returns TRUE on success.
|
||||
//If both fail it drops it on the floor and returns FALSE.
|
||||
//This is probably the main one you need to know :)
|
||||
/mob/proc/put_in_hands(obj/item/W)
|
||||
if(!W)
|
||||
return 0
|
||||
if(put_in_active_hand(W))
|
||||
return 1
|
||||
else if(put_in_inactive_hand(W))
|
||||
return 1
|
||||
else
|
||||
var/atom/old_loc = W.loc
|
||||
W.loc = get_turf(src)
|
||||
W.Moved(old_loc, 0) // MSO told me to do this!
|
||||
W.layer = initial(W.layer)
|
||||
W.dropped(src)
|
||||
return 0
|
||||
/mob/proc/put_in_hands(obj/item/I, del_on_fail = FALSE)
|
||||
if(!I)
|
||||
return FALSE
|
||||
if(put_in_active_hand(I))
|
||||
return TRUE
|
||||
var/hand = get_empty_held_index_for_side("l")
|
||||
if(!hand)
|
||||
hand = get_empty_held_index_for_side("r")
|
||||
if(hand)
|
||||
if(put_in_hand(I, hand))
|
||||
return TRUE
|
||||
if(del_on_fail)
|
||||
qdel(I)
|
||||
return FALSE
|
||||
I.forceMove(get_turf(src))
|
||||
I.layer = initial(I.layer)
|
||||
I.plane = initial(I.plane)
|
||||
I.dropped(src)
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/proc/put_in_hands_or_del(obj/item/I)
|
||||
return put_in_hands(I, TRUE)
|
||||
|
||||
|
||||
/mob/proc/drop_item_v() //this is dumb.
|
||||
if(stat == CONSCIOUS && isturf(loc))
|
||||
return drop_item()
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
//Drops the item in our left hand
|
||||
/mob/proc/drop_l_hand()
|
||||
/mob/proc/drop_all_held_items()
|
||||
if(!loc || !loc.allow_drop())
|
||||
return
|
||||
return unEquip(l_hand) //All needed checks are in unEquip
|
||||
|
||||
|
||||
//Drops the item in our right hand
|
||||
/mob/proc/drop_r_hand()
|
||||
if(!loc || !loc.allow_drop())
|
||||
return
|
||||
return unEquip(r_hand)
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
unEquip(I)
|
||||
|
||||
//Drops the item in our active hand.
|
||||
/mob/proc/drop_item()
|
||||
if(hand)
|
||||
return drop_l_hand()
|
||||
else
|
||||
return drop_r_hand()
|
||||
if(!loc || !loc.allow_drop())
|
||||
return
|
||||
var/obj/item/held = get_active_held_item()
|
||||
return unEquip(held)
|
||||
|
||||
|
||||
//Here lie drop_from_inventory and before_item_take, already forgotten and not missed.
|
||||
|
||||
|
||||
/mob/proc/canUnEquip(obj/item/I, force)
|
||||
if(!I)
|
||||
return 1
|
||||
return TRUE
|
||||
if((I.flags & NODROP) && !force)
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/proc/unEquip(obj/item/I, force) //Force overrides NODROP for things like wizarditis and admin undress.
|
||||
if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP.
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if((I.flags & NODROP) && !force)
|
||||
return 0
|
||||
|
||||
if(I == r_hand)
|
||||
r_hand = null
|
||||
update_inv_r_hand()
|
||||
else if(I == l_hand)
|
||||
l_hand = null
|
||||
update_inv_l_hand()
|
||||
return FALSE
|
||||
|
||||
var/hand_index = get_held_index_of_item(I)
|
||||
if(hand_index)
|
||||
held_items[hand_index] = null
|
||||
update_inv_hands()
|
||||
if(I)
|
||||
if(client)
|
||||
client.screen -= I
|
||||
I.loc = loc
|
||||
I.Moved(src, 0) // MSO told me to do this!
|
||||
I.layer = initial(I.layer)
|
||||
I.plane = initial(I.plane)
|
||||
I.appearance_flags &= ~NO_CLIENT_COLOR
|
||||
I.forceMove(loc)
|
||||
I.dropped(src)
|
||||
if(I)
|
||||
I.layer = initial(I.layer)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
//Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob.
|
||||
/mob/proc/remove_from_mob(var/obj/O)
|
||||
unEquip(O)
|
||||
O.screen_loc = null
|
||||
return 1
|
||||
/mob/proc/remove_from_mob(var/obj/item/I)
|
||||
unEquip(I)
|
||||
I.screen_loc = null
|
||||
return TRUE
|
||||
|
||||
|
||||
//Outdated but still in use apparently. This should at least be a human proc.
|
||||
/mob/proc/get_equipped_items()
|
||||
var/list/items = new/list()
|
||||
//Daily reminder to murder this - Remie.
|
||||
/mob/living/proc/get_equipped_items()
|
||||
return
|
||||
|
||||
if(hasvar(src,"back"))
|
||||
if(src:back)
|
||||
items += src:back
|
||||
if(hasvar(src,"belt"))
|
||||
if(src:belt)
|
||||
items += src:belt
|
||||
if(hasvar(src,"ears"))
|
||||
if(src:ears)
|
||||
items += src:ears
|
||||
if(hasvar(src,"glasses"))
|
||||
if(src:glasses)
|
||||
items += src:glasses
|
||||
if(hasvar(src,"gloves"))
|
||||
if(src:gloves)
|
||||
items += src:gloves
|
||||
if(hasvar(src,"head"))
|
||||
if(src:head)
|
||||
items += src:head
|
||||
if(hasvar(src,"shoes"))
|
||||
if(src:shoes)
|
||||
items += src:shoes
|
||||
if(hasvar(src,"wear_id"))
|
||||
if(src:wear_id)
|
||||
items += src:wear_id
|
||||
if(hasvar(src,"wear_mask"))
|
||||
if(src:wear_mask)
|
||||
items += src:wear_mask
|
||||
if(hasvar(src,"wear_suit"))
|
||||
if(src:wear_suit)
|
||||
items += src:wear_suit
|
||||
/* if(hasvar(src,"w_radio"))
|
||||
if(src:w_radio)
|
||||
items += src:w_radio commenting this out since headsets go on your ears now PLEASE DON'T BE MAD KEELIN */
|
||||
if(hasvar(src,"w_uniform"))
|
||||
if(src:w_uniform)
|
||||
items += src:w_uniform
|
||||
|
||||
/* if(hasvar(src,"l_hand"))
|
||||
if(src:l_hand)
|
||||
items += src:l_hand
|
||||
if(hasvar(src,"r_hand"))
|
||||
if(src:r_hand)
|
||||
items += src:r_hand*/
|
||||
/mob/living/carbon/get_equipped_items()
|
||||
var/list/items = list()
|
||||
if(back)
|
||||
items += back
|
||||
if(head)
|
||||
items += head
|
||||
if(wear_mask)
|
||||
items += wear_mask
|
||||
if(wear_neck)
|
||||
items += wear_neck
|
||||
return items
|
||||
|
||||
/mob/living/carbon/human/get_equipped_items()
|
||||
var/list/items = ..()
|
||||
if(belt)
|
||||
items += belt
|
||||
if(ears)
|
||||
items += ears
|
||||
if(glasses)
|
||||
items += glasses
|
||||
if(gloves)
|
||||
items += gloves
|
||||
if(shoes)
|
||||
items += shoes
|
||||
if(wear_id)
|
||||
items += wear_id
|
||||
if(wear_suit)
|
||||
items += wear_suit
|
||||
if(w_uniform)
|
||||
items += w_uniform
|
||||
return items
|
||||
|
||||
|
||||
|
||||
/obj/item/proc/equip_to_best_slot(var/mob/M)
|
||||
if(src != M.get_active_hand())
|
||||
if(src != M.get_active_held_item())
|
||||
M << "<span class='warning'>You are not holding anything to equip!</span>"
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(M.equip_to_appropriate_slot(src))
|
||||
if(M.hand)
|
||||
M.update_inv_l_hand()
|
||||
else
|
||||
M.update_inv_r_hand()
|
||||
return 1
|
||||
M.update_inv_hands()
|
||||
return TRUE
|
||||
|
||||
if(M.s_active && M.s_active.can_be_inserted(src,1)) //if storage active insert there
|
||||
M.s_active.handle_item_insertion(src)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
var/obj/item/weapon/storage/S = M.get_inactive_hand()
|
||||
var/obj/item/weapon/storage/S = M.get_inactive_held_item()
|
||||
if(istype(S) && S.can_be_inserted(src,1)) //see if we have box in other hand
|
||||
S.handle_item_insertion(src)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
S = M.get_item_by_slot(slot_belt)
|
||||
if(istype(S) && S.can_be_inserted(src,1)) //else we put in belt
|
||||
S.handle_item_insertion(src)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
S = M.get_item_by_slot(slot_drone_storage) //else we put in whatever is in drone storage
|
||||
S = M.get_item_by_slot(slot_generic_dextrous_storage) //else we put in whatever is in drone storage
|
||||
if(istype(S) && S.can_be_inserted(src,1))
|
||||
S.handle_item_insertion(src)
|
||||
|
||||
S = M.get_item_by_slot(slot_back) //else we put in backpack
|
||||
if(istype(S) && S.can_be_inserted(src,1))
|
||||
S.handle_item_insertion(src)
|
||||
playsound(src.loc, "rustle", 50, 1, -5)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
M << "<span class='warning'>You are unable to equip that!</span>"
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/verb/quick_equip()
|
||||
set name = "quick-equip"
|
||||
set hidden = 1
|
||||
|
||||
var/obj/item/I = get_active_hand()
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if (I)
|
||||
I.equip_to_best_slot(src)
|
||||
|
||||
@@ -282,3 +373,46 @@
|
||||
|
||||
/mob/proc/getBeltSlot()
|
||||
return slot_belt
|
||||
|
||||
|
||||
|
||||
//Inventory.dm is -kind of- an ok place for this I guess
|
||||
|
||||
//This is NOT for dismemberment, as the user still technically has 2 "hands"
|
||||
//This is for multi-handed mobs, such as a human with a third limb installed
|
||||
//This is a very rare proc to call (besides admin fuckery) so
|
||||
//any cost it has isn't a worry
|
||||
/mob/proc/change_number_of_hands(amt)
|
||||
if(amt < held_items.len)
|
||||
for(var/i in held_items.len to amt step -1)
|
||||
unEquip(held_items[i])
|
||||
held_items.len = amt
|
||||
|
||||
if(hud_used)
|
||||
var/style
|
||||
if(client && client.prefs)
|
||||
style = ui_style2icon(client.prefs.UI_style)
|
||||
hud_used.build_hand_slots(style)
|
||||
|
||||
|
||||
/mob/living/carbon/human/change_number_of_hands(amt)
|
||||
var/old_limbs = held_items.len
|
||||
if(amt < old_limbs)
|
||||
for(var/i in hand_bodyparts.len to amt step -1)
|
||||
var/obj/item/bodypart/BP = hand_bodyparts[i]
|
||||
BP.dismember()
|
||||
hand_bodyparts[i] = null
|
||||
hand_bodyparts.len = amt
|
||||
else if(amt > old_limbs)
|
||||
hand_bodyparts.len = amt
|
||||
for(var/i in old_limbs+1 to amt)
|
||||
var/path = /obj/item/bodypart/l_arm
|
||||
if(!(i % 2))
|
||||
path = /obj/item/bodypart/r_arm
|
||||
|
||||
var/obj/item/bodypart/BP = new path ()
|
||||
BP.owner = src
|
||||
BP.held_index = i
|
||||
bodyparts += BP
|
||||
hand_bodyparts[i] = BP
|
||||
..() //Don't redraw hands until we have organs for them
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/handle_blood()
|
||||
|
||||
if(NOBLOOD in dna.species.specflags)
|
||||
if(NOBLOOD in dna.species.species_traits)
|
||||
bleed_rate = 0
|
||||
return
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
add_splatter_floor(src.loc, 1)
|
||||
|
||||
/mob/living/carbon/human/bleed(amt)
|
||||
if(!(NOBLOOD in dna.species.specflags))
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
..()
|
||||
|
||||
|
||||
@@ -162,8 +162,13 @@
|
||||
blood_data["trace_chem"] = list2params(temp_chem)
|
||||
if(mind)
|
||||
blood_data["mind"] = mind
|
||||
else if(last_mind)
|
||||
blood_data["mind"] = last_mind
|
||||
if(ckey)
|
||||
blood_data["ckey"] = ckey
|
||||
else if(last_mind)
|
||||
blood_data["ckey"] = ckey(last_mind.key)
|
||||
|
||||
if(!suiciding)
|
||||
blood_data["cloneable"] = 1
|
||||
blood_data["blood_type"] = copytext(dna.blood_type,1,0)
|
||||
@@ -188,7 +193,7 @@
|
||||
/mob/living/carbon/human/get_blood_id()
|
||||
if(dna.species.exotic_blood)
|
||||
return dna.species.exotic_blood
|
||||
else if((NOBLOOD in dna.species.specflags) || (disabilities & NOCLONE))
|
||||
else if((NOBLOOD in dna.species.species_traits) || (disabilities & NOCLONE))
|
||||
return
|
||||
return "blood"
|
||||
|
||||
@@ -216,70 +221,43 @@
|
||||
return list("O-", "O+")
|
||||
if("L")
|
||||
return list("L")
|
||||
if("X")
|
||||
return list("X")
|
||||
|
||||
//to add a splatter of blood or other mob liquid.
|
||||
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
|
||||
if(get_blood_id() != "blood" && get_blood_id() != "xblood")
|
||||
if(get_blood_id() != "blood")
|
||||
return
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
|
||||
var/list/temp_blood_DNA
|
||||
if(small_drip)
|
||||
// Only a certain number of drips (or one large splatter) can be on a given turf.
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.dna.species.id == "xeno")
|
||||
var/obj/effect/decal/cleanable/xdrip/xdrop = locate() in T
|
||||
if(xdrop)
|
||||
if(xdrop.drips < 3)
|
||||
xdrop.drips++
|
||||
xdrop.overlays |= pick(xdrop.random_icon_states)
|
||||
xdrop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= xdrop.blood_DNA.Copy()
|
||||
qdel(xdrop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
xdrop = new(T)
|
||||
xdrop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T
|
||||
if(drop)
|
||||
if(drop.drips < 3)
|
||||
drop.drips++
|
||||
drop.overlays |= pick(drop.random_icon_states)
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
|
||||
qdel(drop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
drop = new(T)
|
||||
var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T
|
||||
if(drop)
|
||||
if(drop.drips < 3)
|
||||
drop.drips++
|
||||
drop.overlays |= pick(drop.random_icon_states)
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
|
||||
qdel(drop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
drop = new(T)
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
|
||||
// Find a blood decal or create a new one.
|
||||
var/obj/effect/decal/cleanable/blood/B = locate() in T
|
||||
if(!B)
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.dna.species.id == "xeno")
|
||||
B = new /obj/effect/decal/cleanable/xenoblood(T)
|
||||
else
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T)
|
||||
else
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T)
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T)
|
||||
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
|
||||
if(temp_blood_DNA)
|
||||
B.blood_DNA |= temp_blood_DNA
|
||||
|
||||
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
|
||||
if(!(NOBLOOD in dna.species.specflags))
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip)
|
||||
@@ -295,4 +273,4 @@
|
||||
T = get_turf(src)
|
||||
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
|
||||
if(!B)
|
||||
B = new(T)
|
||||
B = new(T)
|
||||
@@ -6,7 +6,7 @@
|
||||
density = 0
|
||||
anchored = 1
|
||||
invisibility = 60
|
||||
burn_state = LAVA_PROOF
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/dummy/slaughter/relaymove(mob/user, direction)
|
||||
forceMove(get_step(src,direction))
|
||||
@@ -27,7 +27,7 @@
|
||||
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
if(C.l_hand || C.r_hand)
|
||||
for(var/obj/item/I in C.held_items)
|
||||
//TODO make it toggleable to either forcedrop the items, or deny
|
||||
//entry when holding them
|
||||
// literally only an option for carbons though
|
||||
@@ -68,7 +68,7 @@
|
||||
return
|
||||
|
||||
// if the thing we're pulling isn't alive
|
||||
if (!(istype(pullee, /mob/living)))
|
||||
if (!isliving(pullee))
|
||||
return
|
||||
|
||||
var/mob/living/victim = pullee
|
||||
@@ -145,15 +145,14 @@
|
||||
|
||||
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
var/oldcolor = src.color
|
||||
//Makes the mob have the color of the blood pool it came out of
|
||||
var/newcolor = rgb(149, 10, 10)
|
||||
if(istype(B, /obj/effect/decal/cleanable/xenoblood))
|
||||
src.color = rgb(43, 186, 0)
|
||||
else
|
||||
src.color = rgb(149, 10, 10)
|
||||
newcolor = rgb(43, 186, 0)
|
||||
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
|
||||
// but only for a few seconds
|
||||
spawn(30)
|
||||
src.color = oldcolor
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
|
||||
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
|
||||
+43
-27
@@ -1,16 +1,16 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/obj/item/device/mmi
|
||||
name = "Man-Machine Interface"
|
||||
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "mmi_empty"
|
||||
w_class = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "biotech=2;programming=3;engineering=2"
|
||||
var/braintype = "Cyborg"
|
||||
var/obj/item/device/radio/radio = null //Let's give it a radio.
|
||||
var/hacked = 0 //Whether or not this is a Syndicate MMI
|
||||
var/mob/living/carbon/brain/brainmob = null //The current occupant.
|
||||
var/mob/living/brain/brainmob = null //The current occupant.
|
||||
var/mob/living/silicon/robot = null //Appears unused.
|
||||
var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm.
|
||||
var/obj/item/organ/brain/brain = null //The actual brain
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
if(!user.unEquip(O))
|
||||
return
|
||||
var/mob/living/carbon/brain/B = newbrain.brainmob
|
||||
var/mob/living/brain/B = newbrain.brainmob
|
||||
if(!B.key)
|
||||
B.notify_ghost_cloning("Someone has put your brain in a MMI!", source = src)
|
||||
visible_message("[user] sticks \a [newbrain] into \the [src].")
|
||||
@@ -78,12 +78,11 @@
|
||||
|
||||
feedback_inc("cyborg_mmis_filled",1)
|
||||
|
||||
return
|
||||
|
||||
else if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
return
|
||||
..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device/mmi/attack_self(mob/user)
|
||||
if(!brain)
|
||||
@@ -91,23 +90,27 @@
|
||||
user << "<span class='notice'>You toggle the MMI's radio system [radio.on==1 ? "on" : "off"].</span>"
|
||||
else
|
||||
user << "<span class='notice'>You unlock and upend the MMI, spilling the brain onto the floor.</span>"
|
||||
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.loc = brain //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
living_mob_list -= brainmob //Get outta here
|
||||
dead_mob_list += brainmob
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
brain = null //No more brain in here
|
||||
|
||||
eject_brain(user)
|
||||
update_icon()
|
||||
name = "Man-Machine Interface"
|
||||
|
||||
/obj/item/device/mmi/proc/eject_brain(mob/user)
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.loc = brain //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
living_mob_list -= brainmob //Get outta here
|
||||
dead_mob_list += brainmob
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
if(user)
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
else
|
||||
brain.forceMove(get_turf(src))
|
||||
brain = null //No more brain in here
|
||||
|
||||
|
||||
/obj/item/device/mmi/proc/transfer_identity(mob/living/L) //Same deal as the regular brain proc. Used for human-->robot people.
|
||||
if(!brainmob)
|
||||
brainmob = new(src)
|
||||
@@ -115,9 +118,9 @@
|
||||
brainmob.real_name = L.real_name
|
||||
if(L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
brainmob.container = src
|
||||
|
||||
if(ishuman(L))
|
||||
@@ -165,18 +168,31 @@
|
||||
..()
|
||||
|
||||
/obj/item/device/mmi/Destroy()
|
||||
if(isrobot(loc))
|
||||
if(iscyborg(loc))
|
||||
var/mob/living/silicon/robot/borg = loc
|
||||
borg.mmi = null
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
if(brain)
|
||||
qdel(brain)
|
||||
brain = null
|
||||
if(mecha)
|
||||
mecha = null
|
||||
if(radio)
|
||||
qdel(radio)
|
||||
radio = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/mmi/deconstruct(disassembled = TRUE)
|
||||
if(brain)
|
||||
eject_brain()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/mmi/examine(mob/user)
|
||||
..()
|
||||
if(brainmob)
|
||||
var/mob/living/carbon/brain/B = brainmob
|
||||
var/mob/living/brain/B = brainmob
|
||||
if(!B.key || !B.mind || B.stat == DEAD)
|
||||
user << "<span class='warning'>The MMI indicates the brain is completely unresponsive.</span>"
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
/mob/living/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
|
||||
stat = DEAD //we start dead by default
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/mob/living/brain/New(loc)
|
||||
..()
|
||||
create_dna(src)
|
||||
stored_dna.initialize_dna(random_blood_type())
|
||||
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
|
||||
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
|
||||
src.loc = OB
|
||||
OB.brainmob = src
|
||||
|
||||
|
||||
/mob/living/brain/proc/create_dna()
|
||||
stored_dna = new /datum/dna/stored(src)
|
||||
if(!stored_dna.species)
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
stored_dna.species = new rando_race()
|
||||
|
||||
/mob/living/brain/Destroy()
|
||||
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
|
||||
if(stat!=DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
container = null
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha))
|
||||
canmove = 1
|
||||
else
|
||||
canmove = 0
|
||||
return canmove
|
||||
|
||||
/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
|
||||
/mob/living/brain/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/mob/living/brain/get_eye_protection()//no eyes
|
||||
return 2
|
||||
|
||||
/mob/living/brain/get_ear_protection()//no ears
|
||||
return 2
|
||||
|
||||
/mob/living/brain/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/brain/can_be_revived()
|
||||
. = 1
|
||||
if(!container || health <= HEALTH_THRESHOLD_DEAD)
|
||||
return 0
|
||||
|
||||
/mob/living/brain/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(stored_dna)
|
||||
stored_dna.real_name = real_name
|
||||
+30
-32
@@ -10,35 +10,34 @@
|
||||
vital = 1
|
||||
origin_tech = "biotech=5"
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
var/mob/living/carbon/brain/brainmob = null
|
||||
var/mob/living/brain/brainmob = null
|
||||
var/damaged_brain = 0 //whether the brain organ is damaged.
|
||||
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0)
|
||||
..()
|
||||
name = "brain"
|
||||
if(brainmob)
|
||||
if(M.key)
|
||||
M.ghostize()
|
||||
if(C.key)
|
||||
C.ghostize()
|
||||
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(M)
|
||||
brainmob.mind.transfer_to(C)
|
||||
else
|
||||
M.key = brainmob.key
|
||||
C.key = brainmob.key
|
||||
|
||||
qdel(brainmob)
|
||||
|
||||
//Update the body's icon so it doesnt appear debrained anymore
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_hair(0)
|
||||
C.update_hair()
|
||||
|
||||
/obj/item/organ/brain/Remove(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0)
|
||||
..()
|
||||
if(!special)
|
||||
transfer_identity(M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_hair(0)
|
||||
if(C.has_brain_worms())
|
||||
var/mob/living/simple_animal/borer/B = C.has_brain_worms()
|
||||
B.leave_victim() //Should remove borer if the brain is removed - RR
|
||||
transfer_identity(C)
|
||||
C.update_hair()
|
||||
|
||||
/obj/item/organ/brain/prepare_eat()
|
||||
return // Too important to eat.
|
||||
@@ -51,9 +50,9 @@
|
||||
brainmob.timeofhostdeath = L.timeofdeath
|
||||
if(L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
if(L.mind && L.mind.current && (L.mind.current.stat == DEAD))
|
||||
L.mind.transfer_to(brainmob)
|
||||
brainmob << "<span class='notice'>You feel slightly disoriented. That's normal when you're just a brain.</span>"
|
||||
@@ -68,7 +67,7 @@
|
||||
|
||||
if(brainmob)
|
||||
if(brainmob.client)
|
||||
if(brainmob.health <= config.health_threshold_dead)
|
||||
if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
|
||||
user << "It's lifeless and severely damaged."
|
||||
else
|
||||
user << "You can feel the small spark of life still left in this one."
|
||||
@@ -77,8 +76,8 @@
|
||||
else
|
||||
user << "This one is completely devoid of life."
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user)
|
||||
if(!istype(M))
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/C, mob/user)
|
||||
if(!istype(C))
|
||||
return ..()
|
||||
|
||||
add_fingerprint(user)
|
||||
@@ -86,31 +85,30 @@
|
||||
if(user.zone_selected != "head")
|
||||
return ..()
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
if((C.head && (C.head.flags_cover & HEADCOVERSEYES)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSEYES)) || (C.glasses && (C.glasses.flags & GLASSESCOVERSEYES)))
|
||||
user << "<span class='warning'>You're going to need to remove their head cover first!</span>"
|
||||
return
|
||||
|
||||
//since these people will be dead M != usr
|
||||
|
||||
if(!M.getorgan(/obj/item/organ/brain))
|
||||
if(istype(H) && !H.get_bodypart("head"))
|
||||
if(!C.getorgan(/obj/item/organ/brain))
|
||||
if(!C.get_bodypart("head"))
|
||||
return
|
||||
user.drop_item()
|
||||
var/msg = "[M] has [src] inserted into \his head by [user]."
|
||||
if(M == user)
|
||||
msg = "[user] inserts [src] into \his head!"
|
||||
var/msg = "[C] has [src] inserted into [C.p_their()] head by [user]."
|
||||
if(C == user)
|
||||
msg = "[user] inserts [src] into [user.p_their()] head!"
|
||||
|
||||
M.visible_message("<span class='danger'>[msg]</span>",
|
||||
C.visible_message("<span class='danger'>[msg]</span>",
|
||||
"<span class='userdanger'>[msg]</span>")
|
||||
|
||||
if(M != user)
|
||||
M << "<span class='notice'>[user] inserts [src] into your head.</span>"
|
||||
user << "<span class='notice'>You insert [src] into [M]'s head.</span>"
|
||||
if(C != user)
|
||||
C << "<span class='notice'>[user] inserts [src] into your head.</span>"
|
||||
user << "<span class='notice'>You insert [src] into [C]'s head.</span>"
|
||||
else
|
||||
user << "<span class='notice'>You insert [src] into your head.</span>" //LOL
|
||||
|
||||
Insert(M)
|
||||
Insert(C)
|
||||
else
|
||||
..()
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/brain/death(gibbed)
|
||||
/mob/living/brain/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/gib()
|
||||
/mob/living/brain/gib()
|
||||
if(container)
|
||||
qdel(container)//Gets rid of the MMI if there is one
|
||||
if(loc)
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/brain/emote(act,m_type=1,message = null)
|
||||
/mob/living/brain/emote(act,m_type=1,message = null)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
|
||||
return
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
log_emote("[name]/[key] : [message]")
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if (!M.client || istype(M, /mob/new_player))
|
||||
if (!M.client || isnewplayer(M))
|
||||
continue //skip monkeys, leavers, and new_players
|
||||
if(M.stat == DEAD && (M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
+8
-19
@@ -1,5 +1,5 @@
|
||||
|
||||
/mob/living/carbon/brain/Life()
|
||||
/mob/living/brain/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
@@ -10,19 +10,10 @@
|
||||
. = ..()
|
||||
handle_emp_damage()
|
||||
|
||||
/mob/living/carbon/brain/handle_breathing()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_mutations_and_radiation()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/update_stat()
|
||||
/mob/living/brain/update_stat()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(health <= config.health_threshold_dead)
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
if(stat != DEAD)
|
||||
death()
|
||||
var/obj/item/organ/brain/BR
|
||||
@@ -34,27 +25,25 @@
|
||||
BR.damaged_brain = 1 //beaten to a pulp
|
||||
|
||||
/* //currently unused feature, since brain outside a mmi is always dead.
|
||||
/mob/living/carbon/brain/proc/handle_brain_revival_life()
|
||||
/mob/living/brain/proc/handle_brain_revival_life()
|
||||
if(stat != DEAD)
|
||||
if(config.revival_brain_life != -1)
|
||||
if( !container && (world.time - timeofhostdeath) > config.revival_brain_life)
|
||||
death()
|
||||
*/
|
||||
|
||||
/mob/living/carbon/brain/proc/handle_emp_damage()
|
||||
/mob/living/brain/proc/handle_emp_damage()
|
||||
if(emp_damage)
|
||||
if(stat == DEAD)
|
||||
emp_damage = 0
|
||||
else
|
||||
emp_damage = max(emp_damage-1, 0)
|
||||
|
||||
/mob/living/carbon/brain/handle_status_effects()
|
||||
/mob/living/brain/handle_status_effects()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_disabilities()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_changeling()
|
||||
/mob/living/brain/handle_disabilities()
|
||||
return
|
||||
|
||||
|
||||
|
||||
+16
-11
@@ -5,7 +5,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "posibrain"
|
||||
w_class = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "biotech=3;programming=3;plasmatech=2"
|
||||
var/notified = 0
|
||||
var/askDelay = 600 //one minute
|
||||
@@ -14,6 +14,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
req_access = list(access_robotics)
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
braintype = "Android"
|
||||
var/autoping = TRUE //if it pings on creation immediately
|
||||
var/begin_activation_message = "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
|
||||
var/success_message = "<span class='notice'>The positronic brain pings, and its lights start flashing. Success!</span>"
|
||||
var/fail_message = "<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>"
|
||||
@@ -25,6 +26,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
var/new_mob_message = "<span class='notice'>The positronic brain chimes quietly.</span>"
|
||||
var/dead_message = "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>"
|
||||
var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
|
||||
var/picked_fluff_name //which fluff name we picked
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/Topic(href, href_list)
|
||||
@@ -38,7 +40,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
|
||||
if(!newlymade)
|
||||
posibrain_notif_cooldown = 1
|
||||
addtimer(src, "reset_posibrain_cooldown", askDelay, FALSE)
|
||||
addtimer(src, "reset_posibrain_cooldown", askDelay, TIMER_NORMAL)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/reset_posibrain_cooldown()
|
||||
posibrain_notif_cooldown = 0
|
||||
@@ -79,11 +81,10 @@ var/global/posibrain_notif_cooldown = 0
|
||||
name = "[initial(name)] ([C])"
|
||||
brainmob.name = C.real_name
|
||||
brainmob.real_name = C.real_name
|
||||
brainmob.dna = C.dna
|
||||
if(C.has_dna())
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
brainmob.timeofhostdeath = C.timeofdeath
|
||||
brainmob.stat = CONSCIOUS
|
||||
if(brainmob.mind)
|
||||
@@ -94,14 +95,16 @@ var/global/posibrain_notif_cooldown = 0
|
||||
brainmob.mind.remove_all_antag()
|
||||
brainmob.mind.wipe_memory()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/transfer_personality(mob/candidate)
|
||||
if(used || (brainmob && brainmob.key)) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
|
||||
candidate << "This brain has already been taken! Please try your possesion again later!"
|
||||
return
|
||||
notified = 0
|
||||
brainmob.ckey = candidate.ckey
|
||||
if(candidate.mind && !isobserver(candidate))
|
||||
candidate.mind.transfer_to(brainmob)
|
||||
else
|
||||
brainmob.ckey = candidate.ckey
|
||||
name = "[initial(name)] ([brainmob.name])"
|
||||
brainmob << welcome_message
|
||||
brainmob.mind.assigned_role = new_role
|
||||
@@ -122,7 +125,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
|
||||
if(!usr || !src)
|
||||
return
|
||||
if( (usr.disabilities & BLIND || usr.stat) && !istype(usr,/mob/dead/observer) )
|
||||
if((usr.disabilities & BLIND || usr.stat) && !isobserver(usr))
|
||||
usr << "<span class='notice'>Something is there but you can't see it.</span>"
|
||||
return
|
||||
|
||||
@@ -144,11 +147,13 @@ var/global/posibrain_notif_cooldown = 0
|
||||
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
brainmob = new(src)
|
||||
brainmob.name = "[pick(fluff_names)]-[rand(100, 999)]"
|
||||
picked_fluff_name = pick(fluff_names)
|
||||
brainmob.name = "[picked_fluff_name]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.loc = src
|
||||
brainmob.container = src
|
||||
ping_ghosts("created", TRUE)
|
||||
if(autoping)
|
||||
ping_ghosts("created", TRUE)
|
||||
..()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/brain/say(message)
|
||||
/mob/living/brain/say(message)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
@@ -9,15 +9,15 @@
|
||||
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
|
||||
..()
|
||||
|
||||
/mob/living/carbon/brain/radio(message, message_mode, list/spans)
|
||||
/mob/living/brain/radio(message, message_mode, list/spans)
|
||||
if(message_mode && istype(container, /obj/item/device/mmi))
|
||||
var/obj/item/device/mmi/R = container
|
||||
if(R.radio)
|
||||
R.radio.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/mob/living/carbon/brain/lingcheck()
|
||||
/mob/living/brain/lingcheck()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/brain/treat_message(message)
|
||||
/mob/living/brain/treat_message(message)
|
||||
return message
|
||||
+8
-13
@@ -4,35 +4,30 @@
|
||||
|
||||
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/adjustEarDamage()
|
||||
/mob/living/brain/adjustEarDamage()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/setEarDamage() // no ears to damage or heal
|
||||
/mob/living/brain/setEarDamage() // no ears to damage or heal
|
||||
return
|
||||
|
||||
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/blind_eyes() // no eyes to damage or heal
|
||||
/mob/living/brain/blind_eyes() // no eyes to damage or heal
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/adjust_blindness()
|
||||
/mob/living/brain/adjust_blindness()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/set_blindness()
|
||||
/mob/living/brain/set_blindness()
|
||||
return
|
||||
|
||||
/////////////////////////////////// EYE_BLURRY ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/blur_eyes()
|
||||
/mob/living/brain/blur_eyes()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/adjust_blurriness()
|
||||
/mob/living/brain/adjust_blurriness()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/set_blurriness()
|
||||
/mob/living/brain/set_blurriness()
|
||||
return
|
||||
|
||||
/////////////////////////////////// BLIND DISABILITY ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/become_blind()
|
||||
return
|
||||
@@ -7,10 +7,10 @@
|
||||
name = "alien"
|
||||
voice_name = "alien"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
gender = FEMALE
|
||||
gender = FEMALE //All xenos are girls!!
|
||||
dna = null
|
||||
faction = list("alien")
|
||||
ventcrawler = 2
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
languages_spoken = ALIEN
|
||||
languages_understood = ALIEN
|
||||
sight = SEE_MOBS
|
||||
@@ -19,7 +19,6 @@
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
var/deathNotified = 0
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
@@ -38,35 +37,22 @@
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
internal_organs += new /obj/item/organ/brain/alien
|
||||
internal_organs += new /obj/item/organ/alien/hivenode
|
||||
internal_organs += new /obj/item/organ/tongue/alien
|
||||
create_bodyparts() //initialize bodyparts
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.Insert(src)
|
||||
create_internal_organs()
|
||||
|
||||
AddAbility(new/obj/effect/proc_holder/alien/nightvisiontoggle(null))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/brain/alien
|
||||
internal_organs += new /obj/item/organ/alien/hivenode
|
||||
internal_organs += new /obj/item/organ/tongue/alien
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/assess_threat() // beepsky won't hunt aliums
|
||||
return -10
|
||||
|
||||
/mob/living/carbon/alien/adjustToxLoss(amount)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
|
||||
if(amount > 0)
|
||||
..(amount * 2)
|
||||
else
|
||||
..(amount)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/check_eye_prot()
|
||||
return ..() + 2
|
||||
|
||||
/mob/living/carbon/alien/getToxLoss()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
@@ -101,35 +87,6 @@
|
||||
else
|
||||
clear_alert("alien_fire")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/ex_act(severity, target)
|
||||
..()
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
adjustBruteLoss(60)
|
||||
adjustFireLoss(60)
|
||||
adjustEarDamage(30,120)
|
||||
|
||||
if(3)
|
||||
adjustBruteLoss(30)
|
||||
if (prob(50))
|
||||
Paralyse(1)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
updatehealth()
|
||||
|
||||
|
||||
/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/reagent_check(datum/reagent/R) //can metabolize all reagents
|
||||
return 0
|
||||
|
||||
@@ -229,3 +186,5 @@ Des: Removes all infected images from the alien.
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
|
||||
/mob/living/carbon/alien/can_hold_items()
|
||||
return has_fine_manipulation
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
|
||||
/mob/living/carbon/alien/get_eye_protection()
|
||||
return ..() + 2 //potential cyber implants + natural eye protection
|
||||
|
||||
/mob/living/carbon/alien/get_ear_protection()
|
||||
return 2 //no ears
|
||||
|
||||
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush)
|
||||
..(AM, skipcatch = 1, hitpush = 0)
|
||||
|
||||
@@ -7,11 +14,7 @@ As such, they can either help or harm other aliens. Help works like the human he
|
||||
In all, this is a lot like the monkey code. /N
|
||||
*/
|
||||
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
M << "You cannot attack people before the game has started."
|
||||
return
|
||||
|
||||
if (istype(loc, /turf) && istype(loc.loc, /area/start))
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
M << "No attacking people at spawn, you jackass."
|
||||
return
|
||||
|
||||
@@ -23,24 +26,22 @@ In all, this is a lot like the monkey code. /N
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake it up!</span>")
|
||||
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
|
||||
|
||||
if ("grab")
|
||||
grabbedby(M)
|
||||
|
||||
else
|
||||
if (health > 0)
|
||||
M.do_attack_animation(src)
|
||||
if(health > 0)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
var/damage = 1
|
||||
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
adjustBruteLoss(1)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
M << "<span class='warning'>[name] is too injured for that.</span>"
|
||||
return
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
@@ -56,8 +57,11 @@ In all, this is a lot like the monkey code. /N
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
grabbedby(M)
|
||||
if ("harm", "disarm")
|
||||
M.do_attack_animation(src)
|
||||
if ("harm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
return 1
|
||||
if("disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -65,9 +69,8 @@ In all, this is a lot like the monkey code. /N
|
||||
/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(..())
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(rand(1, 3))
|
||||
updatehealth()
|
||||
return
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(rand(1, 3), BRUTE, affecting)
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
|
||||
@@ -96,3 +99,28 @@ In all, this is a lot like the monkey code. /N
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/alien/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
switch (severity)
|
||||
if (1)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
take_overall_damage(60, 60)
|
||||
adjustEarDamage(30,120)
|
||||
|
||||
if(3)
|
||||
take_overall_damage(30,0)
|
||||
if(prob(50))
|
||||
Paralyse(1)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
|
||||
return 0//aliens are immune to acid.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/getToxLoss()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/adjustToxLoss(amount) //alien immune to tox damage
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
|
||||
if(amount > 0)
|
||||
..(amount * 2)
|
||||
else
|
||||
..(amount)
|
||||
|
||||
|
||||
|
||||
//aliens are immune to stamina damage.
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
@@ -1,5 +1,8 @@
|
||||
/mob/living/carbon/alien/spawn_gibs()
|
||||
xgibs(loc, viruses)
|
||||
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/xeno(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/xenobodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/gib_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-a"))
|
||||
@@ -9,17 +12,3 @@
|
||||
|
||||
/mob/living/carbon/alien/dust_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-a"))
|
||||
|
||||
/mob/living/carbon/alien/proc/deathNotice(var/area/AR, var/turf/T)
|
||||
if(src.z == 2) //Admin fuckery can continue without giving false death rattles to aliens on station or elsewhere.
|
||||
return
|
||||
src.deathNotified = 1
|
||||
T = get_turf(src)
|
||||
var/mob/living/carbon/alien/A
|
||||
for(A in world)
|
||||
A << "<span class='userdanger'>[src.name] has died at [T.loc.name]! </span>"
|
||||
|
||||
/mob/living/carbon/alien/death(gibbed)
|
||||
if(!deathNotified)
|
||||
deathNotice()
|
||||
..()
|
||||
|
||||
@@ -11,7 +11,6 @@ Doesn't work on other aliens/AI.*/
|
||||
panel = "Alien"
|
||||
var/plasma_cost = 0
|
||||
var/check_turf = 0
|
||||
|
||||
var/has_action = 1
|
||||
var/datum/action/spell_action/alien/action = null
|
||||
var/action_icon = 'icons/mob/actions.dmi'
|
||||
@@ -49,7 +48,7 @@ Doesn't work on other aliens/AI.*/
|
||||
if(!silent)
|
||||
user << "<span class='noticealien'>Not enough plasma stored.</span>"
|
||||
return 0
|
||||
if(check_turf && (!isturf(user.loc) || istype(user.loc, /turf/open/space)))
|
||||
if(check_turf && (!isturf(user.loc) || isspaceturf(user.loc)))
|
||||
if(!silent)
|
||||
user << "<span class='noticealien'>Bad place for a garden!</span>"
|
||||
return 0
|
||||
@@ -141,30 +140,16 @@ Doesn't work on other aliens/AI.*/
|
||||
/obj/effect/proc_holder/alien/acid/on_lose(mob/living/carbon/user)
|
||||
user.verbs.Remove(/mob/living/carbon/proc/corrosive_acid)
|
||||
|
||||
/obj/effect/proc_holder/alien/acid/proc/corrode(target,mob/living/carbon/user = usr)
|
||||
/obj/effect/proc_holder/alien/acid/proc/corrode(atom/target,mob/living/carbon/user = usr)
|
||||
if(target in oview(1,user))
|
||||
// OBJ CHECK
|
||||
if(isobj(target))
|
||||
var/obj/I = target
|
||||
if(I.unacidable) //So the aliens don't destroy energy fields/singularies/other aliens/etc with their acid.
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
return 0
|
||||
// TURF CHECK
|
||||
else if(istype(target, /turf))
|
||||
var/turf/T = target
|
||||
// R WALL
|
||||
if(istype(T, /turf/closed/wall/r_wall))
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
return 0
|
||||
// R FLOOR
|
||||
if(istype(T, /turf/open/floor/engine))
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
return 0
|
||||
else// Not a type we can acid.
|
||||
if(target.acid_act(200, 100))
|
||||
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
|
||||
return 1
|
||||
else
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
|
||||
|
||||
return 0
|
||||
new /obj/effect/acid(get_turf(target), target)
|
||||
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
|
||||
return 1
|
||||
else
|
||||
src << "<span class='noticealien'>Target is too far away.</span>"
|
||||
return 0
|
||||
@@ -172,8 +157,10 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/acid/fire(mob/living/carbon/alien/user)
|
||||
var/O = input("Select what to dissolve:","Dissolve",null) as obj|turf in oview(1,user)
|
||||
if(!O) return 0
|
||||
return corrode(O,user)
|
||||
if(!O || user.incapacitated())
|
||||
return 0
|
||||
else
|
||||
return corrode(O,user)
|
||||
|
||||
/mob/living/carbon/proc/corrosive_acid(O as obj|turf in oview(1)) // right click menu verb ugh
|
||||
set name = "Corrossive Acid"
|
||||
@@ -191,39 +178,40 @@ Doesn't work on other aliens/AI.*/
|
||||
name = "Spit Neurotoxin"
|
||||
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
|
||||
action_icon_state = "alien_neurotoxin_0"
|
||||
var/active = 0
|
||||
active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/fire(mob/living/carbon/user)
|
||||
var/message
|
||||
if(active)
|
||||
user.ranged_ability = null
|
||||
user << "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
active = 0
|
||||
else if(user.ranged_ability && user.ranged_ability != src)
|
||||
user << "<span class='warning'>You already have another aimed ability readied! Cancel it first."
|
||||
return
|
||||
message = "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
remove_ranged_ability(message)
|
||||
else
|
||||
user.ranged_ability = src
|
||||
active = 1
|
||||
user << "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
message = "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
add_ranged_ability(user, message, TRUE)
|
||||
|
||||
user.client.click_intercept = user.ranged_ability
|
||||
/obj/effect/proc_holder/alien/neurotoxin/update_icon()
|
||||
action.button_icon_state = "alien_neurotoxin_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/carbon/user, params, atom/target)
|
||||
var/p_cost = 50
|
||||
if(!iscarbon(user) || user.lying || user.stat)
|
||||
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
user.next_click = world.time + 6
|
||||
user.face_atom(target)
|
||||
var/p_cost = 50
|
||||
if(!iscarbon(ranged_ability_user) || ranged_ability_user.lying || ranged_ability_user.stat)
|
||||
remove_ranged_ability(ranged_ability_user)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/user = ranged_ability_user
|
||||
|
||||
if(user.getPlasma() < p_cost)
|
||||
user << "<span class='warning'>You need at least [p_cost] plasma to spit.</span>"
|
||||
remove_ranged_ability()
|
||||
return
|
||||
|
||||
var/turf/T = user.loc
|
||||
var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction
|
||||
if(!isturf(U) || !isturf(T))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
user.visible_message("<span class='danger'>[user] spits neurotoxin!", "<span class='alertalien'>You spit neurotoxin.</span>")
|
||||
var/obj/item/projectile/bullet/neurotoxin/A = new /obj/item/projectile/bullet/neurotoxin(user.loc)
|
||||
@@ -233,12 +221,25 @@ Doesn't work on other aliens/AI.*/
|
||||
user.newtonian_move(get_dir(U, T))
|
||||
user.adjustPlasma(-p_cost)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/on_lose(mob/living/carbon/user)
|
||||
if(user.ranged_ability == src)
|
||||
user.ranged_ability = null
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/add_ranged_ability(mob/living/user, msg)
|
||||
..()
|
||||
if(isalienadult(user))
|
||||
var/mob/living/carbon/alien/humanoid/A = user
|
||||
A.drooling = 1
|
||||
A.update_icons()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/remove_ranged_ability(mob/living/user, msg)
|
||||
..()
|
||||
if(isalienadult(user))
|
||||
var/mob/living/carbon/alien/humanoid/A = user
|
||||
A.drooling = 0
|
||||
A.update_icons()
|
||||
|
||||
/obj/effect/proc_holder/alien/resin
|
||||
name = "Secrete Resin"
|
||||
@@ -308,7 +309,7 @@ Doesn't work on other aliens/AI.*/
|
||||
/obj/effect/proc_holder/alien/sneak
|
||||
name = "Sneak"
|
||||
desc = "Blend into the shadows to stalk your prey."
|
||||
var/active = 0
|
||||
active = 0
|
||||
|
||||
action_icon_state = "alien_sneak"
|
||||
|
||||
|
||||
@@ -7,11 +7,14 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/New()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
|
||||
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/movement_delay()
|
||||
@@ -36,7 +39,7 @@
|
||||
if(!isturf(user.loc))
|
||||
user << "<span class='notice'>You can't evolve here!</span>"
|
||||
return 0
|
||||
if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal))
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal))
|
||||
var/mob/living/carbon/alien/humanoid/royal/praetorian/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
return 1
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
icon_state = "alienh_s"
|
||||
var/obj/screen/leap_icon = null
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/New()
|
||||
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small
|
||||
..()
|
||||
|
||||
@@ -45,16 +45,18 @@
|
||||
if(leaping || stat || buckled || lying)
|
||||
return
|
||||
|
||||
if(!has_gravity(src) || !has_gravity(A))
|
||||
if(!has_gravity() || !A.has_gravity())
|
||||
src << "<span class='alertalien'>It is unsafe to leap without gravity!</span>"
|
||||
//It's also extremely buggy visually, so it's balance+bugfix
|
||||
return
|
||||
|
||||
else //Maybe uses plasma in the future, although that wouldn't make any sense...
|
||||
leaping = 1
|
||||
weather_immunities += "lava"
|
||||
update_icons()
|
||||
throw_at(A,MAX_ALIEN_LEAP_DIST,1, spin=0, diagonals_first = 1)
|
||||
leaping = 0
|
||||
weather_immunities -= "lava"
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
|
||||
@@ -63,18 +65,20 @@
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(istype(A, /mob/living))
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/blocked = 0
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.check_shields(90, "the [name]", src, attack_type = THROWN_PROJECTILE_ATTACK))
|
||||
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
|
||||
blocked = 1
|
||||
if(!blocked)
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Weaken(5)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
else
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
@@ -82,7 +86,7 @@
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
|
||||
weakened = 2
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
if(leaping)
|
||||
leaping = 0
|
||||
|
||||
@@ -11,14 +11,18 @@
|
||||
|
||||
real_name = name
|
||||
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/praetorian/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/praetorian/movement_delay()
|
||||
. = ..()
|
||||
. += 1
|
||||
@@ -38,7 +42,7 @@
|
||||
if(node.recent_queen_death)
|
||||
user << "<span class='danger'>You are still too burdened with guilt to evolve into a queen.</span>"
|
||||
return 0
|
||||
if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal/queen))
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen))
|
||||
var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
if(new_xeno.client.prefs.unlock_content)
|
||||
|
||||
@@ -7,11 +7,15 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/New()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
AddAbility(new /obj/effect/proc_holder/alien/sneak)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/movement_delay()
|
||||
. = ..()
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/mob/living/carbon/alien/humanoid/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
|
||||
if(!deathNotified) //Did we message the other aliens that we died?
|
||||
deathNotice() //If not, do so now. This proc will change the deathNotified var to 1 so it never happens again.
|
||||
stat = DEAD
|
||||
|
||||
if(!gibbed)
|
||||
playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
|
||||
@@ -12,11 +10,6 @@
|
||||
update_canmove()
|
||||
update_icons()
|
||||
status_flags |= CANPUSH
|
||||
if(fireloss >= (maxHealth/2))
|
||||
spawn(10)
|
||||
visible_message("<span class='warning'>[src] starts shaking...</span>")
|
||||
spawn(30)
|
||||
src.gib()
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -32,20 +25,4 @@
|
||||
if(istype(node)) // just in case someone would ever add a diffirent node to hivenode slot
|
||||
node.queen_death()
|
||||
|
||||
return ..(gibbed)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/gib()
|
||||
visible_message("<span class='danger'>[src] explodes in a shower of acid blood and gibs!</span>")
|
||||
for(var/mob/living/M in viewers(2, src))
|
||||
if(ishuman(M))
|
||||
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
|
||||
M.adjustFireLoss(15)
|
||||
M.reagents.add_reagent("xblood",5)
|
||||
else if(ismonkey(M))
|
||||
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
|
||||
M.adjustFireLoss(15)
|
||||
M.reagents.add_reagent("xblood",5)
|
||||
else if(!isalien(M))
|
||||
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
|
||||
M.adjustFireLoss(15)
|
||||
..()
|
||||
return ..(gibbed)
|
||||
@@ -3,6 +3,7 @@
|
||||
icon_state = "alien_s"
|
||||
pass_flags = PASSTABLE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
limb_destroyer = 1
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
@@ -13,89 +14,35 @@
|
||||
var/custom_pixel_x_offset = 0 //for admin fuckery.
|
||||
var/custom_pixel_y_offset = 0
|
||||
var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
|
||||
var/drooling = 0 //For Neruotoxic spit overlays
|
||||
bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
|
||||
/obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/New()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/movement_delay()
|
||||
. = ..()
|
||||
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stuns
|
||||
|
||||
/mob/living/carbon/alien/humanoid/emp_act(severity)
|
||||
if(r_store) r_store.emp_act(severity)
|
||||
if(l_store) l_store.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
adjustBruteLoss(15)
|
||||
var/hitverb = "punched"
|
||||
if(mob_size < MOB_SIZE_LARGE)
|
||||
Paralyse(1)
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
hitverb = "slammed"
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hitverb] [src]!</span>")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
switch(M.a_intent)
|
||||
if ("harm")
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>")
|
||||
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
|
||||
Paralyse(2)
|
||||
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has weakened [src]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
|
||||
|
||||
if ("disarm")
|
||||
if (!lying)
|
||||
if (prob(5))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if (prob(50))
|
||||
drop_item()
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>")
|
||||
else
|
||||
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/restrained(ignore_grab)
|
||||
. = handcuffed
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
var/list/dat = list()
|
||||
dat += {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [l_hand ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [r_hand ? r_hand : "Nothing"]</A>
|
||||
<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"}
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_handcuffed]'>Handcuffed</A>"
|
||||
@@ -106,7 +53,7 @@
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
@@ -147,39 +94,29 @@
|
||||
else
|
||||
return initial(pixel_x)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_ear_prot()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_permeability_protection()
|
||||
return 0.8
|
||||
|
||||
/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
drop_all_held_items()
|
||||
for(var/atom/movable/A in stomach_contents)
|
||||
stomach_contents.Remove(A)
|
||||
new_xeno.stomach_contents.Add(A)
|
||||
A.loc = new_xeno
|
||||
..()
|
||||
|
||||
//For alien evolution/promotion procs. Checks for
|
||||
proc/alien_type_present(var/alienpath)
|
||||
//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
|
||||
/proc/get_alien_type(var/alienpath)
|
||||
for(var/mob/living/carbon/alien/humanoid/A in living_mob_list)
|
||||
if(!istype(A, alienpath))
|
||||
continue
|
||||
if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
|
||||
continue
|
||||
return 1
|
||||
return 0
|
||||
return A
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
|
||||
if(breath && breath.total_moles() > 0 && !sneaking)
|
||||
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
|
||||
devour_mob(pulling, devour_time = 60)
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
|
||||
devour_mob(pulling, devour_time = 60)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
adjustBruteLoss(15)
|
||||
var/hitverb = "punched"
|
||||
if(mob_size < MOB_SIZE_LARGE)
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
hitverb = "slammed"
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hitverb] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
switch(M.a_intent)
|
||||
if ("harm")
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
|
||||
Paralyse(2)
|
||||
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has weakened [src]!</span>")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
add_logs(M, src, "attacked")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='userdanger'>[M] has attempted to punch [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to punch [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
if ("disarm")
|
||||
if (!lying)
|
||||
if (prob(5))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if (prob(50))
|
||||
drop_item()
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='userdanger'>[M] has attempted to disarm [src]!</span>",\
|
||||
"<span class='userdanger'>[M] has attempted to disarm [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(!no_effect && !visual_effect_icon)
|
||||
visual_effect_icon = ATTACK_EFFECT_CLAW
|
||||
..()
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
|
||||
var/temperature = current
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//Common stuffs for Praetorian and Queen
|
||||
icon = 'icons/mob/alienqueen.dmi'
|
||||
status_flags = 0
|
||||
ventcrawler = 0 //pull over that ass too fat
|
||||
ventcrawler = VENTCRAWLER_NONE //pull over that ass too fat
|
||||
unique_name = 0
|
||||
pixel_x = -16
|
||||
bubble_icon = "alienroyal"
|
||||
@@ -22,7 +22,27 @@
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
icon_state = "alienq"
|
||||
var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite()
|
||||
|
||||
/datum/action/small_sprite
|
||||
name = "Toggle Giant Sprite - Others will always see you as giant"
|
||||
button_icon_state = "smallqueen"
|
||||
background_icon_state = "bg_alien"
|
||||
var/small = 0
|
||||
|
||||
/datum/action/small_sprite/Trigger()
|
||||
..()
|
||||
if(!small)
|
||||
var/image/I = image(icon = 'icons/mob/alien.dmi' , icon_state = "alienq_running", loc = owner)
|
||||
I.override = 1
|
||||
I.pixel_x -= owner.pixel_x
|
||||
I.pixel_y -= owner.pixel_y
|
||||
owner.add_alt_appearance("smallqueen", I, list(owner))
|
||||
|
||||
small = 1
|
||||
else
|
||||
owner.remove_alt_appearance("smallqueen")
|
||||
small = 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/New()
|
||||
//there should only be one queen
|
||||
@@ -37,18 +57,22 @@
|
||||
|
||||
real_name = src.name
|
||||
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
|
||||
smallsprite.Grant(src)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
internal_organs += new /obj/item/organ/alien/eggsac
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
|
||||
. = ..()
|
||||
. += 5
|
||||
. += 3
|
||||
|
||||
//Queen verbs
|
||||
/obj/effect/proc_holder/alien/lay_egg
|
||||
@@ -78,7 +102,7 @@
|
||||
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote/fire(mob/living/carbon/alien/user)
|
||||
var/obj/item/queenpromote/prom
|
||||
if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
user << "<span class='noticealien'>You already have a Praetorian!</span>"
|
||||
return 0
|
||||
else
|
||||
@@ -99,14 +123,14 @@
|
||||
name = "\improper royal parasite"
|
||||
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
|
||||
icon_state = "alien_medal"
|
||||
flags = ABSTRACT|NODROP
|
||||
flags = ABSTRACT|NODROP|DROPDEL
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
|
||||
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
|
||||
if(!isalienadult(M) || istype(M, /mob/living/carbon/alien/humanoid/royal))
|
||||
user << "<span class='noticealien'>You may only use this with your adult, non-royal children!</span>"
|
||||
return
|
||||
if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
user << "<span class='noticealien'>You already have a Praetorian!</span>"
|
||||
return
|
||||
|
||||
@@ -161,4 +185,4 @@
|
||||
desc = ""
|
||||
icon_state = "alienq"
|
||||
caste = "q"
|
||||
update_icons()
|
||||
update_icons()
|
||||
|
||||
@@ -20,8 +20,12 @@
|
||||
icon_state = "alien[caste]_sleep"
|
||||
else if(mob_size == MOB_SIZE_LARGE)
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit_[caste]")
|
||||
else
|
||||
icon_state = "alien[caste]_s"
|
||||
if(drooling)
|
||||
add_overlay("alienspit_s")
|
||||
|
||||
if(leaping)
|
||||
if(alt_icon == initial(alt_icon))
|
||||
@@ -50,28 +54,40 @@
|
||||
..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
var/cuff_icon = "aliencuff_s"
|
||||
var/dmi_file = 'icons/mob/alien.dmi'
|
||||
|
||||
if(mob_size == MOB_SIZE_LARGE)
|
||||
cuff_icon = "aliencuff_[caste]"
|
||||
dmi_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image(dmi_file,icon_state= cuff_icon, layer =-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
//Royals have bigger sprites, so inhand things must be handled differently.
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_r_hand()
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_hands()
|
||||
..()
|
||||
remove_overlay(R_HAND_LAYER)
|
||||
if(r_hand)
|
||||
var/itm_state = r_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = r_hand.icon_state
|
||||
remove_overlay(HANDS_LAYER)
|
||||
var/list/hands = list()
|
||||
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-R_HAND_LAYER)
|
||||
overlays_standing[R_HAND_LAYER] = I
|
||||
|
||||
apply_overlay(R_HAND_LAYER)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_l_hand()
|
||||
..()
|
||||
remove_overlay(L_HAND_LAYER)
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
if(l_hand)
|
||||
var/itm_state = l_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = l_hand.icon_state
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-HANDS_LAYER)
|
||||
hands += I
|
||||
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-L_HAND_LAYER)
|
||||
overlays_standing[L_HAND_LAYER] = I
|
||||
apply_overlay(L_HAND_LAYER)
|
||||
var/obj/item/r_hand = get_item_for_held_index(2)
|
||||
if(r_hand)
|
||||
var/itm_state = r_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = r_hand.icon_state
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-HANDS_LAYER)
|
||||
hands += I
|
||||
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
apply_overlay(HANDS_LAYER)
|
||||
@@ -8,3 +8,18 @@
|
||||
visible_message("<span class='name'>[src]</span> lets out a waning high-pitched cry.")
|
||||
|
||||
return ..(gibbed)
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/larva(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/larvabodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/larva/gib_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-l"))
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/larva/dust_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-l"))
|
||||
|
||||
@@ -14,16 +14,20 @@
|
||||
var/time_of_birth
|
||||
|
||||
rotate_on_lying = 0
|
||||
bodyparts = list(/obj/item/bodypart/chest/larva, /obj/item/bodypart/head/larva)
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/larva/New()
|
||||
regenerate_icons()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny
|
||||
|
||||
AddAbility(new/obj/effect/proc_holder/alien/hide(null))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/larva_evolve(null))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/larva/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny
|
||||
..()
|
||||
|
||||
//This needs to be fixed
|
||||
/mob/living/carbon/alien/larva/Stat()
|
||||
..()
|
||||
@@ -39,37 +43,6 @@
|
||||
/mob/living/carbon/alien/larva/attack_ui(slot_id)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
adjustBruteLoss(5 + rand(1,9))
|
||||
Paralyse(1)
|
||||
spawn()
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
add_logs(M, src, "attacked")
|
||||
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has kicked [src]!</span>")
|
||||
if ((stat != DEAD) && (damage > 4.9))
|
||||
Paralyse(rand(5,10))
|
||||
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to kick [src]!</span>")
|
||||
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/restrained(ignore_grab)
|
||||
. = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
add_logs(M, src, "attacked")
|
||||
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 4.9))
|
||||
Paralyse(rand(5,10))
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to kick [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
adjustBruteLoss(5 + rand(1,9))
|
||||
spawn()
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(!no_effect && !visual_effect_icon)
|
||||
visual_effect_icon = ATTACK_EFFECT_BITE
|
||||
..()
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/Life()
|
||||
set invisibility = 0
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
if(..())
|
||||
if(..()) //not dead
|
||||
// GROW!
|
||||
if(amount_grown < max_grown)
|
||||
amount_grown++
|
||||
@@ -20,7 +20,7 @@
|
||||
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
|
||||
death()
|
||||
return
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/mob/living/carbon/alien/larva/update_icons()
|
||||
var/state = 0
|
||||
if(amount_grown > 150)
|
||||
if(amount_grown > 80)
|
||||
state = 2
|
||||
else if(amount_grown > 50)
|
||||
state = 1
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/mob/living/carbon/alien/Life()
|
||||
findQueen()
|
||||
return..()
|
||||
|
||||
/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
|
||||
if(status_flags & GODMODE)
|
||||
@@ -42,4 +45,10 @@
|
||||
move_delay_add = max(0, move_delay_add - rand(1, 2))
|
||||
|
||||
/mob/living/carbon/alien/handle_changeling()
|
||||
return
|
||||
|
||||
/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
|
||||
@@ -31,7 +31,7 @@
|
||||
name = "plasma vessel"
|
||||
icon_state = "plasma"
|
||||
origin_tech = "biotech=5;plasmatech=4"
|
||||
w_class = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
zone = "chest"
|
||||
slot = "plasmavessel"
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/plant, /obj/effect/proc_holder/alien/transfer)
|
||||
@@ -49,7 +49,7 @@
|
||||
/obj/item/organ/alien/plasmavessel/large
|
||||
name = "large plasma vessel"
|
||||
icon_state = "plasma_large"
|
||||
w_class = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
storedPlasma = 200
|
||||
max_plasma = 500
|
||||
plasma_rate = 15
|
||||
@@ -61,7 +61,7 @@
|
||||
/obj/item/organ/alien/plasmavessel/small
|
||||
name = "small plasma vessel"
|
||||
icon_state = "plasma_small"
|
||||
w_class = 2
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
storedPlasma = 100
|
||||
max_plasma = 150
|
||||
plasma_rate = 5
|
||||
@@ -69,7 +69,7 @@
|
||||
/obj/item/organ/alien/plasmavessel/small/tiny
|
||||
name = "tiny plasma vessel"
|
||||
icon_state = "plasma_tiny"
|
||||
w_class = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_plasma = 100
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/transfer)
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
zone = "head"
|
||||
slot = "hivenode"
|
||||
origin_tech = "biotech=5;magnets=4;bluespace=3"
|
||||
w_class = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active.
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/whisper)
|
||||
|
||||
@@ -182,6 +182,6 @@
|
||||
icon_state = "eggsac"
|
||||
zone = "groin"
|
||||
slot = "eggsac"
|
||||
w_class = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
origin_tech = "biotech=6"
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/lay_egg)
|
||||
|
||||
@@ -4,4 +4,31 @@
|
||||
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>"
|
||||
|
||||
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/proc/findQueen()
|
||||
if(hud_used)
|
||||
hud_used.alien_queen_finder.cut_overlays()
|
||||
var/mob/queen = get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen)
|
||||
if(!queen)
|
||||
return
|
||||
var/turf/Q = get_turf(queen)
|
||||
var/turf/A = get_turf(src)
|
||||
if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far.
|
||||
return
|
||||
var/Qdir = get_dir(src, Q)
|
||||
var/Qdist = get_dist(src, Q)
|
||||
image(icon,loc,icon_state,layer,dir)
|
||||
var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen!
|
||||
switch(Qdist)
|
||||
if(2 to 7)
|
||||
finder_icon = "finder_near"
|
||||
if(8 to 20)
|
||||
finder_icon = "finder_med"
|
||||
if(21 to INFINITY)
|
||||
finder_icon = "finder_far"
|
||||
var/image/finder_eye = image('icons/mob/screen_alien.dmi', icon_state = finder_icon, dir = Qdir)
|
||||
hud_used.alien_queen_finder.add_overlay(finder_eye)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/findQueen()
|
||||
return //Queen already knows where she is. Hopefully.
|
||||
@@ -41,7 +41,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
|
||||
if(prob(4))
|
||||
owner << "<span class='danger'>Your muscles ache.</span>"
|
||||
if(prob(20))
|
||||
owner.take_organ_damage(1)
|
||||
owner.take_bodypart_damage(1)
|
||||
if(prob(4))
|
||||
owner << "<span class='danger'>Your stomach hurts.</span>"
|
||||
if(prob(20))
|
||||
@@ -99,7 +99,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
|
||||
new_xeno.notransform = 0
|
||||
new_xeno.invisibility = 0
|
||||
if(gib_on_success)
|
||||
owner.gib()
|
||||
owner.gib(TRUE)
|
||||
else
|
||||
owner.adjustBruteLoss(40)
|
||||
owner.overlays -= overlay
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
@@ -14,7 +14,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "facehugger"
|
||||
item_state = "facehugger"
|
||||
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
w_class = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = MASKINTERNALS
|
||||
throw_range = 5
|
||||
tint = 3
|
||||
@@ -23,8 +23,8 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
|
||||
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
|
||||
var/sterile = 0
|
||||
var/real = 1 //0 for the toy, 1 for real. Sure I could istype, but fuck that.
|
||||
var/sterile = FALSE
|
||||
var/real = TRUE //0 for the toy, 1 for real. Sure I could istype, but fuck that.
|
||||
var/strength = 5
|
||||
|
||||
var/attached = 0
|
||||
@@ -33,6 +33,16 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
name = "Lamarr"
|
||||
sterile = 1
|
||||
|
||||
/obj/item/clothing/mask/facehugger/dead
|
||||
icon_state = "facehugger_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/impregnated
|
||||
icon_state = "facehugger_impregnated"
|
||||
item_state = "facehugger_impregnated"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens
|
||||
attack_hand(user)
|
||||
return
|
||||
@@ -68,7 +78,6 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
/obj/item/clothing/mask/facehugger/bullet_act(obj/item/projectile/P)
|
||||
if(P.damage)
|
||||
Die()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
@@ -92,7 +101,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
return Attach(AM)
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin)
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
|
||||
if(!..())
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -107,62 +116,82 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon_state = "[initial(icon_state)]"
|
||||
Attach(hit_atom)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
|
||||
if(!isliving(M))
|
||||
return 0
|
||||
if((!iscorgi(M) && !iscarbon(M)) || isalien(M))
|
||||
return 0
|
||||
if(attached)
|
||||
return 0
|
||||
else
|
||||
attached++
|
||||
spawn(MAX_IMPREGNATION_TIME)
|
||||
attached = 0
|
||||
if(M.getorgan(/obj/item/organ/alien/hivenode))
|
||||
return 0
|
||||
if(M.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
return 0
|
||||
/obj/item/clothing/mask/facehugger/proc/valid_to_attach(mob/living/M)
|
||||
// valid targets: corgis, carbons except aliens and devils
|
||||
// facehugger state early exit checks
|
||||
if(stat != CONSCIOUS)
|
||||
return 0
|
||||
if(!sterile) M.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
|
||||
return FALSE
|
||||
if(attached)
|
||||
return FALSE
|
||||
if(!iscorgi(M) && !iscarbon(M))
|
||||
return FALSE
|
||||
if(iscarbon(M))
|
||||
// disallowed carbons
|
||||
if(isalien(M) || isdevil(M))
|
||||
return FALSE
|
||||
var/mob/living/carbon/target = M
|
||||
// gotta have a head to be implanted (no changelings or sentient plants)
|
||||
if(!target.get_bodypart("head"))
|
||||
return FALSE
|
||||
|
||||
if(target.getorgan(/obj/item/organ/alien/hivenode) || target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
return FALSE
|
||||
// carbon, has head, not alien or devil, has no hivenode or embryo: valid
|
||||
return TRUE
|
||||
else if(iscorgi(M))
|
||||
// corgi: valid
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
|
||||
if(!valid_to_attach(M))
|
||||
return FALSE
|
||||
// passed initial checks - time to leap!
|
||||
M.visible_message("<span class='danger'>[src] leaps at [M]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return 0
|
||||
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
|
||||
|
||||
// probiscis-blocker handling
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = M
|
||||
if(target.wear_mask)
|
||||
if(prob(20))
|
||||
return 0
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(W.flags & NODROP)
|
||||
return 0
|
||||
target.unEquip(W)
|
||||
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
return FALSE
|
||||
if(!istype(W,/obj/item/clothing/mask/facehugger))
|
||||
target.unEquip(W)
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return FALSE
|
||||
src.loc = target
|
||||
target.equip_to_slot(src, slot_wear_mask,,0)
|
||||
if(!sterile)
|
||||
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
else if (iscorgi(M))
|
||||
target.equip_to_slot_if_possible(src, slot_wear_mask, 0, 1, 1)
|
||||
// early returns and validity checks done: attach.
|
||||
attached++
|
||||
//ensure we detach once we no longer need to be attached
|
||||
spawn(MAX_IMPREGNATION_TIME)
|
||||
attached = 0
|
||||
|
||||
if (iscorgi(M))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/C = M
|
||||
loc = C
|
||||
C.facehugger = src
|
||||
C.regenerate_icons()
|
||||
|
||||
if(!sterile)
|
||||
M.take_bodypart_damage(strength,0) //done here so that humans in helmets take damage
|
||||
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
|
||||
GoIdle() //so it doesn't jump the people that tear it off
|
||||
|
||||
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
|
||||
Impregnate(M)
|
||||
|
||||
return 1
|
||||
return TRUE // time for a smoke
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target)
|
||||
if(!target || target.stat == DEAD) //was taken off or something
|
||||
@@ -182,7 +211,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon_state = "[initial(icon_state)]_impregnated"
|
||||
|
||||
var/obj/item/bodypart/chest/LC = target.get_bodypart("chest")
|
||||
if((!LC || LC.status != ORGAN_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
if((!LC || LC.status != BODYPART_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
new /obj/item/organ/body_egg/alien_embryo(target)
|
||||
|
||||
if(iscorgi(target))
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/alien/update_damage_overlays() //aliens don't have damage overlays.
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/update_body() // we don't use the bodyparts or body layers for aliens.
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/update_body_parts()//we don't use the bodyparts layer for aliens.
|
||||
return
|
||||
@@ -1,63 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/mob/living/carbon/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
has_limbs = 0
|
||||
stat = DEAD //we start dead by default
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/mob/living/carbon/brain/New(loc)
|
||||
..()
|
||||
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
|
||||
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
|
||||
src.loc = OB
|
||||
OB.brainmob = src
|
||||
|
||||
|
||||
/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.
|
||||
if(stat!=DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
container = null
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha))
|
||||
canmove = 1
|
||||
else
|
||||
canmove = 0
|
||||
return canmove
|
||||
|
||||
/mob/living/carbon/brain/toggle_throw_mode()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/blob_act(obj/effect/blob/B)
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/check_ear_prot()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/brain/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/carbon/brain/update_damage_hud()
|
||||
return //no red circles for brain
|
||||
|
||||
/mob/living/carbon/brain/can_be_revived()
|
||||
. = 1
|
||||
if(!container || health <= config.health_threshold_dead)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/brain/update_sight()
|
||||
return
|
||||
@@ -3,15 +3,18 @@
|
||||
|
||||
/mob/living/carbon/New()
|
||||
create_reagents(1000)
|
||||
update_body_parts() //to update the carbon's new bodyparts appearance
|
||||
..()
|
||||
|
||||
/mob/living/carbon/Destroy()
|
||||
for(var/atom/movable/guts in internal_organs)
|
||||
for(var/guts in internal_organs)
|
||||
qdel(guts)
|
||||
for(var/atom/movable/food in stomach_contents)
|
||||
qdel(food)
|
||||
for(var/BP in bodyparts)
|
||||
qdel(BP)
|
||||
for(var/imp in implants)
|
||||
qdel(imp)
|
||||
bodyparts = list()
|
||||
remove_from_all_data_huds()
|
||||
if(dna)
|
||||
@@ -25,19 +28,12 @@
|
||||
audible_message("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>", \
|
||||
"<span class='warning'>You hear something rumbling.</span>", 4,\
|
||||
"<span class='userdanger'>Something is rumbling inside your stomach!</span>")
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
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/organ = H.get_bodypart("chest")
|
||||
if (istype(organ, /obj/item/bodypart))
|
||||
var/obj/item/bodypart/temp = organ
|
||||
if(temp.take_damage(d, 0))
|
||||
H.update_damage_overlays(0)
|
||||
H.updatehealth()
|
||||
else
|
||||
src.take_organ_damage(d)
|
||||
var/obj/item/bodypart/BP = get_bodypart("chest")
|
||||
if(BP.receive_damage(d, 0))
|
||||
update_damage_overlays()
|
||||
visible_message("<span class='danger'>[user] attacks [src]'s stomach wall with the [I.name]!</span>", \
|
||||
"<span class='userdanger'>[user] attacks your stomach wall with the [I.name]!</span>")
|
||||
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
@@ -49,140 +45,65 @@
|
||||
src.gib()
|
||||
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, override = 0, tesla_shock = 0)
|
||||
shock_damage *= siemens_coeff
|
||||
if(dna && dna.species)
|
||||
shock_damage *= dna.species.siemens_coeff
|
||||
if(shock_damage<1 && !override)
|
||||
return 0
|
||||
if(reagents.has_reagent("teslium"))
|
||||
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
|
||||
take_overall_damage(0,shock_damage)
|
||||
//src.adjustFireLoss(shock_damage)
|
||||
//src.updatehealth()
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
jitteriness += 1000 //High numbers for violent convulsions
|
||||
do_jitter_animation(jitteriness)
|
||||
stuttering += 2
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(2)
|
||||
spawn(20)
|
||||
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(3)
|
||||
Weaken(3)
|
||||
if(override)
|
||||
return override
|
||||
else
|
||||
return shock_damage
|
||||
/mob/living/carbon/swap_hand(held_index)
|
||||
if(!held_index)
|
||||
held_index = (active_hand_index % held_items.len)+1
|
||||
|
||||
|
||||
/mob/living/carbon/swap_hand()
|
||||
var/obj/item/item_in_hand = src.get_active_hand()
|
||||
var/obj/item/item_in_hand = src.get_active_held_item()
|
||||
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
|
||||
if(istype(item_in_hand,/obj/item/weapon/twohanded))
|
||||
if(item_in_hand:wielded == 1)
|
||||
usr << "<span class='warning'>Your other hand is too busy holding the [item_in_hand.name]</span>"
|
||||
return
|
||||
src.hand = !( src.hand )
|
||||
if(hud_used && hud_used.inv_slots[slot_l_hand] && hud_used.inv_slots[slot_r_hand])
|
||||
var/oindex = active_hand_index
|
||||
active_hand_index = held_index
|
||||
if(hud_used)
|
||||
var/obj/screen/inventory/hand/H
|
||||
H = hud_used.inv_slots[slot_l_hand]
|
||||
H.update_icon()
|
||||
H = hud_used.inv_slots[slot_r_hand]
|
||||
H.update_icon()
|
||||
/*if (!( src.hand ))
|
||||
src.hands.setDir(NORTH)
|
||||
else
|
||||
src.hands.setDir(SOUTH)*/
|
||||
return
|
||||
H = hud_used.hand_slots["[oindex]"]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
H = hud_used.hand_slots["[held_index]"]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
|
||||
/mob/living/carbon/activate_hand(selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
|
||||
|
||||
/mob/living/carbon/activate_hand(selhand) //l/r OR 1-held_items.len
|
||||
if(!selhand)
|
||||
selhand = (active_hand_index % held_items.len)+1
|
||||
|
||||
if(istext(selhand))
|
||||
selhand = lowertext(selhand)
|
||||
|
||||
if(selhand == "right" || selhand == "r")
|
||||
selhand = 0
|
||||
selhand = 2
|
||||
if(selhand == "left" || selhand == "l")
|
||||
selhand = 1
|
||||
|
||||
if(selhand != src.hand)
|
||||
swap_hand()
|
||||
if(selhand != active_hand_index)
|
||||
swap_hand(selhand)
|
||||
else
|
||||
mode() // Activate held item
|
||||
|
||||
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
||||
if(on_fire)
|
||||
M << "<span class='warning'>You can't put them out with just your bare hands!"
|
||||
return
|
||||
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
|
||||
if(lying && surgeries.len)
|
||||
if(user != src && user.a_intent == INTENT_HELP)
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
if(health >= 0 && !(status_flags & FAKEDEATH))
|
||||
|
||||
if(lying)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to get them up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to get them up!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make them feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make them feel better!</span>")
|
||||
AdjustSleeping(-5)
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
if(resting)
|
||||
resting = 0
|
||||
update_canmove()
|
||||
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
|
||||
var/damage = intensity - check_eye_prot()
|
||||
if(.) // we've been flashed
|
||||
if(visual)
|
||||
return
|
||||
if(weakeyes)
|
||||
Stun(2)
|
||||
|
||||
if (damage == 1)
|
||||
src << "<span class='warning'>Your eyes sting a little.</span>"
|
||||
if(prob(40))
|
||||
adjust_eye_damage(1)
|
||||
|
||||
else if (damage == 2)
|
||||
src << "<span class='warning'>Your eyes burn.</span>"
|
||||
adjust_eye_damage(rand(2, 4))
|
||||
|
||||
else if( damage > 3)
|
||||
src << "<span class='warning'>Your eyes itch and burn severely!</span>"
|
||||
adjust_eye_damage(rand(12, 16))
|
||||
|
||||
if(eye_damage > 10)
|
||||
blind_eyes(damage)
|
||||
blur_eyes(damage * rand(3, 6))
|
||||
|
||||
if(eye_damage > 20)
|
||||
if(prob(eye_damage - 20))
|
||||
if(become_nearsighted())
|
||||
src << "<span class='warning'>Your eyes start to burn badly!</span>"
|
||||
else if(prob(eye_damage - 25))
|
||||
if(become_blind())
|
||||
src << "<span class='warning'>You can't see anything!</span>"
|
||||
else
|
||||
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(-500)
|
||||
return 1
|
||||
else if(damage == 0) // just enough protection
|
||||
if(prob(20))
|
||||
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(0)
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
Weaken(1)
|
||||
take_bodypart_damage(10)
|
||||
if(iscarbon(hit_atom))
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
victim.Weaken(1)
|
||||
Weaken(1)
|
||||
victim.take_bodypart_damage(10)
|
||||
take_bodypart_damage(10)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>", "<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,1)
|
||||
|
||||
|
||||
//Throwing stuff
|
||||
@@ -217,7 +138,7 @@
|
||||
return
|
||||
|
||||
var/atom/movable/thrown_thing
|
||||
var/obj/item/I = src.get_active_hand()
|
||||
var/obj/item/I = src.get_active_held_item()
|
||||
|
||||
if(!I)
|
||||
if(pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
|
||||
@@ -256,8 +177,11 @@
|
||||
<HR>
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=[slot_head]'> [(head && !(head.flags&ABSTRACT)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=\ref[src];item=[slot_wear_mask]'> [(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]</A>"}
|
||||
<BR><B>Neck:</B> <A href='?src=\ref[src];item=[slot_neck]'> [(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "Nothing"]</A>"}
|
||||
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "Nothing"]</a>"
|
||||
|
||||
dat += "<BR><B>Back:</B> <A href='?src=\ref[src];item=[slot_back]'>[back ? back : "Nothing"]</A>"
|
||||
|
||||
@@ -305,13 +229,6 @@
|
||||
/mob/living/carbon/is_muzzled()
|
||||
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
|
||||
/mob/living/carbon/blob_act(obj/effect/blob/B)
|
||||
if (stat == DEAD)
|
||||
return
|
||||
else
|
||||
show_message("<span class='userdanger'>The blob attacks!</span>")
|
||||
adjustBruteLoss(10)
|
||||
|
||||
/mob/living/carbon/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
var/D = dir
|
||||
@@ -347,7 +264,7 @@
|
||||
|
||||
/mob/living/carbon/resist_fire()
|
||||
fire_stacks -= 5
|
||||
Weaken(3,1)
|
||||
Weaken(3, 1, 1)
|
||||
spin(32,2)
|
||||
visible_message("<span class='danger'>[src] rolls on the floor, trying to put themselves out!</span>", \
|
||||
"<span class='notice'>You stop, drop, and roll!</span>")
|
||||
@@ -407,6 +324,7 @@
|
||||
W.dropped(src)
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
if (legcuffed)
|
||||
var/obj/item/weapon/W = legcuffed
|
||||
legcuffed = null
|
||||
@@ -418,6 +336,7 @@
|
||||
W.dropped(src)
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
|
||||
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
|
||||
if(!I.loc || buckled)
|
||||
@@ -452,6 +371,10 @@
|
||||
legcuffed = null
|
||||
update_inv_legcuffed()
|
||||
return
|
||||
else
|
||||
unEquip(I)
|
||||
I.dropped()
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/proc/is_mouth_covered(head_only = 0, mask_only = 0)
|
||||
@@ -464,10 +387,6 @@
|
||||
else
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/check_ear_prot()
|
||||
if(head && (head.flags & HEADBANGPROTECT))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/accident(obj/item/I)
|
||||
if(!I || (I.flags & (NODROP|ABSTRACT)))
|
||||
return
|
||||
@@ -496,17 +415,6 @@
|
||||
var/turf/target = get_turf(loc)
|
||||
I.throw_at(target,I.throw_range,I.throw_speed,src)
|
||||
|
||||
/mob/living/carbon/emp_act(severity)
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/check_eye_prot()
|
||||
var/number = ..()
|
||||
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
|
||||
number += EFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/proc/AddAbility(obj/effect/proc_holder/alien/A)
|
||||
abilities.Add(A)
|
||||
A.on_gain(src)
|
||||
@@ -535,7 +443,15 @@
|
||||
|
||||
add_abilities_to_panel()
|
||||
|
||||
/mob/living/carbon/attack_ui(slot)
|
||||
if(!has_hand_for_held_index(active_hand_index))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1, var/toxic = 0)
|
||||
if(dna && dna.species && NOHUNGER in dna.species.species_traits)
|
||||
return 1
|
||||
|
||||
if(nutrition < 100 && !blood)
|
||||
if(message)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
@@ -575,12 +491,27 @@
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(dna)
|
||||
dna.real_name = real_name
|
||||
|
||||
//Updates the mob's health from bodyparts and mob damage variables
|
||||
/mob/living/carbon/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/X in bodyparts) //hardcoded to streamline things a bit
|
||||
var/obj/item/bodypart/BP = X
|
||||
total_brute += BP.brute_dam
|
||||
total_burn += BP.burn_dam
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
|
||||
become_husk()
|
||||
med_hud_set_health()
|
||||
|
||||
/mob/living/carbon/update_sight()
|
||||
if(!client)
|
||||
return
|
||||
@@ -636,7 +567,7 @@
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
|
||||
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
|
||||
var/severity = 0
|
||||
switch(health)
|
||||
if(-20 to -10) severity = 1
|
||||
@@ -714,10 +645,10 @@
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
if(health<= config.health_threshold_dead || !getorgan(/obj/item/organ/brain))
|
||||
if(health<= HEALTH_THRESHOLD_DEAD || !getorgan(/obj/item/organ/brain))
|
||||
death()
|
||||
return
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
@@ -735,8 +666,7 @@
|
||||
//called when we get cuffed/uncuffed
|
||||
/mob/living/carbon/proc/update_handcuffed()
|
||||
if(handcuffed)
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
drop_all_held_items()
|
||||
stop_pulling()
|
||||
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
|
||||
else
|
||||
@@ -752,8 +682,10 @@
|
||||
if(B)
|
||||
B.damaged_brain = 0
|
||||
for(var/datum/disease/D in viruses)
|
||||
D.cure(0)
|
||||
if (D.severity != NONTHREAT)
|
||||
D.cure(0)
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
handcuffed = initial(handcuffed)
|
||||
for(var/obj/item/weapon/restraints/R in contents) //actually remove cuffs from inventory
|
||||
qdel(R)
|
||||
@@ -771,7 +703,8 @@
|
||||
if(qdeleted(src))
|
||||
return
|
||||
var/organs_amt = 0
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/O = X
|
||||
if(prob(50))
|
||||
organs_amt++
|
||||
O.Remove(src)
|
||||
@@ -781,12 +714,59 @@
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health=1)
|
||||
if(has_dna() && TOXINLOVER in dna.species.specflags) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
if(amount > 0)
|
||||
blood_volume -= 5*amount
|
||||
else
|
||||
blood_volume -= amount
|
||||
return ..()
|
||||
/mob/living/carbon/ExtinguishMob()
|
||||
for(var/X in get_equipped_items())
|
||||
var/obj/item/I = X
|
||||
I.acid_level = 0 //washes off the acid on our clothes
|
||||
I.extinguish() //extinguishes our clothes
|
||||
..()
|
||||
|
||||
/mob/living/carbon/fakefire(var/fire_icon = "Generic_mob_burning")
|
||||
overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"= fire_icon, "layer"=-FIRE_LAYER)
|
||||
apply_overlay(FIRE_LAYER)
|
||||
|
||||
/mob/living/carbon/fakefireextinguish()
|
||||
remove_overlay(FIRE_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
|
||||
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
|
||||
"<span class='userdanger'>[src] is attempting to devour you!</span>")
|
||||
if(!do_mob(src, C, devour_time))
|
||||
return
|
||||
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == INTENT_GRAB)
|
||||
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
|
||||
"<span class='userdanger'>[src] devours you!</span>")
|
||||
C.forceMove(src)
|
||||
stomach_contents.Add(C)
|
||||
add_logs(src, C, "devoured")
|
||||
|
||||
/mob/living/carbon/proc/create_bodyparts()
|
||||
var/l_arm_index_next = -1
|
||||
var/r_arm_index_next = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/O = new X()
|
||||
O.owner = src
|
||||
bodyparts.Remove(X)
|
||||
bodyparts.Add(O)
|
||||
if(O.body_part == ARM_LEFT)
|
||||
l_arm_index_next += 2
|
||||
O.held_index = l_arm_index_next //1, 3, 5, 7...
|
||||
hand_bodyparts += O
|
||||
else if(O.body_part == ARM_RIGHT)
|
||||
r_arm_index_next += 2
|
||||
O.held_index = r_arm_index_next //2, 4, 6, 8...
|
||||
hand_bodyparts += O
|
||||
|
||||
|
||||
/mob/living/carbon/proc/create_internal_organs()
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
I.Insert(src)
|
||||
|
||||
/mob/living/carbon/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
.["Make AI"] = "?_src_=vars;makeai=\ref[src]"
|
||||
.["Modify bodypart"] = "?_src_=vars;editbodypart=\ref[src]"
|
||||
.["Modify organs"] = "?_src_=vars;editorgans=\ref[src]"
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
|
||||
/mob/living/carbon/get_eye_protection()
|
||||
var/number = ..()
|
||||
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
|
||||
number += EFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/get_ear_protection()
|
||||
if(head && (head.flags & HEADBANGPROTECT))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(def_zone)
|
||||
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
|
||||
affecting.dismember(P.damtype)
|
||||
|
||||
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
|
||||
if(!skipcatch) //ugly, but easy
|
||||
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
|
||||
if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
@@ -11,25 +27,46 @@
|
||||
return 1
|
||||
..()
|
||||
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
Weaken(1)
|
||||
take_organ_damage(10)
|
||||
|
||||
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
|
||||
if(lying)
|
||||
if(surgeries.len)
|
||||
if(user != src && user.a_intent == "help")
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user, src))
|
||||
return 1
|
||||
return ..()
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected))
|
||||
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
|
||||
affecting = bodyparts[1]
|
||||
send_item_attack_message(I, user, affecting.name)
|
||||
if(I.force)
|
||||
apply_damage(I.force, I.damtype, affecting)
|
||||
damage_clothes(I.force, I.damtype, "melee", affecting.body_zone)
|
||||
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
|
||||
if(prob(33))
|
||||
I.add_mob_blood(src)
|
||||
var/turf/location = get_turf(src)
|
||||
add_splatter_floor(location)
|
||||
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
|
||||
user.add_mob_blood(src)
|
||||
|
||||
if(affecting.body_zone == "head")
|
||||
if(wear_mask)
|
||||
wear_mask.add_mob_blood(src)
|
||||
update_inv_wear_mask()
|
||||
if(wear_neck)
|
||||
wear_neck.add_mob_blood(src)
|
||||
update_inv_neck()
|
||||
if(head)
|
||||
head.add_mob_blood(src)
|
||||
update_inv_head()
|
||||
|
||||
//dismemberment
|
||||
var/probability = I.get_dismemberment_chance(affecting)
|
||||
if(prob(probability))
|
||||
if(affecting.dismember(I.damtype))
|
||||
I.add_mob_blood(src)
|
||||
playsound(get_turf(src), I.get_dismember_sound(), 80, 1)
|
||||
return TRUE //successful attack
|
||||
|
||||
/mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user)
|
||||
return //so we don't call the carbon's attack_hand().
|
||||
|
||||
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
|
||||
for(var/datum/disease/D in viruses)
|
||||
if(D.IsSpreadByTouch())
|
||||
@@ -39,19 +76,15 @@
|
||||
if(D.IsSpreadByTouch())
|
||||
ContractDisease(D)
|
||||
|
||||
if(lying)
|
||||
if(user.a_intent == "help")
|
||||
if(surgeries.len)
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user, src))
|
||||
return 1
|
||||
if(lying && surgeries.len)
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(!istype(M, /mob/living/carbon))
|
||||
return 0
|
||||
|
||||
for(var/datum/disease/D in viruses)
|
||||
if(D.IsSpreadByTouch())
|
||||
M.ContractDisease(D)
|
||||
@@ -60,7 +93,7 @@
|
||||
if(D.IsSpreadByTouch())
|
||||
ContractDisease(D)
|
||||
|
||||
if(M.a_intent == "help")
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
help_shake_act(M)
|
||||
return 0
|
||||
|
||||
@@ -95,14 +128,177 @@
|
||||
updatehealth()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
|
||||
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
|
||||
"<span class='userdanger'>[src] is attempting to devour you!</span>")
|
||||
if(!do_mob(src, C, devour_time))
|
||||
/mob/living/carbon/proc/dismembering_strike(mob/living/attacker, dam_zone)
|
||||
if(!attacker.limb_destroyer)
|
||||
return dam_zone
|
||||
var/obj/item/bodypart/affecting
|
||||
if(dam_zone && attacker.client)
|
||||
affecting = get_bodypart(ran_zone(dam_zone))
|
||||
else
|
||||
var/list/things_to_ruin = shuffle(bodyparts.Copy())
|
||||
for(var/B in things_to_ruin)
|
||||
var/obj/item/bodypart/bodypart = B
|
||||
if(bodypart.body_zone == "head" || bodypart.body_zone == "chest")
|
||||
continue
|
||||
if(!affecting || ((affecting.get_damage() / affecting.max_damage) < (bodypart.get_damage() / bodypart.max_damage)))
|
||||
affecting = bodypart
|
||||
if(affecting)
|
||||
dam_zone = affecting.body_zone
|
||||
if(affecting.get_damage() >= affecting.max_damage)
|
||||
affecting.dismember()
|
||||
return null
|
||||
return affecting.body_zone
|
||||
return dam_zone
|
||||
|
||||
|
||||
/mob/living/carbon/blob_act(obj/structure/blob/B)
|
||||
if (stat == DEAD)
|
||||
return
|
||||
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == "grab")
|
||||
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
|
||||
"<span class='userdanger'>[src] devours you!</span>")
|
||||
C.forceMove(src)
|
||||
stomach_contents.Add(C)
|
||||
add_logs(src, C, "devoured")
|
||||
else
|
||||
show_message("<span class='userdanger'>The blob attacks!</span>")
|
||||
adjustBruteLoss(10)
|
||||
|
||||
/mob/living/carbon/emp_act(severity)
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/O = X
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
|
||||
shock_damage *= siemens_coeff
|
||||
if(dna && dna.species)
|
||||
shock_damage *= dna.species.siemens_coeff
|
||||
if(shock_damage<1 && !override)
|
||||
return 0
|
||||
if(reagents.has_reagent("teslium"))
|
||||
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
|
||||
if(illusion)
|
||||
adjustStaminaLoss(shock_damage)
|
||||
else
|
||||
take_overall_damage(0,shock_damage)
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
jitteriness += 1000 //High numbers for violent convulsions
|
||||
do_jitter_animation(jitteriness)
|
||||
stuttering += 2
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(2)
|
||||
spawn(20)
|
||||
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(3)
|
||||
Weaken(3)
|
||||
if(override)
|
||||
return override
|
||||
else
|
||||
return shock_damage
|
||||
|
||||
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
||||
if(on_fire)
|
||||
M << "<span class='warning'>You can't put them out with just your bare hands!"
|
||||
return
|
||||
|
||||
if(health >= 0 && !(status_flags & FAKEDEATH))
|
||||
|
||||
if(lying)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
AdjustSleeping(-5)
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
if(resting)
|
||||
resting = 0
|
||||
update_canmove()
|
||||
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
|
||||
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
. = ..()
|
||||
|
||||
var/damage = intensity - get_eye_protection()
|
||||
if(.) // we've been flashed
|
||||
if(visual)
|
||||
return
|
||||
if(weakeyes)
|
||||
Stun(2)
|
||||
|
||||
if (damage == 1)
|
||||
src << "<span class='warning'>Your eyes sting a little.</span>"
|
||||
if(prob(40))
|
||||
adjust_eye_damage(1)
|
||||
|
||||
else if (damage == 2)
|
||||
src << "<span class='warning'>Your eyes burn.</span>"
|
||||
adjust_eye_damage(rand(2, 4))
|
||||
|
||||
else if( damage > 3)
|
||||
src << "<span class='warning'>Your eyes itch and burn severely!</span>"
|
||||
adjust_eye_damage(rand(12, 16))
|
||||
|
||||
if(eye_damage > 10)
|
||||
blind_eyes(damage)
|
||||
blur_eyes(damage * rand(3, 6))
|
||||
|
||||
if(eye_damage > 20)
|
||||
if(prob(eye_damage - 20))
|
||||
if(become_nearsighted())
|
||||
src << "<span class='warning'>Your eyes start to burn badly!</span>"
|
||||
else if(prob(eye_damage - 25))
|
||||
if(become_blind())
|
||||
src << "<span class='warning'>You can't see anything!</span>"
|
||||
else
|
||||
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(-500)
|
||||
return 1
|
||||
else if(damage == 0) // just enough protection
|
||||
if(prob(20))
|
||||
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(0)
|
||||
|
||||
|
||||
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
|
||||
var/ear_safety = get_ear_protection()
|
||||
if(ear_safety < 2) //has ears
|
||||
var/effect_amount = intensity - ear_safety
|
||||
if(effect_amount > 0)
|
||||
if(stun_pwr)
|
||||
Stun(stun_pwr*effect_amount)
|
||||
Weaken(stun_pwr*effect_amount)
|
||||
if(deafen_pwr || damage_pwr)
|
||||
setEarDamage(ear_damage + damage_pwr*effect_amount, max(ear_deaf, deafen_pwr*effect_amount))
|
||||
if (ear_damage >= 15)
|
||||
src << "<span class='warning'>Your ears start to ring badly!</span>"
|
||||
if(prob(ear_damage - 5))
|
||||
src << "<span class='warning'>You can't hear anything!</span>"
|
||||
disabilities |= DEAF
|
||||
else if(ear_damage >= 5)
|
||||
src << "<span class='warning'>Your ears start to ring!</span>"
|
||||
src << sound('sound/weapons/flash_ring.ogg',0,1,0,250)
|
||||
return effect_amount //how soundbanged we are
|
||||
|
||||
|
||||
/mob/living/carbon/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
if(damage_type != BRUTE && damage_type != BURN)
|
||||
return
|
||||
damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed
|
||||
if(!def_zone || def_zone == "head")
|
||||
var/obj/item/clothing/hit_clothes
|
||||
if(wear_mask)
|
||||
hit_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
hit_clothes = wear_neck
|
||||
if(head)
|
||||
hit_clothes = head
|
||||
if(hit_clothes)
|
||||
hit_clothes.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/mob/living/
|
||||
var/list/stomach_contents = list()
|
||||
|
||||
/mob/living/carbon
|
||||
gender = MALE
|
||||
//var/list/stomach_contents = list()
|
||||
pressure_resistance = 15
|
||||
var/list/stomach_contents = list()
|
||||
var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know.
|
||||
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
|
||||
|
||||
var/list/implants = list()
|
||||
|
||||
var/silent = 0 //Can't talk. Value goes down every life proc. //NOTE TO FUTURE CODERS: DO NOT INITIALIZE NUMERICAL VARS AS NULL OR I WILL MURDER YOU.
|
||||
|
||||
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
|
||||
@@ -15,17 +15,24 @@
|
||||
//inventory slots
|
||||
var/obj/item/back = null
|
||||
var/obj/item/clothing/mask/wear_mask = null
|
||||
var/obj/item/clothing/neck/wear_neck = null
|
||||
var/obj/item/weapon/tank/internal = null
|
||||
var/obj/item/head = null
|
||||
|
||||
var/obj/item/gloves = null //only used by humans
|
||||
var/obj/item/shoes = null //only used by humans.
|
||||
var/obj/item/clothing/glasses/glasses = null //only used by humans.
|
||||
var/obj/item/ears = null //only used by humans.
|
||||
|
||||
var/datum/dna/dna = null//Carbon
|
||||
var/datum/mind/last_mind = null //last mind to control this mob, for blood-based cloning
|
||||
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
|
||||
var/co2overloadtime = null
|
||||
var/temperature_resistance = T0C+75
|
||||
has_limbs = 1
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab
|
||||
|
||||
var/list/obj/effect/proc_holder/alien/abilities = list()
|
||||
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
@@ -34,4 +41,8 @@
|
||||
|
||||
var/tinttotal = 0 // Total level of visualy impairing items
|
||||
|
||||
var/list/bodyparts = list() //Gets filled up in the constructor (New() proc in human.dm and monkey.dm)
|
||||
var/list/bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
//Gets filled up in create_bodyparts()
|
||||
|
||||
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
|
||||
@@ -1,16 +1,35 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
. = ..()
|
||||
. += grab_state * 3
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
var/FP
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
var/obj/item/device/flightpack/F = C.get_flightpack()
|
||||
if(istype(F) && F.flight)
|
||||
FP = 1
|
||||
. = ..(FP)
|
||||
if(!FP)
|
||||
. += grab_state * 1 //Flightpacks are too powerful to be slowed too much by the weight of a corpse.
|
||||
else
|
||||
. += grab_state * 3 //can't go fast while grabbing something.
|
||||
|
||||
if(!get_leg_ignore()) //ignore the fact we lack legs
|
||||
var/leg_amount = get_num_legs()
|
||||
. += 6 - 3*leg_amount //the fewer the legs, the slower the mob
|
||||
if(!leg_amount)
|
||||
. += 6 - 3*get_num_arms() //crawling is harder with fewer arms
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
|
||||
|
||||
var/const/NO_SLIP_WHEN_WALKING = 1
|
||||
var/const/SLIDE = 2
|
||||
var/const/GALOSHES_DONT_HELP = 4
|
||||
var/const/SLIDE_ICE = 8
|
||||
|
||||
/mob/living/carbon/slip(s_amount, w_amount, obj/O, lube)
|
||||
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
|
||||
if(movement_type & FLYING)
|
||||
return 0
|
||||
if(!(lube&SLIDE_ICE))
|
||||
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
|
||||
return loc.handle_slip(src, s_amount, w_amount, O, lube)
|
||||
|
||||
|
||||
@@ -20,6 +39,10 @@ var/const/GALOSHES_DONT_HELP = 4
|
||||
if(!isturf(loc))
|
||||
return 0
|
||||
|
||||
var/obj/item/device/flightpack/F = get_flightpack()
|
||||
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
|
||||
return 1
|
||||
|
||||
// Do we have a jetpack implant (and is it on)?
|
||||
var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot("thrusters")
|
||||
if(istype(T) && movement_dir && T.allow_thrust(0.01))
|
||||
@@ -29,14 +52,14 @@ var/const/GALOSHES_DONT_HELP = 4
|
||||
if(istype(J) && (movement_dir || J.stabilizers) && J.allow_thrust(0.01, src))
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.nutrition && src.stat != 2)
|
||||
src.nutrition -= HUNGER_FACTOR/10
|
||||
if(src.m_intent == "run")
|
||||
src.nutrition -= HUNGER_FACTOR/10
|
||||
if((src.disabilities & FAT) && src.m_intent == "run" && src.bodytemperature <= 360)
|
||||
src.bodytemperature += 2
|
||||
if(dna && dna.species && (NOHUNGER in dna.species.species_traits))
|
||||
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
if(m_intent == MOVE_INTENT_RUN)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
if((disabilities & FAT) && m_intent == MOVE_INTENT_RUN && bodytemperature <= 360)
|
||||
bodytemperature += 2
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
|
||||
|
||||
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || hit_percent <= 0)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/BP = null
|
||||
if(islimb(def_zone)) //we specified a bodypart object
|
||||
BP = def_zone
|
||||
else
|
||||
if(!def_zone)
|
||||
def_zone = ran_zone(def_zone)
|
||||
BP = get_bodypart(check_zone(def_zone))
|
||||
if(!BP)
|
||||
BP = bodyparts[1]
|
||||
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
if(BP)
|
||||
if(BP.receive_damage(damage * hit_percent, 0))
|
||||
update_damage_overlays()
|
||||
else //no bodypart, we deal damage with a more general method.
|
||||
adjustBruteLoss(damage * hit_percent)
|
||||
if(BURN)
|
||||
if(BP)
|
||||
if(BP.receive_damage(0, damage * hit_percent))
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustFireLoss(damage * hit_percent)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage * hit_percent)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage * hit_percent)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/getBruteLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.brute_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/getFireLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/adjustBruteLoss(amount, updating_health = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0)
|
||||
else
|
||||
heal_overall_damage(-amount, 0, 0, 1, updating_health)
|
||||
|
||||
/mob/living/carbon/adjustFireLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount)
|
||||
else
|
||||
heal_overall_damage(0, -amount)
|
||||
|
||||
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health=1)
|
||||
if(has_dna() && TOXINLOVER in dna.species.species_traits) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
if(amount > 0)
|
||||
blood_volume -= 5*amount
|
||||
else
|
||||
blood_volume -= amount
|
||||
return ..()
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
/mob/living/carbon/proc/get_damaged_bodyparts(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Returns a list of damageable bodyparts
|
||||
/mob/living/carbon/proc/get_damageable_bodyparts()
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Heals ONE bodypart randomly selected from damaged ones.
|
||||
//It automatically updates damage overlays if necessary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/heal_bodypart_damage(brute, burn, only_robotic = 0, only_organic = 1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.heal_damage(brute, burn, only_robotic, only_organic))
|
||||
update_damage_overlays()
|
||||
|
||||
//Damages ONE bodypart randomly selected from damagable ones.
|
||||
//It automatically updates damage overlays if necessary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/take_bodypart_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.receive_damage(brute,burn))
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
//Heal MANY bodyparts, in random order
|
||||
/mob/living/carbon/heal_overall_damage(brute, burn, only_robotic = 0, only_organic = 1, updating_health = 1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
update |= picked.heal_damage(brute,burn, only_robotic, only_organic, 0)
|
||||
|
||||
brute -= (brute_was-picked.brute_dam)
|
||||
burn -= (burn_was-picked.burn_dam)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/carbon/take_overall_damage(brute, burn, updating_health = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return //godmode
|
||||
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
var/brute_per_part = round(brute/parts.len, 0.01)
|
||||
var/burn_per_part = round(burn/parts.len, 0.01)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
|
||||
update |= picked.receive_damage(brute_per_part,burn_per_part, 0)
|
||||
|
||||
brute -= (picked.brute_dam - brute_was)
|
||||
burn -= (picked.burn_dam - burn_was)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
staminaloss = Clamp(staminaloss + amount, 0, maxHealth*2)
|
||||
if(updating_stamina)
|
||||
update_stamina()
|
||||
|
||||
|
||||
/mob/living/carbon/setStaminaLoss(amount, updating_stamina = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
staminaloss = amount
|
||||
if(updating_stamina)
|
||||
update_stamina()
|
||||
@@ -3,19 +3,43 @@
|
||||
losebreath = 0
|
||||
..()
|
||||
|
||||
/mob/living/carbon/gib(no_brain, no_organs)
|
||||
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
|
||||
for(var/mob/M in src)
|
||||
if(M in stomach_contents)
|
||||
stomach_contents.Remove(M)
|
||||
M.loc = loc
|
||||
M.forceMove(loc)
|
||||
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
|
||||
..()
|
||||
|
||||
/mob/living/carbon/spill_organs(no_brain)
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
if(no_brain && istype(I, /obj/item/organ/brain))
|
||||
continue
|
||||
if(I)
|
||||
/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts)
|
||||
if(!no_bodyparts)
|
||||
if(no_organs)//so the organs don't get transfered inside the bodyparts we'll drop.
|
||||
for(var/X in internal_organs)
|
||||
qdel(X)
|
||||
else //we're going to drop all bodyparts except chest, so the only organs that needs spilling are those inside it.
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/O = X
|
||||
if(no_brain && istype(O, /obj/item/organ/brain))
|
||||
qdel(O) //so the brain isn't transfered to the head when the head drops.
|
||||
continue
|
||||
var/org_zone = check_zone(O.zone) //both groin and chest organs.
|
||||
if(org_zone == "chest")
|
||||
O.Remove(src)
|
||||
O.forceMove(get_turf(src))
|
||||
O.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
else
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
if(no_brain && istype(I, /obj/item/organ/brain))
|
||||
qdel(I)
|
||||
continue
|
||||
I.Remove(src)
|
||||
I.loc = get_turf(src)
|
||||
I.forceMove(get_turf(src))
|
||||
I.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
|
||||
|
||||
/mob/living/carbon/spread_bodyparts()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.drop_limb()
|
||||
BP.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
@@ -14,10 +14,6 @@
|
||||
//var/m_type = 1
|
||||
|
||||
switch(act)//Even carbon organisms want it alphabetically ordered..
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if ("airguitar")
|
||||
if (!src.restrained())
|
||||
@@ -32,10 +28,6 @@
|
||||
message = "<B>[src]</B> blinks rapidly."
|
||||
m_type = 1
|
||||
|
||||
if ("blush","blushes")
|
||||
message = "<B>[src]</B> blushes."
|
||||
m_type = 1
|
||||
|
||||
if ("bow","bows")
|
||||
if (!src.buckled)
|
||||
var/M = null
|
||||
@@ -82,15 +74,6 @@
|
||||
message = "<B>[src]</B> makes a strong noise."
|
||||
m_type = 2
|
||||
|
||||
if ("deathgasp","deathgasps")
|
||||
message = "<B>[src]</B> seizes up and falls limp, \his eyes dead and lifeless..."
|
||||
m_type = 1
|
||||
|
||||
if ("flap","flaps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings."
|
||||
m_type = 2
|
||||
|
||||
if ("gasp","gasps")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
@@ -116,10 +99,6 @@
|
||||
..()
|
||||
return
|
||||
|
||||
if ("nod","nods")
|
||||
message = "<B>[src]</B> nods."
|
||||
m_type = 1
|
||||
|
||||
if ("scream","screams")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
@@ -127,10 +106,6 @@
|
||||
message = "<B>[src]</B> makes a very loud noise."
|
||||
m_type = 2
|
||||
|
||||
if ("shake","shakes")
|
||||
message = "<B>[src]</B> shakes \his head."
|
||||
m_type = 1
|
||||
|
||||
if ("sneeze","sneezes")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
@@ -145,10 +120,6 @@
|
||||
message = "<B>[src]</B> sighs."
|
||||
m_type = 2
|
||||
|
||||
if ("sniff","sniffs")
|
||||
message = "<B>[src]</B> sniffs."
|
||||
m_type = 2
|
||||
|
||||
if ("snore","snores")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
@@ -188,7 +159,7 @@
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
if(!M.client || isnewplayer(M))
|
||||
continue //skip monkeys, leavers and new players
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
@@ -1,64 +1,90 @@
|
||||
/mob/living/carbon/examine(mob/user)
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_His = p_their(TRUE)
|
||||
var/t_his = p_their()
|
||||
var/t_him = p_them()
|
||||
var/t_has = p_have()
|
||||
var/t_is = p_are()
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
|
||||
|
||||
if (handcuffed)
|
||||
msg += "It is \icon[src.handcuffed] handcuffed!\n"
|
||||
msg += "<span class='warning'>[t_He] [t_is] \icon[src.handcuffed] handcuffed!</span>\n"
|
||||
if (head)
|
||||
msg += "It has \icon[src.head] \a [src.head] on its head. \n"
|
||||
msg += "[t_He] [t_is] wearing \icon[src.head] \a [src.head] on [t_his] head. \n"
|
||||
if (wear_mask)
|
||||
msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its face.\n"
|
||||
if (l_hand)
|
||||
msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n"
|
||||
if (r_hand)
|
||||
msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n"
|
||||
msg += "[t_He] [t_is] wearing \icon[src.wear_mask] \a [src.wear_mask] on [t_his] face.\n"
|
||||
if (wear_neck)
|
||||
msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
if (back)
|
||||
msg += "It has \icon[src.back] \a [src.back] on its back.\n"
|
||||
msg += "[t_He] [t_has] \icon[src.back] \a [src.back] on [t_his] back.\n"
|
||||
var/appears_dead = 0
|
||||
if (stat == DEAD)
|
||||
msg += "<span class='deadsay'>It is limp and unresponsive, with no signs of life.</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>"
|
||||
var/temp = getBruteLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "It has minor bruising.\n"
|
||||
else
|
||||
msg += "<B>It has severe bruising!</B>\n"
|
||||
appears_dead = 1
|
||||
if(getorgan(/obj/item/organ/brain))
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive, with no signs of life.</span>\n"
|
||||
else if(get_bodypart("head"))
|
||||
msg += "<span class='deadsay'>[t_He] appears that [t_his] brain is missing...</span>\n"
|
||||
|
||||
temp = getFireLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "It has minor burns.\n"
|
||||
else
|
||||
msg += "<B>It has severe burns!</B>\n"
|
||||
var/list/missing = get_missing_limbs()
|
||||
for(var/t in missing)
|
||||
if(t=="head")
|
||||
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
|
||||
continue
|
||||
msg += "<span class='warning'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
|
||||
|
||||
temp = getCloneLoss()
|
||||
if(temp)
|
||||
if(getCloneLoss() < 30)
|
||||
msg += "It is slightly deformed.\n"
|
||||
else
|
||||
msg += "<b>It is severely deformed.</b>\n"
|
||||
msg += "<span class='warning'>"
|
||||
var/temp = getBruteLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "[t_He] [t_has] minor bruising.\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] severe bruising!</B>\n"
|
||||
|
||||
if(getBrainLoss() > 60)
|
||||
msg += "It seems to be clumsy and unable to think.\n"
|
||||
temp = getFireLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "[t_He] [t_has] minor burns.\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] severe burns!</B>\n"
|
||||
|
||||
if(fire_stacks > 0)
|
||||
msg += "It's covered in something flammable.\n"
|
||||
if(fire_stacks < 0)
|
||||
msg += "It's soaked in water.\n"
|
||||
temp = getCloneLoss()
|
||||
if(temp)
|
||||
if(getCloneLoss() < 30)
|
||||
msg += "[t_He] [t_is] slightly deformed.\n"
|
||||
else
|
||||
msg += "<b>[t_He] [t_is] severely deformed.</b>\n"
|
||||
|
||||
if(pulledby && pulledby.grab_state)
|
||||
msg += "It's restrained by [pulledby]'s grip.\n"
|
||||
if(getBrainLoss() > 60)
|
||||
msg += "[t_He] seems to be clumsy and unable to think.\n"
|
||||
|
||||
if(fire_stacks > 0)
|
||||
msg += "[t_He] [t_is] covered in something flammable.\n"
|
||||
if(fire_stacks < 0)
|
||||
msg += "[t_He] [t_is] looks a little soaked.\n"
|
||||
|
||||
if(pulledby && pulledby.grab_state)
|
||||
msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n"
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
if(!appears_dead)
|
||||
if(stat == UNCONSCIOUS)
|
||||
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
|
||||
msg += "</span>"
|
||||
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
|
||||
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
if(digitalcamo)
|
||||
msg += "It is moving its body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
if(!getorgan(/obj/item/organ/brain))
|
||||
msg += "<span class='deadsay'>It appears that it's brain is missing...</span>\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
user << msg
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
|
||||
@@ -4,8 +4,11 @@
|
||||
/mob/living/carbon/human/dust_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-h"))
|
||||
|
||||
/mob/living/carbon/human/spawn_gibs()
|
||||
hgibs(loc, viruses, dna)
|
||||
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/human(loc, viruses, dna)
|
||||
else
|
||||
new /obj/effect/gibspawner/humanbodypartless(loc, viruses, dna)
|
||||
|
||||
/mob/living/carbon/human/spawn_dust()
|
||||
new /obj/effect/decal/remains/human(loc)
|
||||
@@ -33,29 +36,16 @@
|
||||
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
|
||||
. = ..(gibbed)
|
||||
if(mind && mind.devilinfo)
|
||||
spawn(0)
|
||||
mind.devilinfo.beginResurrectionCheck(src)
|
||||
addtimer(mind.devilinfo, "beginResurrectionCheck", 0, TIMER_NORMAL, src)
|
||||
|
||||
/mob/living/carbon/human/proc/makeSkeleton()
|
||||
status_flags |= DISFIGURED
|
||||
set_species(/datum/species/skeleton)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/ChangeToHusk()
|
||||
if(disabilities & HUSK)
|
||||
return
|
||||
disabilities |= HUSK
|
||||
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/ChangeToHusk()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_hair()
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/proc/Drain()
|
||||
ChangeToHusk()
|
||||
become_husk()
|
||||
disabilities |= NOCLONE
|
||||
blood_volume = 0
|
||||
return 1
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
var/muzzled = is_muzzled()
|
||||
//var/m_type = 1
|
||||
|
||||
for (var/obj/item/weapon/implant/I in src)
|
||||
if (I.implanted)
|
||||
I.trigger(act, src)
|
||||
for (var/obj/item/weapon/implant/I in implants)
|
||||
I.trigger(act, src)
|
||||
|
||||
var/miming=0
|
||||
if(mind)
|
||||
@@ -24,12 +23,12 @@
|
||||
switch(act) //Please keep this alphabetically ordered when adding or changing emotes.
|
||||
if ("aflap") //Any emote on human that uses miming must be left in, oh well.
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings ANGRILY!"
|
||||
message = "<B>[src]</B> flaps [p_their()] wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if ("choke","chokes")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> clutches \his throat desperately!"
|
||||
message = "<B>[src]</B> clutches [p_their()] throat desperately!"
|
||||
else
|
||||
..(act)
|
||||
|
||||
@@ -45,10 +44,11 @@
|
||||
m_type = 2
|
||||
|
||||
if ("collapse","collapses")
|
||||
Paralyse(2)
|
||||
adjustStaminaLoss(100) // Hampers abuse against simple mobs, but still leaves it a viable option.
|
||||
message = "<B>[src]</B> collapses!"
|
||||
m_type = 2
|
||||
if(status_flags & CANPARALYSE) //You can't collapse if you can't actually collapse.
|
||||
Paralyse(2)
|
||||
adjustStaminaLoss(100) // Hampers abuse against simple mobs, but still leaves it a viable option.
|
||||
message = "<B>[src]</B> collapses!"
|
||||
m_type = 2
|
||||
|
||||
if ("cough","coughs")
|
||||
if (miming)
|
||||
@@ -69,7 +69,7 @@
|
||||
message = "<B>[src]</B> cries."
|
||||
m_type = 2
|
||||
else
|
||||
message = "<B>[src]</B> makes a weak noise. \He frowns."
|
||||
message = "<B>[src]</B> makes a weak noise. [p_they(TRUE)] frown[p_s()]."
|
||||
m_type = 2
|
||||
|
||||
if ("custom")
|
||||
@@ -120,7 +120,7 @@
|
||||
if (M)
|
||||
message = "<B>[src]</B> gives daps to [M]."
|
||||
else
|
||||
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps \himself. Shameful."
|
||||
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps [p_them()]self. Shameful."
|
||||
|
||||
if ("eyebrow")
|
||||
message = "<B>[src]</B> raises an eyebrow."
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
if ("flap","flaps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings."
|
||||
message = "<B>[src]</B> flaps [p_their()] wings."
|
||||
m_type = 2
|
||||
if(((dna.features["wings"] != "None") && !("wings" in dna.species.mutant_bodyparts)))
|
||||
OpenWings()
|
||||
@@ -137,10 +137,10 @@
|
||||
if ("wings")
|
||||
if (!src.restrained())
|
||||
if(dna && dna.species &&((dna.features["wings"] != "None") && ("wings" in dna.species.mutant_bodyparts)))
|
||||
message = "<B>[src]</B> opens \his wings."
|
||||
message = "<B>[src]</B> opens [p_their()] wings."
|
||||
OpenWings()
|
||||
else if(dna && dna.species &&((dna.features["wings"] != "None") && ("wingsopen" in dna.species.mutant_bodyparts)))
|
||||
message = "<B>[src]</B> closes \his wings."
|
||||
message = "<B>[src]</B> closes [p_their()] wings."
|
||||
CloseWings()
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
@@ -177,7 +177,7 @@
|
||||
|
||||
if ("handshake")
|
||||
m_type = 1
|
||||
if (!src.restrained() && !src.r_hand)
|
||||
if (!src.restrained() && get_empty_held_indexes())
|
||||
var/mob/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(1, src))
|
||||
@@ -187,10 +187,10 @@
|
||||
if (M == src)
|
||||
M = null
|
||||
if (M)
|
||||
if (M.canmove && !M.r_hand && !M.restrained())
|
||||
if (M.canmove && M.get_empty_held_indexes() && !M.restrained())
|
||||
message = "<B>[src]</B> shakes hands with [M]."
|
||||
else
|
||||
message = "<B>[src]</B> holds out \his hand to [M]."
|
||||
message = "<B>[src]</B> holds out [p_their()] hand to [M]."
|
||||
|
||||
if ("hug","hugs")
|
||||
m_type = 1
|
||||
@@ -206,7 +206,7 @@
|
||||
if (M)
|
||||
message = "<B>[src]</B> hugs [M]."
|
||||
else
|
||||
message = "<B>[src]</B> hugs \himself."
|
||||
message = "<B>[src]</B> hugs [p_them()]self."
|
||||
|
||||
if ("me")
|
||||
if(silent)
|
||||
@@ -259,21 +259,6 @@
|
||||
message = "<B>[src]</B> raises a hand."
|
||||
m_type = 1
|
||||
|
||||
if ("roar","roars")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> appears to roar!"
|
||||
else
|
||||
if(!muzzled && has_dna())
|
||||
m_type = 2
|
||||
message = "<B>[src]</B> roars!"
|
||||
switch(dna.species.id)
|
||||
if("pred")
|
||||
playsound(get_turf(src), "predroar", 50, 0, 5)
|
||||
if("xeno")
|
||||
playsound(get_turf(src), "alienscreech", 50, 0, 5)
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("salute","salutes")
|
||||
if (!src.buckled)
|
||||
var/M = null
|
||||
@@ -294,23 +279,6 @@
|
||||
if (miming)
|
||||
message = "<B>[src]</B> acts out a scream!"
|
||||
else
|
||||
if(has_dna())
|
||||
switch(dna.species.id) //Visit sound.dm to see and add more 'soundin' options. (alienscreech, malescream, femscream, etc)
|
||||
if("xeno")
|
||||
playsound(get_turf(src), "alienscreech", 50, 0, 5)
|
||||
if("pred")
|
||||
playsound(get_turf(src), "predroar", 50, 0, 5)
|
||||
if("moth")
|
||||
playsound(get_turf(src), "mothscream", 50, 1, 5)
|
||||
if("lizard" || "drake")
|
||||
playsound(get_turf(src), "drakescream", 50, 0, 5)
|
||||
if("avian")
|
||||
playsound(get_turf(src), "birdscream", 50, 0, 5)
|
||||
else
|
||||
if(gender == MALE)
|
||||
playsound(get_turf(src), "malescream", 50, 0, 5)
|
||||
if(gender == FEMALE)
|
||||
playsound(get_turf(src), "femscream", 50, 0, 5)
|
||||
..(act)
|
||||
|
||||
if ("shiver","shivers")
|
||||
@@ -329,12 +297,16 @@
|
||||
|
||||
if ("signal","signals")
|
||||
if (!src.restrained())
|
||||
var/maximum_fingers = 10
|
||||
var/full_hands
|
||||
for(var/obj/item/I in held_items)
|
||||
full_hands++
|
||||
maximum_fingers = (held_items.len-full_hands)*5
|
||||
var/t1 = round(text2num(param))
|
||||
if (isnum(t1))
|
||||
if (t1 <= 5 && (!src.r_hand || !src.l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
else if (t1 <= 10 && (!src.r_hand && !src.l_hand))
|
||||
if (t1 <= maximum_fingers)
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
|
||||
m_type = 1
|
||||
|
||||
if ("sneeze","sneezes")
|
||||
@@ -365,22 +337,16 @@
|
||||
m_type = 2
|
||||
|
||||
if("wag","wags")
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || ((dna.features["mam_tail"] != "None") && !("mam_waggingtail" in dna.species.mutant_bodyparts)) || ((dna.features["tail_human"] != "None") && !("waggingtail_human" in dna.species.mutant_bodyparts))))
|
||||
message = "<B>[src]</B> wags \his tail."
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || ((dna.features["tail_human"] != "None") && !("waggingtail_human" in dna.species.mutant_bodyparts))))
|
||||
message = "<B>[src]</B> wags [p_their()] tail."
|
||||
startTailWag()
|
||||
else if(dna && dna.species && (("waggingtail_lizard" in dna.species.mutant_bodyparts) || ("mam_waggingtail" in dna.species.mutant_bodyparts) || ("waggingtail_human" in dna.species.mutant_bodyparts)))
|
||||
else if(dna && dna.species && (("waggingtail_lizard" in dna.species.mutant_bodyparts) || ("waggingtail_human" in dna.species.mutant_bodyparts)))
|
||||
endTailWag()
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
|
||||
if ("help") //This can stay at the bottom.
|
||||
if(has_dna(src))
|
||||
switch(dna.species.id)//Set lists of emotes for specific species. Not the best way to do this, but the easiest considering they'll share most emotes.
|
||||
if("pred")
|
||||
src << "Help for yautja emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, <b>roar</b>, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
|
||||
|
||||
else
|
||||
src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
|
||||
src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
|
||||
|
||||
else
|
||||
..(act)
|
||||
@@ -397,7 +363,7 @@
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
if(!M.client || isnewplayer(M))
|
||||
continue //skip monkeys, leavers and new players
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
@@ -422,9 +388,6 @@
|
||||
if("tail_human" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "tail_human"
|
||||
dna.species.mutant_bodyparts |= "waggingtail_human"
|
||||
if("mam_tail" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "mam_tail"
|
||||
dna.species.mutant_bodyparts |= "mam_waggingtail"
|
||||
update_body()
|
||||
|
||||
|
||||
@@ -439,9 +402,6 @@
|
||||
if("waggingtail_human" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "waggingtail_human"
|
||||
dna.species.mutant_bodyparts |= "tail_human"
|
||||
if("mam_waggingtail" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "mam_waggingtail"
|
||||
dna.species.mutant_bodyparts |= "mam_tail"
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/human/proc/OpenWings()
|
||||
@@ -459,10 +419,3 @@
|
||||
dna.species.mutant_bodyparts -= "wingsopen"
|
||||
dna.species.mutant_bodyparts |= "wings"
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/human/verb/set_flavor()
|
||||
set name = "Set Flavor Text"
|
||||
set desc = "Sets an extended description of your character's features."
|
||||
set category = "IC"
|
||||
|
||||
flavor_text = copytext(sanitize(input(usr, "Please enter your new flavor text.", "Flavor text", null) as text), 1)
|
||||
|
||||
@@ -1,36 +1,17 @@
|
||||
/mob/living/carbon/human/examine(mob/user)
|
||||
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_His = p_their(TRUE)
|
||||
var/t_his = p_their()
|
||||
var/t_him = p_them()
|
||||
var/t_has = p_have()
|
||||
var/t_is = p_are()
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is <EM>[src.name]</EM>!\n"
|
||||
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
|
||||
|
||||
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
|
||||
var/t_He = "It" //capitalised for use at the start of each line.
|
||||
var/t_his = "its"
|
||||
var/t_him = "it"
|
||||
var/t_has = "has"
|
||||
var/t_is = "is"
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is "
|
||||
|
||||
if( (slot_w_uniform in obscured) && skipface ) //big suits/masks/helmets make it hard to tell their gender
|
||||
t_He = "They"
|
||||
t_his = "their"
|
||||
t_him = "them"
|
||||
t_has = "have"
|
||||
t_is = "are"
|
||||
else
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
t_his = "his"
|
||||
t_him = "him"
|
||||
if(FEMALE)
|
||||
t_He = "She"
|
||||
t_his = "her"
|
||||
t_him = "her"
|
||||
|
||||
msg += "<EM>[src.name]</EM>!\n"
|
||||
|
||||
//uniform
|
||||
if(w_uniform && !(slot_w_uniform in obscured))
|
||||
//Ties
|
||||
@@ -73,19 +54,13 @@
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
|
||||
|
||||
//left hand
|
||||
if(l_hand && !(l_hand.flags&ABSTRACT))
|
||||
if(l_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in [t_his] left hand!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
|
||||
|
||||
//right hand
|
||||
if(r_hand && !(r_hand.flags&ABSTRACT))
|
||||
if(r_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in [t_his] right hand!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n"
|
||||
//Hands
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
//gloves
|
||||
if(gloves && !(slot_gloves in obscured))
|
||||
@@ -128,6 +103,9 @@
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
|
||||
|
||||
if (wear_neck && !(slot_neck in obscured))
|
||||
msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
|
||||
|
||||
//eyes
|
||||
if(glasses && !(slot_glasses in obscured))
|
||||
if(glasses.blood_DNA)
|
||||
@@ -141,16 +119,6 @@
|
||||
|
||||
//ID
|
||||
if(wear_id)
|
||||
/*var/id
|
||||
if(istype(wear_id, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = wear_id
|
||||
id = pda.owner
|
||||
else if(istype(wear_id, /obj/item/weapon/card/id)) //just in case something other than a PDA/ID card somehow gets in the ID slot :[
|
||||
var/obj/item/weapon/card/id/idcard = wear_id
|
||||
id = idcard.registered_name
|
||||
if(id && (id != real_name) && (get_dist(src, user) <= 1) && prob(10))
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
|
||||
else*/
|
||||
msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n"
|
||||
|
||||
//Jitters
|
||||
@@ -162,20 +130,14 @@
|
||||
if(100 to 200)
|
||||
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
|
||||
|
||||
if(gender_ambiguous) //someone fucked up a gender reassignment surgery
|
||||
if (gender == MALE)
|
||||
msg += "[t_He] has a strange feminine quality to [t_him].\n"
|
||||
else
|
||||
msg += "[t_He] has a strange masculine quality to [t_him].\n"
|
||||
|
||||
var/appears_dead = 0
|
||||
if(stat == DEAD || (status_flags & FAKEDEATH))
|
||||
appears_dead = 1
|
||||
if(getorgan(/obj/item/organ/brain))//Only perform these checks if there is no brain
|
||||
if(suiciding)
|
||||
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
msg += "<span class='warning'>[t_He] appear[p_s()] to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
if(hellbound)
|
||||
msg += "<span class='warning'>[t_his] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
|
||||
msg += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
|
||||
if(!key)
|
||||
var/foundghost = 0
|
||||
@@ -203,12 +165,27 @@
|
||||
for(var/obj/item/I in BP.embedded_objects)
|
||||
msg += "<B>[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [BP.name]!</B>\n"
|
||||
|
||||
//stores missing limbs
|
||||
var/l_limbs_missing = 0
|
||||
var/r_limbs_missing = 0
|
||||
for(var/t in missing)
|
||||
if(t=="head")
|
||||
msg += "<span class='deadsay'><B>[capitalize(t_his)] [parse_zone(t)] is missing!</B><span class='warning'>\n"
|
||||
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B><span class='warning'>\n"
|
||||
continue
|
||||
if(t == "l_arm" || t == "l_leg")
|
||||
l_limbs_missing++
|
||||
else if(t == "r_arm" || t == "r_leg")
|
||||
r_limbs_missing++
|
||||
|
||||
msg += "<B>[capitalize(t_his)] [parse_zone(t)] is missing!</B>\n"
|
||||
|
||||
if(l_limbs_missing >= 2 && r_limbs_missing == 0)
|
||||
msg += "[t_He] looks all right now.\n"
|
||||
else if(l_limbs_missing == 0 && r_limbs_missing >= 2)
|
||||
msg += "[t_He] really keeps to the left.\n"
|
||||
else if(l_limbs_missing >= 2 && r_limbs_missing >= 2)
|
||||
msg += "[t_He] doesn't seem all there.\n"
|
||||
|
||||
if(temp)
|
||||
if(temp < 30)
|
||||
msg += "[t_He] [t_has] minor bruising.\n"
|
||||
@@ -246,22 +223,7 @@
|
||||
msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] quite chubby.\n"
|
||||
/*
|
||||
if( (vore_womb_datum.has_people()||vore_stomach_datum.has_people()) && !(slot_w_uniform in obscured) )
|
||||
msg += "It seems [t_his] belly is shifting around slighty.\n"
|
||||
if( (vore_breast_datum.has_people()||vore_breast_datum.digestion_count) && !(slot_w_uniform in obscured) )
|
||||
msg += "It seems [t_his] breasts are heavy with milk.\n"
|
||||
if( !(slot_w_uniform in obscured) && (!w_uniform||!(w_uniform.body_parts_covered&GROIN)) )
|
||||
if(vore_cock_datum.has_people()||vore_cock_datum.digestion_count)
|
||||
msg += "It looks like [t_his] cock is full.\n"
|
||||
if(vore_balls_datum.has_people()||vore_balls_datum.digestion_count)
|
||||
msg += "It looks like [t_his] balls are full.\n"
|
||||
if(vore_tail_datum.has_people())
|
||||
msg += "[t_He] has a bulge in [t_his] tail."
|
||||
if(vore_tail_datum.transfer_factor)
|
||||
msg += " It moves slowly toward the base."
|
||||
msg += "\n"
|
||||
*/
|
||||
|
||||
if(blood_volume < BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
|
||||
@@ -276,10 +238,12 @@
|
||||
if(reagents.has_reagent("teslium"))
|
||||
msg += "[t_He] is emitting a gentle blue glow!\n"
|
||||
|
||||
if(stun_absorption)
|
||||
msg += "[t_He] is radiating with a soft yellow light!\n" //Used by Vanguard
|
||||
if(islist(stun_absorption))
|
||||
for(var/i in stun_absorption)
|
||||
if(stun_absorption[i]["end_time"] > world.time && stun_absorption[i]["examine_message"])
|
||||
msg += "[t_He] [t_is][stun_absorption[i]["examine_message"]]\n"
|
||||
|
||||
if(drunkenness && !skipface && stat != DEAD) //Drunkenness
|
||||
if(drunkenness && !skipface && !appears_dead) //Drunkenness
|
||||
switch(drunkenness)
|
||||
if(11 to 21)
|
||||
msg += "[t_He] [t_is] slightly flushed.\n"
|
||||
@@ -292,7 +256,7 @@
|
||||
if(61.01 to 91)
|
||||
msg += "[t_He] looks like a drunken mess.\n"
|
||||
if(91.01 to INFINITY)
|
||||
msg += "[t_He] is a shitfaced, slobbering wreck.\n"
|
||||
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
@@ -304,7 +268,13 @@
|
||||
|
||||
if(getorgan(/obj/item/organ/brain))
|
||||
if(istype(src,/mob/living/carbon/human/interactive))
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
|
||||
var/mob/living/carbon/human/interactive/auto = src
|
||||
if(auto.showexaminetext)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
|
||||
if(auto.debugexamine)
|
||||
var/dodebug = auto.doing2string(auto.doing)
|
||||
var/interestdebug = auto.interest2string(auto.interest)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be [interestdebug] and [dodebug].</span>\n"
|
||||
else if(!key)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.</span>\n"
|
||||
else if(!client)
|
||||
@@ -313,7 +283,7 @@
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
|
||||
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/cyberimp/eyes/hud)
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH)
|
||||
@@ -325,18 +295,18 @@
|
||||
msg += "<a href='?src=\ref[src];hud=1;photo_front=1'>\[Front photo\]</a> "
|
||||
msg += "<a href='?src=\ref[src];hud=1;photo_side=1'>\[Side photo\]</a><br>"
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
var/implant_detect
|
||||
var/cyberimp_detect
|
||||
for(var/obj/item/organ/cyberimp/CI in internal_organs)
|
||||
if(CI.status == ORGAN_ROBOTIC)
|
||||
implant_detect += "[name] is modified with a [CI.name].<br>"
|
||||
if(implant_detect)
|
||||
cyberimp_detect += "[name] is modified with a [CI.name].<br>"
|
||||
if(cyberimp_detect)
|
||||
msg += "Detected cybernetic modifications:<br>"
|
||||
msg += implant_detect
|
||||
msg += cyberimp_detect
|
||||
if(R)
|
||||
var/health = R.fields["p_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health]\]</a>"
|
||||
health = R.fields["m_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health]\]</a><br>"
|
||||
var/health_r = R.fields["p_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health_r]\]</a>"
|
||||
health_r = R.fields["m_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health_r]\]</a><br>"
|
||||
R = find_record("name", perpname, data_core.medical)
|
||||
if(R)
|
||||
msg += "<a href='?src=\ref[src];hud=m;evaluation=1'>\[Medical evaluation\]</a><br>"
|
||||
@@ -356,10 +326,6 @@
|
||||
msg += "<a href='?src=\ref[src];hud=s;add_crime=1'>\[Add crime\]</a> "
|
||||
msg += "<a href='?src=\ref[src];hud=s;view_comment=1'>\[View comment log\]</a> "
|
||||
msg += "<a href='?src=\ref[src];hud=s;add_comment=1'>\[Add comment\]</a>\n"
|
||||
|
||||
if(print_flavor_text() && get_visible_name() != "Unknown")//Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
|
||||
msg += "[print_flavor_text()]\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
real_name = "Unknown"
|
||||
voice_name = "Unknown"
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "caucasian1_m_s"
|
||||
icon_state = "caucasian_m_s"
|
||||
|
||||
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
//initialize limbs first
|
||||
bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/O = X
|
||||
O.owner = src
|
||||
create_bodyparts()
|
||||
|
||||
//initialize dna. for spawned humans; overwritten by other code
|
||||
create_dna(src)
|
||||
@@ -33,21 +29,7 @@
|
||||
set_species(dna.species.type)
|
||||
|
||||
//initialise organs
|
||||
if(!(NOHUNGER in dna.species.specflags))
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
|
||||
if(!(NOBREATH in dna.species.specflags))
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
|
||||
if(!(NOBLOOD in dna.species.specflags))
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
|
||||
//Note: Additional organs are generated/replaced on the dna.species level
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.Insert(src)
|
||||
create_internal_organs()
|
||||
|
||||
martial_art = default_martial_art
|
||||
|
||||
@@ -55,6 +37,19 @@
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/create_internal_organs()
|
||||
if(!(NOHUNGER in dna.species.species_traits))
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
if(!(NOBREATH in dna.species.species_traits))
|
||||
if(dna.species.mutantlungs)
|
||||
internal_organs += new dna.species.mutantlungs()
|
||||
else
|
||||
internal_organs += new /obj/item/organ/lungs()
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/OpenCraftingMenu()
|
||||
handcrafting.ui_interact(src)
|
||||
|
||||
@@ -81,6 +76,11 @@
|
||||
stat("Internal Atmosphere Info", internal.name)
|
||||
stat("Tank Pressure", internal.air_contents.return_pressure())
|
||||
stat("Distribution Pressure", internal.distribute_pressure)
|
||||
|
||||
var/mob/living/simple_animal/borer/B = has_brain_worms()
|
||||
if(B && B.controlling)
|
||||
stat("Chemicals", B.chemicals)
|
||||
|
||||
if(mind)
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
||||
@@ -116,94 +116,17 @@
|
||||
stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]")
|
||||
|
||||
|
||||
/mob/living/carbon/human/ex_act(severity, ex_target)
|
||||
var/b_loss = null
|
||||
var/f_loss = null
|
||||
var/bomb_armor = getarmor(null, "bomb")
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
b_loss += 500
|
||||
if (prob(bomb_armor))
|
||||
shred_clothing(1,150)
|
||||
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
|
||||
throw_at(target, 200, 4)
|
||||
else
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
b_loss += 60
|
||||
|
||||
f_loss += 60
|
||||
if (prob(bomb_armor))
|
||||
b_loss = b_loss/1.5
|
||||
f_loss = f_loss/1.5
|
||||
shred_clothing(1,25)
|
||||
else
|
||||
shred_clothing(1,50)
|
||||
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(30, 120)
|
||||
if (prob(70))
|
||||
Paralyse(10)
|
||||
|
||||
if(3)
|
||||
b_loss += 30
|
||||
if (prob(bomb_armor))
|
||||
b_loss = b_loss/2
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(15,60)
|
||||
if (prob(50))
|
||||
Paralyse(10)
|
||||
|
||||
take_overall_damage(b_loss,f_loss)
|
||||
//attempt to dismember bodyparts
|
||||
if(severity <= 2 || !bomb_armor)
|
||||
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest")
|
||||
BP.brute_dam = BP.max_damage
|
||||
BP.dismember()
|
||||
max_limb_loss--
|
||||
if(!max_limb_loss)
|
||||
break
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/blob_act(obj/effect/blob/B)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
show_message("<span class='userdanger'>The blob attacks you!</span>")
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/bullet_act()
|
||||
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(!prob(martial_art.deflection_chance))
|
||||
return ..()
|
||||
if(!src.lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
src.visible_message("<span class='danger'>[src] deflects the projectile; they can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
|
||||
return 0
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/attack_ui(slot)
|
||||
if(!get_bodypart(hand ? "l_arm" : "r_arm"))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/list/dat = list()
|
||||
|
||||
var/dat = {"<table>
|
||||
<tr><td><B>Left Hand:</B></td><td><A href='?src=\ref[src];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td><B>Right Hand:</B></td><td><A href='?src=\ref[src];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
dat += "<table>"
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(back, /obj/item/weapon/tank))
|
||||
@@ -218,6 +141,11 @@
|
||||
else
|
||||
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=\ref[src];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_neck in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Neck:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=\ref[src];item=[slot_neck]'>[(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_glasses in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
@@ -277,7 +205,7 @@
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 510)
|
||||
popup.set_content(dat)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
// called when something steps onto a human
|
||||
@@ -289,35 +217,6 @@
|
||||
|
||||
spreadFire(AM)
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0)
|
||||
if(tesla_shock)
|
||||
var/total_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(G.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.5
|
||||
if(wear_suit)
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
if(S.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.95
|
||||
siemens_coeff = total_coeff
|
||||
else if(!safety)
|
||||
var/gloves_siemens_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
gloves_siemens_coeff = G.siemens_coefficient
|
||||
siemens_coeff = gloves_siemens_coeff
|
||||
if(heart_attack)
|
||||
if(shock_damage * siemens_coeff >= 1 && prob(25))
|
||||
heart_attack = 0
|
||||
if(stat == CONSCIOUS)
|
||||
src << "<span class='notice'>You feel your heart beating again!</span>"
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
@@ -333,8 +232,8 @@
|
||||
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
|
||||
return
|
||||
L.embedded_objects -= I
|
||||
L.take_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
|
||||
I.loc = get_turf(src)
|
||||
L.receive_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
|
||||
I.forceMove(get_turf(src))
|
||||
usr.put_in_hands(I)
|
||||
usr.emote("scream")
|
||||
usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","<span class='notice'>You successfully remove [I] from your [L.name].</span>")
|
||||
@@ -352,14 +251,14 @@
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store)
|
||||
var/obj/item/pocket_item = (pocket_id == slot_r_store ? r_store : l_store)
|
||||
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
|
||||
var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty
|
||||
|
||||
var/delay_denominator = 1
|
||||
if(pocket_item && !(pocket_item.flags&ABSTRACT))
|
||||
if(pocket_item.flags & NODROP)
|
||||
usr << "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>"
|
||||
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
|
||||
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1) && !(place_item.flags&ABSTRACT))
|
||||
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags&ABSTRACT))
|
||||
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
|
||||
delay_denominator = 4
|
||||
else
|
||||
@@ -382,13 +281,11 @@
|
||||
src << "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>"
|
||||
|
||||
..()
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
///////HUDs///////
|
||||
if(href_list["hud"])
|
||||
if(istype(usr, /mob/living/carbon/human))
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/perpname = get_face_name(get_id_name(""))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud))
|
||||
@@ -410,24 +307,24 @@
|
||||
if(href_list["hud"] == "m")
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
|
||||
if(href_list["p_stat"])
|
||||
var/health = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
|
||||
var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health))
|
||||
return
|
||||
if(health && health != "Cancel")
|
||||
R.fields["p_stat"] = health
|
||||
if(health_status && health_status != "Cancel")
|
||||
R.fields["p_stat"] = health_status
|
||||
return
|
||||
if(href_list["m_stat"])
|
||||
var/health = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
|
||||
var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health))
|
||||
return
|
||||
if(health && health != "Cancel")
|
||||
R.fields["m_stat"] = health
|
||||
if(health_status && health_status != "Cancel")
|
||||
R.fields["m_stat"] = health_status
|
||||
return
|
||||
if(href_list["evaluation"])
|
||||
if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20)
|
||||
@@ -588,7 +485,7 @@
|
||||
var/counter = 1
|
||||
while(R.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1,)
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1)
|
||||
usr << "<span class='notice'>Successfully added comment.</span>"
|
||||
return
|
||||
usr << "<span class='warning'>Unable to locate a data core entry for this person.</span>"
|
||||
@@ -600,7 +497,7 @@
|
||||
. = 1 // Default to returning true.
|
||||
if(user && !target_zone)
|
||||
target_zone = user.zone_selected
|
||||
if(dna && (PIERCEIMMUNE in dna.species.specflags))
|
||||
if(dna && (PIERCEIMMUNE in dna.species.species_traits))
|
||||
. = 0
|
||||
// If targeting the head, see if the head item is thin enough.
|
||||
// If targeting anything else, see if the wear suit is thin enough.
|
||||
@@ -612,7 +509,7 @@
|
||||
. = 0
|
||||
if(!. && error_msg && user)
|
||||
// Might need re-wording.
|
||||
user << "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on their head" : "on their body"].</span>"
|
||||
user << "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on [p_their()] head" : "on [p_their()] body"].</span>"
|
||||
|
||||
/mob/living/carbon/human/proc/check_obscured_slots()
|
||||
var/list/obscured = list()
|
||||
@@ -637,7 +534,7 @@
|
||||
if(wear_mask.flags_inv & HIDEEYES)
|
||||
obscured |= slot_glasses
|
||||
|
||||
if(obscured.len > 0)
|
||||
if(obscured.len)
|
||||
return obscured
|
||||
else
|
||||
return null
|
||||
@@ -653,7 +550,7 @@
|
||||
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/redtag))
|
||||
threatcount += 4
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
|
||||
threatcount += 4
|
||||
if(istype(belt, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
threatcount += 2
|
||||
@@ -661,7 +558,7 @@
|
||||
if(lasercolor == "r")
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/bluetag))
|
||||
threatcount += 4
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
|
||||
threatcount += 4
|
||||
if(istype(belt, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
threatcount += 2
|
||||
@@ -676,10 +573,9 @@
|
||||
//Check for weapons
|
||||
if(judgebot.weaponscheck)
|
||||
if(!idcard || !(access_weapons in idcard.access))
|
||||
if(judgebot.check_for_weapons(l_hand))
|
||||
threatcount += 4
|
||||
if(judgebot.check_for_weapons(r_hand))
|
||||
threatcount += 4
|
||||
for(var/obj/item/I in held_items)
|
||||
if(judgebot.check_for_weapons(I))
|
||||
threatcount += 4
|
||||
if(judgebot.check_for_weapons(belt))
|
||||
threatcount += 2
|
||||
|
||||
@@ -697,23 +593,22 @@
|
||||
threatcount += 2
|
||||
|
||||
//Check for dresscode violations
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/syndicate) || istype(head, /obj/item/clothing/head/culthood))
|
||||
threatcount += 5
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
|
||||
threatcount += 2
|
||||
|
||||
//Check for nonhuman scum
|
||||
if(dna && dna.species.id && dna.species.id != "human")
|
||||
threatcount += 0
|
||||
threatcount += 1
|
||||
|
||||
//Loyalty implants imply trustworthyness
|
||||
if(isloyal(src))
|
||||
//mindshield implants imply trustworthyness
|
||||
if(isloyal())
|
||||
threatcount -= 1
|
||||
|
||||
//Agent cards lower threatlevel, but only just enough to avoid dresscode violations.
|
||||
//Agent cards lower threatlevel.
|
||||
if(istype(idcard, /obj/item/weapon/card/id/syndicate))
|
||||
threatcount -= 2
|
||||
threatcount -= 5
|
||||
|
||||
return threatcount
|
||||
return threatcount
|
||||
|
||||
|
||||
//Used for new human mobs created by cloning/goleming/podding
|
||||
@@ -727,21 +622,9 @@
|
||||
update_body()
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/singularity_act()
|
||||
var/gain = 20
|
||||
if(mind)
|
||||
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
|
||||
gain = 100
|
||||
if(mind.assigned_role == "Clown")
|
||||
gain = rand(-300, 300)
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/carbon/human/singularity_pull(S, current_size)
|
||||
if(current_size >= STAGE_THREE)
|
||||
var/list/handlist = list(l_hand, r_hand)
|
||||
for(var/obj/item/hand in handlist)
|
||||
for(var/obj/item/hand in held_items)
|
||||
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
|
||||
step_towards(hand, src)
|
||||
src << "<span class='warning'>\The [S] pulls \the [hand] from your grip!</span>"
|
||||
@@ -750,71 +633,6 @@
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/help_shake_act(mob/living/carbon/M)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(health >= 0)
|
||||
if(src == M)
|
||||
visible_message( \
|
||||
"[src] examines \himself.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/LB = X
|
||||
missing -= LB.body_zone
|
||||
var/status = ""
|
||||
var/brutedamage = LB.brute_dam
|
||||
var/burndamage = LB.burn_dam
|
||||
if(hallucination)
|
||||
if(prob(30))
|
||||
brutedamage += rand(30,40)
|
||||
if(prob(30))
|
||||
burndamage += rand(30,40)
|
||||
|
||||
if(brutedamage > 0)
|
||||
status = "bruised"
|
||||
if(brutedamage > 20)
|
||||
status = "battered"
|
||||
if(brutedamage > 40)
|
||||
status = "mangled"
|
||||
if(brutedamage > 0 && burndamage > 0)
|
||||
status += " and "
|
||||
if(burndamage > 40)
|
||||
status += "peeling away"
|
||||
|
||||
else if(burndamage > 10)
|
||||
status += "blistered"
|
||||
else if(burndamage > 0)
|
||||
status += "numb"
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]."
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
src << "\t <a href='byond://?src=\ref[src];embedded_object=\ref[I];embedded_limb=\ref[LB]'>\red There is \a [I] embedded in your [LB.name]!</a>"
|
||||
|
||||
for(var/t in missing)
|
||||
src << "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>"
|
||||
|
||||
if(bleed_rate)
|
||||
src << "<span class='danger'>You are bleeding!</span>"
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
src << "<span class='info'>You're completely exhausted.</span>"
|
||||
else
|
||||
src << "<span class='info'>You feel fatigued.</span>"
|
||||
else
|
||||
if(wear_suit)
|
||||
wear_suit.add_fingerprint(M)
|
||||
else if(w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
|
||||
CHECK_DNA_AND_SPECIES(C)
|
||||
|
||||
@@ -825,7 +643,7 @@
|
||||
src << "<span class='warning'>Remove your mask first!</span>"
|
||||
return 0
|
||||
if(C.is_mouth_covered())
|
||||
src << "<span class='warning'>Remove their mask first!</span>"
|
||||
src << "<span class='warning'>Remove [p_their()] mask first!</span>"
|
||||
return 0
|
||||
|
||||
if(C.cpr_time < world.time + 30)
|
||||
@@ -835,10 +653,10 @@
|
||||
src << "<span class='warning'>You fail to perform CPR on [C]!</span>"
|
||||
return 0
|
||||
|
||||
var/they_breathe = (!(NOBREATH in C.dna.species.specflags))
|
||||
var/they_breathe = (!(NOBREATH in C.dna.species.species_traits))
|
||||
var/they_lung = C.getorganslot("lungs")
|
||||
|
||||
if(C.health > config.health_threshold_crit)
|
||||
if(C.health > HEALTH_THRESHOLD_CRIT)
|
||||
return
|
||||
|
||||
src.visible_message("[src] performs CPR on [C.name]!", "<span class='notice'>You perform CPR on [C.name].</span>")
|
||||
@@ -907,10 +725,11 @@
|
||||
/mob/living/carbon/human/proc/electrocution_animation(anim_duration)
|
||||
//Handle mutant parts if possible
|
||||
if(dna && dna.species)
|
||||
add_overlay("electrocuted_base")
|
||||
spawn(anim_duration)
|
||||
if(src)
|
||||
overlays -= "electrocuted_base"
|
||||
add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY)
|
||||
var/static/image/electrocution_skeleton_anim = image(icon = icon, icon_state = "electrocuted_base")
|
||||
electrocution_skeleton_anim.appearance_flags = RESET_COLOR
|
||||
add_overlay(electrocution_skeleton_anim)
|
||||
addtimer(src, "end_electrocution_animation", anim_duration, TIMER_NORMAL, electrocution_skeleton_anim)
|
||||
|
||||
else //or just do a generic animation
|
||||
var/list/viewing = list()
|
||||
@@ -919,6 +738,10 @@
|
||||
viewing += M.client
|
||||
flick_overlay(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), viewing, anim_duration)
|
||||
|
||||
/mob/living/carbon/human/proc/end_electrocution_animation(image/I)
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
|
||||
overlays -= I
|
||||
|
||||
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0)
|
||||
if(incapacitated() || lying )
|
||||
return
|
||||
@@ -1004,16 +827,15 @@
|
||||
hud_used.healthdoll.icon_state = "healthdoll_DEAD"
|
||||
|
||||
/mob/living/carbon/human/fully_heal(admin_revive = 0)
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
|
||||
if(!(NOBREATH in dna.species.specflags) && !getorganslot("lungs"))
|
||||
if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs"))
|
||||
var/obj/item/organ/lungs/L = new()
|
||||
L.Insert(src)
|
||||
|
||||
if(!(NOBLOOD in dna.species.specflags) && !getorganslot("heart"))
|
||||
if(!(NOBLOOD in dna.species.species_traits) && !getorganslot("heart"))
|
||||
var/obj/item/organ/heart/H = new()
|
||||
H.Insert(src)
|
||||
|
||||
@@ -1063,12 +885,7 @@
|
||||
O = new /datum/objective/sintouched/pride
|
||||
ticker.mode.sintouched += src.mind
|
||||
src.mind.objectives += O
|
||||
var/obj_count = 1
|
||||
src << "<span class='notice'>Your current objectives:</span>"
|
||||
for(O in src.mind.objectives)
|
||||
var/datum/objective/objective = O
|
||||
src << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
||||
obj_count++
|
||||
src.mind.announce_objectives()
|
||||
|
||||
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
. = ..()
|
||||
@@ -1078,6 +895,36 @@
|
||||
/mob/living/carbon/human/is_literate()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/can_hold_items()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
|
||||
override = dna.species.override_float
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
|
||||
if(blood && (NOBLOOD in dna.species.species_traits))
|
||||
if(message)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
||||
if(stun)
|
||||
Weaken(10)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/Bump(atom/A)
|
||||
..()
|
||||
var/crashdir = get_dir(src, A)
|
||||
var/obj/item/device/flightpack/FP = get_flightpack()
|
||||
if(FP)
|
||||
FP.flight_impact(A, crashdir)
|
||||
|
||||
/mob/living/carbon/human/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
.["Make monkey"] = "?_src_=vars;makemonkey=\ref[src]"
|
||||
.["Set Species"] = "?_src_=vars;setspecies=\ref[src]"
|
||||
.["Make cyborg"] = "?_src_=vars;makerobot=\ref[src]"
|
||||
.["Make alien"] = "?_src_=vars;makealien=\ref[src]"
|
||||
.["Make slime"] = "?_src_=vars;makeslime=\ref[src]"
|
||||
.["Toggle Purrbation"] = "?_src_=vars;purrbation=\ref[src]"
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(check_shields(0, M.name))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return 0
|
||||
|
||||
if(..())
|
||||
if(M.a_intent == "harm")
|
||||
if (w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has lunged at [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, "melee","","",10)
|
||||
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
if (prob(30))
|
||||
visible_message("<span class='danger'>[M] has wounded [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [src]!</span>")
|
||||
apply_effect(4, WEAKEN, armor_block)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
|
||||
if(M.a_intent == "disarm")
|
||||
var/randn = rand(1, 100)
|
||||
if (randn <= 80)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Weaken(5)
|
||||
add_logs(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
else
|
||||
if (randn <= 99)
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
drop_item()
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tried to disarm [src]!</span>")
|
||||
return
|
||||
@@ -1,14 +0,0 @@
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
visible_message("<span class='danger'>[user] has [hulk_verb]ed [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hulk_verb]ed [src]!</span>")
|
||||
adjustBruteLoss(15)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //to allow surgery to return properly.
|
||||
return
|
||||
dna.species.spec_attack_hand(M, src)
|
||||
@@ -1,15 +0,0 @@
|
||||
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
|
||||
if(M.a_intent == "help")
|
||||
..() //shaking
|
||||
return 0
|
||||
|
||||
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
|
||||
if(..()) //successful monkey bite, this handles disease contraction.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
updatehealth()
|
||||
return 1
|
||||
@@ -1,161 +0,0 @@
|
||||
//Updates the mob's health from bodyparts and mob damage variables
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/X in bodyparts) //hardcoded to streamline things a bit
|
||||
var/obj/item/bodypart/BP = X
|
||||
total_brute += BP.brute_dam
|
||||
total_burn += BP.burn_dam
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD )
|
||||
ChangeToHusk()
|
||||
if(on_fire)
|
||||
shred_clothing()
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/human/getBruteLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.brute_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/human/getFireLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/human/adjustBruteLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0)
|
||||
else
|
||||
heal_overall_damage(-amount, 0)
|
||||
|
||||
/mob/living/carbon/human/adjustFireLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount)
|
||||
else
|
||||
heal_overall_damage(0, -amount)
|
||||
|
||||
/mob/living/carbon/human/proc/hat_fall_prob()
|
||||
var/multiplier = 1
|
||||
var/obj/item/clothing/head/H = head
|
||||
var/loose = 40
|
||||
if(stat || (status_flags & FAKEDEATH))
|
||||
multiplier = 2
|
||||
if(H.flags_cover & (HEADCOVERSEYES | HEADCOVERSMOUTH) || H.flags_inv & (HIDEEYES | HIDEFACE))
|
||||
loose = 0
|
||||
return loose * multiplier
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
/mob/living/carbon/human/proc/get_damaged_bodyparts(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Returns a list of damageable bodyparts
|
||||
/mob/living/carbon/human/proc/get_damageable_bodyparts()
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Heals ONE external organ, organ gets randomly selected from damaged ones.
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/heal_organ_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.heal_damage(brute,burn,0))
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
//Damages ONE external organ, organ gets randomly selected from damagable ones.
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/take_organ_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.take_damage(brute,burn))
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
|
||||
//Heal MANY bodyparts, in random order
|
||||
/mob/living/carbon/human/heal_overall_damage(brute, burn, updating_health=1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
update |= picked.heal_damage(brute,burn,0)
|
||||
|
||||
brute -= (brute_was-picked.brute_dam)
|
||||
burn -= (burn_was-picked.burn_dam)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/carbon/human/take_overall_damage(brute, burn)
|
||||
if(status_flags & GODMODE)
|
||||
return //godmode
|
||||
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
var/brute_per_part = brute/parts.len
|
||||
var/burn_per_part = burn/parts.len
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
|
||||
update |= picked.take_damage(brute_per_part,burn_per_part)
|
||||
|
||||
brute -= (picked.brute_dam - brute_was)
|
||||
burn -= (picked.burn_dam - burn_was)
|
||||
|
||||
parts -= picked
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
|
||||
@@ -17,8 +17,8 @@
|
||||
return (armorval/max(organnum, 1))
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, type)
|
||||
if(!type)
|
||||
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type)
|
||||
if(!d_type)
|
||||
return 0
|
||||
var/protection = 0
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
@@ -28,13 +28,44 @@
|
||||
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[d_type]
|
||||
return protection
|
||||
|
||||
/mob/living/carbon/human/on_hit(proj_type)
|
||||
dna.species.on_hit(proj_type, src)
|
||||
///checkeyeprot()
|
||||
///Returns a number between -1 to 2
|
||||
/mob/living/carbon/human/get_eye_protection()
|
||||
var/number = ..()
|
||||
if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head
|
||||
var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item
|
||||
number += HFP.flash_protect
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
|
||||
var/obj/item/clothing/glasses/GFP = src.glasses
|
||||
number += GFP.flash_protect
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/human/get_ear_protection()
|
||||
if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/on_hit(obj/item/projectile/P)
|
||||
dna.species.on_hit(P, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone)
|
||||
var/spec_return = dna.species.bullet_act(P, src)
|
||||
if(spec_return)
|
||||
return spec_return
|
||||
|
||||
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(prob(martial_art.deflection_chance))
|
||||
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
|
||||
return 0
|
||||
|
||||
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
if(check_reflect(def_zone)) // Checks if you've passed a reflection% check
|
||||
@@ -60,31 +91,26 @@
|
||||
if(check_shields(P.damage, "the [P.name]", P, PROJECTILE_ATTACK, P.armour_penetration))
|
||||
P.on_hit(src, 100, def_zone)
|
||||
return 2
|
||||
|
||||
return (..(P , def_zone))
|
||||
|
||||
/mob/living/carbon/human/proc/check_reflect(def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object
|
||||
if(wear_suit)
|
||||
if(wear_suit.IsReflect(def_zone) == 1)
|
||||
return 1
|
||||
if(l_hand)
|
||||
if(l_hand.IsReflect(def_zone) == 1)
|
||||
return 1
|
||||
if(r_hand)
|
||||
if(r_hand.IsReflect(def_zone) == 1)
|
||||
for(var/obj/item/I in held_items)
|
||||
if(I.IsReflect(def_zone) == 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", atom/movable/AM, attack_type = MELEE_ATTACK, armour_penetration = 0)
|
||||
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
|
||||
if(l_hand.hit_reaction(src, 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
|
||||
if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
|
||||
return 1
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!istype(I, /obj/item/clothing))
|
||||
var/final_block_chance = I.block_chance - (Clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
if(I.hit_reaction(src, 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
|
||||
if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
|
||||
@@ -95,252 +121,17 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user)
|
||||
if(!I || !user)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected))
|
||||
var/target_area = parse_zone(check_zone(user.zone_selected))
|
||||
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
|
||||
feedback_add_details("zone_targeted","[target_area]")
|
||||
|
||||
// the attacked_by code varies among species
|
||||
return dna.species.spec_attacked_by(I, user, affecting, a_intent, target_area, src)
|
||||
|
||||
/mob/living/carbon/human/emp_act(severity)
|
||||
var/informed = 0
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
if(L.status == ORGAN_ROBOTIC)
|
||||
if(!informed)
|
||||
src << "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>"
|
||||
informed = 1
|
||||
switch(severity)
|
||||
if(1)
|
||||
L.take_damage(0,10)
|
||||
src.Stun(10)
|
||||
if(2)
|
||||
L.take_damage(0,5)
|
||||
src.Stun(5)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/acid_act(acidpwr, toxpwr, acid_volume)
|
||||
var/list/damaged = list()
|
||||
var/list/inventory_items_to_kill = list()
|
||||
var/acidity = min(acidpwr*acid_volume/200, toxpwr)
|
||||
var/acid_volume_left = acid_volume
|
||||
var/acid_decay = 100/acidpwr // how much volume we lose per item we try to melt. 5 for fluoro, 10 for sulphuric
|
||||
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
if(!head_clothes.unacidable)
|
||||
head_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0) //We remove some of the acid volume.
|
||||
update_inv_glasses()
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
else
|
||||
src << "<span class='notice'>Your [head_clothes.name] protects your head and face from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("head")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(ears)
|
||||
inventory_items_to_kill += ears
|
||||
|
||||
//CHEST//
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
if(!chest_clothes.unacidable)
|
||||
chest_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [chest_clothes.name] protects your body from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("chest")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(wear_id)
|
||||
inventory_items_to_kill += wear_id
|
||||
if(r_store)
|
||||
inventory_items_to_kill += r_store
|
||||
if(l_store)
|
||||
inventory_items_to_kill += l_store
|
||||
if(s_store)
|
||||
inventory_items_to_kill += s_store
|
||||
|
||||
|
||||
//ARMS & HANDS//
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && (w_uniform.body_parts_covered & HANDS) || w_uniform && (w_uniform.body_parts_covered & ARMS))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && (wear_suit.body_parts_covered & HANDS) || wear_suit && (wear_suit.body_parts_covered & ARMS))
|
||||
arm_clothes = wear_suit
|
||||
if(arm_clothes)
|
||||
if(!arm_clothes.unacidable)
|
||||
arm_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_gloves()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [arm_clothes.name] protects your arms and hands from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//LEGS & FEET//
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && (w_uniform.body_parts_covered & FEET) || w_uniform && (w_uniform.body_parts_covered & LEGS))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && (wear_suit.body_parts_covered & FEET) || wear_suit && (wear_suit.body_parts_covered & LEGS))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
if(!leg_clothes.unacidable)
|
||||
leg_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_shoes()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [leg_clothes.name] protects your legs and feet from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//DAMAGE//
|
||||
for(var/obj/item/bodypart/affecting in damaged)
|
||||
affecting.take_damage(acidity, 2*acidity)
|
||||
|
||||
if(affecting.name == "head")
|
||||
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
|
||||
affecting.take_damage(acidity, 2*acidity)
|
||||
emote("scream")
|
||||
facial_hair_style = "Shaved"
|
||||
hair_style = "Bald"
|
||||
update_hair()
|
||||
status_flags |= DISFIGURED
|
||||
|
||||
update_damage_overlays()
|
||||
|
||||
//MELTING INVENTORY ITEMS//
|
||||
//these items are all outside of armour visually, so melt regardless.
|
||||
if(back)
|
||||
inventory_items_to_kill += back
|
||||
if(belt)
|
||||
inventory_items_to_kill += belt
|
||||
if(r_hand)
|
||||
inventory_items_to_kill += r_hand
|
||||
if(l_hand)
|
||||
inventory_items_to_kill += l_hand
|
||||
|
||||
for(var/obj/item/I in inventory_items_to_kill)
|
||||
I.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
|
||||
return 0
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
var/armor = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, M.melee_damage_type, affecting, armor, "", "", M.armour_penetration)
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(check_shields(damage, "the [L.name]"))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
|
||||
if(check_shields(damage, "the [M.name]"))
|
||||
return 0
|
||||
|
||||
var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
|
||||
if(M.occupant.a_intent == "harm")
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head"))
|
||||
if(temp)
|
||||
var/update = 0
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 20)
|
||||
Paralyse(1)
|
||||
update |= temp.take_damage(rand(M.force/2, M.force), 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if("fire")
|
||||
update |= temp.take_damage(0, rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
if("tox")
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>")
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
|
||||
else
|
||||
..()
|
||||
/mob/living/carbon/human/proc/check_block()
|
||||
if(martial_art && martial_art.block_chance \
|
||||
&& prob(martial_art.block_chance) && in_throw_mode \
|
||||
&& !stat && !weakened && !stunned)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
var/spec_return = dna.species.spec_hitby(AM, src)
|
||||
if(spec_return)
|
||||
return spec_return
|
||||
var/obj/item/I
|
||||
var/throwpower = 30
|
||||
if(istype(AM, /obj/item))
|
||||
@@ -355,13 +146,13 @@
|
||||
else if(I)
|
||||
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
|
||||
if(can_embed(I))
|
||||
if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.specflags)))
|
||||
if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.species_traits)))
|
||||
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
|
||||
var/obj/item/bodypart/L = pick(bodyparts)
|
||||
L.embedded_objects |= I
|
||||
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
|
||||
I.loc = src
|
||||
L.take_damage(I.w_class*I.embedded_impact_pain_multiplier)
|
||||
L.receive_damage(I.w_class*I.embedded_impact_pain_multiplier)
|
||||
visible_message("<span class='danger'>\the [I.name] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>\the [I.name] embeds itself in your [L.name]!</span>")
|
||||
hitpush = 0
|
||||
skipcatch = 1 //can't catch the now embedded item
|
||||
@@ -369,8 +160,8 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && iscarbon(pulling))
|
||||
vore_attack(user, pulling)
|
||||
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (disabilities & FAT) && ismonkey(pulling))
|
||||
devour_mob(pulling)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -379,6 +170,574 @@
|
||||
w_uniform.add_fingerprint(user)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/Stun(amount, updating_canmove = 1)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user)
|
||||
if(!I || !user)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected)) //what we're actually ending up trying to hit.
|
||||
var/target_area = parse_zone(check_zone(user.zone_selected)) //our intended target
|
||||
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
|
||||
feedback_add_details("zone_targeted","[target_area]")
|
||||
|
||||
// the attacked_by code varies among species
|
||||
return dna.species.spec_attacked_by(I, user, affecting, a_intent, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
if(check_shields(15, "the [hulk_verb]ing"))
|
||||
return
|
||||
..(user, 1)
|
||||
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
|
||||
var/message = "[user] has [hulk_verb]ed [src]!"
|
||||
visible_message("<span class='danger'>[message]</span>", \
|
||||
"<span class='userdanger'>[message]</span>")
|
||||
adjustBruteLoss(15)
|
||||
damage_clothes(15, BRUTE, "melee")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //to allow surgery to return properly.
|
||||
return
|
||||
dna.species.spec_attack_hand(M, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
..() //shaking
|
||||
return 0
|
||||
|
||||
if(M.limb_destroyer)
|
||||
dismembering_strike(M, affecting.body_zone)
|
||||
|
||||
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
|
||||
if(..()) //successful monkey bite, this handles disease contraction.
|
||||
var/damage = rand(1, 3)
|
||||
if(check_shields(damage))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(check_shields(0, M.name))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return 0
|
||||
|
||||
if(..())
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
if (w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has lunged at [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor_block = run_armor_check(affecting, "melee","","",10)
|
||||
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
add_logs(M, src, "attacked")
|
||||
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
|
||||
return 1
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead.
|
||||
if(get_active_held_item() && drop_item())
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Weaken(5)
|
||||
add_logs(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(check_shields(damage, "the [L.name]"))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
|
||||
return 0
|
||||
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration)
|
||||
apply_damage(damage, M.melee_damage_type, affecting, armor)
|
||||
damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
|
||||
if(check_shields(damage, "the [M.name]"))
|
||||
return 0
|
||||
|
||||
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head"))
|
||||
if(temp)
|
||||
var/update = 0
|
||||
var/dmg = rand(M.force/2, M.force)
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 20)
|
||||
Paralyse(1)
|
||||
update |= temp.receive_damage(dmg, 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
damage_clothes(dmg, BRUTE, "melee", temp.body_zone)
|
||||
if("fire")
|
||||
update |= temp.receive_damage(0, dmg)
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
damage_clothes(dmg, BURN, "melee", temp.body_zone)
|
||||
if("tox")
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
updatehealth()
|
||||
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/ex_act(severity, target, origin)
|
||||
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
var/b_loss = 0
|
||||
var/f_loss = 0
|
||||
var/bomb_armor = getarmor(null, "bomb")
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
if(prob(bomb_armor))
|
||||
b_loss = 500
|
||||
var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
|
||||
throw_at(throw_target, 200, 4)
|
||||
damage_clothes(400 - bomb_armor, BRUTE, "bomb")
|
||||
else
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
b_loss = 60
|
||||
f_loss = 60
|
||||
if(bomb_armor)
|
||||
b_loss = 30*(2 - round(bomb_armor*0.01, 0.05))
|
||||
f_loss = b_loss
|
||||
damage_clothes(200 - bomb_armor, BRUTE, "bomb")
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(30, 120)
|
||||
if (prob(70))
|
||||
Paralyse(10)
|
||||
|
||||
if(3)
|
||||
b_loss = 30
|
||||
if(bomb_armor)
|
||||
b_loss = 15*(2 - round(bomb_armor*0.01, 0.05))
|
||||
damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb")
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(15,60)
|
||||
if (prob(50))
|
||||
Paralyse(8)
|
||||
|
||||
take_overall_damage(b_loss,f_loss)
|
||||
|
||||
//attempt to dismember bodyparts
|
||||
if(severity <= 2 || !bomb_armor)
|
||||
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest")
|
||||
BP.brute_dam = BP.max_damage
|
||||
BP.dismember()
|
||||
max_limb_loss--
|
||||
if(!max_limb_loss)
|
||||
break
|
||||
|
||||
|
||||
/mob/living/carbon/human/blob_act(obj/structure/blob/B)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
show_message("<span class='userdanger'>The blob attacks you!</span>")
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
|
||||
if(tesla_shock)
|
||||
var/total_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(G.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.5
|
||||
if(wear_suit)
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
if(S.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.95
|
||||
siemens_coeff = total_coeff
|
||||
else if(!safety)
|
||||
var/gloves_siemens_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
gloves_siemens_coeff = G.siemens_coefficient
|
||||
siemens_coeff = gloves_siemens_coeff
|
||||
if(heart_attack && !illusion)
|
||||
if(shock_damage * siemens_coeff >= 1 && prob(25))
|
||||
heart_attack = 0
|
||||
if(stat == CONSCIOUS)
|
||||
src << "<span class='notice'>You feel your heart beating again!</span>"
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
|
||||
/mob/living/carbon/human/emp_act(severity)
|
||||
var/informed = 0
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
if(L.status == BODYPART_ROBOTIC)
|
||||
if(!informed)
|
||||
src << "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>"
|
||||
informed = 1
|
||||
switch(severity)
|
||||
if(1)
|
||||
L.receive_damage(0,10)
|
||||
src.Stun(10)
|
||||
if(2)
|
||||
L.receive_damage(0,5)
|
||||
src.Stun(5)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit)
|
||||
var/list/damaged = list()
|
||||
var/list/inventory_items_to_kill = list()
|
||||
var/acidity = acidpwr * min(acid_volume*0.005, 0.1)
|
||||
//HEAD//
|
||||
if(!bodyzone_hit || bodyzone_hit == "head") //only if we didn't specify a zone or if that zone is the head.
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
if(!(head_clothes.resistance_flags & UNACIDABLE))
|
||||
head_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_glasses()
|
||||
update_inv_wear_mask()
|
||||
update_inv_neck()
|
||||
update_inv_head()
|
||||
else
|
||||
src << "<span class='notice'>Your [head_clothes.name] protects your head and face from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("head")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(ears)
|
||||
inventory_items_to_kill += ears
|
||||
|
||||
//CHEST//
|
||||
if(!bodyzone_hit || bodyzone_hit == "chest")
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
if(!(chest_clothes.resistance_flags & UNACIDABLE))
|
||||
chest_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [chest_clothes.name] protects your body from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("chest")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(wear_id)
|
||||
inventory_items_to_kill += wear_id
|
||||
if(r_store)
|
||||
inventory_items_to_kill += r_store
|
||||
if(l_store)
|
||||
inventory_items_to_kill += l_store
|
||||
if(s_store)
|
||||
inventory_items_to_kill += s_store
|
||||
|
||||
|
||||
//ARMS & HANDS//
|
||||
if(!bodyzone_hit || bodyzone_hit == "l_arm" || bodyzone_hit == "r_arm")
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
|
||||
arm_clothes = wear_suit
|
||||
|
||||
if(arm_clothes)
|
||||
if(!(arm_clothes.resistance_flags & UNACIDABLE))
|
||||
arm_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_gloves()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [arm_clothes.name] protects your arms and hands from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//LEGS & FEET//
|
||||
if(!bodyzone_hit || bodyzone_hit == "l_leg" || bodyzone_hit == "r_leg" || bodyzone_hit == "feet")
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (w_uniform.body_parts_covered & LEGS))))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (wear_suit.body_parts_covered & LEGS))))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
if(!(leg_clothes.resistance_flags & UNACIDABLE))
|
||||
leg_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_shoes()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [leg_clothes.name] protects your legs and feet from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//DAMAGE//
|
||||
for(var/obj/item/bodypart/affecting in damaged)
|
||||
affecting.receive_damage(acidity, 2*acidity)
|
||||
|
||||
if(affecting.name == "head")
|
||||
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
|
||||
affecting.receive_damage(acidity, 2*acidity)
|
||||
emote("scream")
|
||||
facial_hair_style = "Shaved"
|
||||
hair_style = "Bald"
|
||||
update_hair()
|
||||
status_flags |= DISFIGURED
|
||||
|
||||
update_damage_overlays()
|
||||
|
||||
//MELTING INVENTORY ITEMS//
|
||||
//these items are all outside of armour visually, so melt regardless.
|
||||
if(!bodyzone_hit)
|
||||
if(back)
|
||||
inventory_items_to_kill += back
|
||||
if(belt)
|
||||
inventory_items_to_kill += belt
|
||||
|
||||
inventory_items_to_kill += held_items
|
||||
|
||||
for(var/obj/item/I in inventory_items_to_kill)
|
||||
I.acid_act(acidpwr, acid_volume)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/singularity_act()
|
||||
var/gain = 20
|
||||
if(mind)
|
||||
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
|
||||
gain = 100
|
||||
if(mind.assigned_role == "Clown")
|
||||
gain = rand(-300, 300)
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/carbon/human/help_shake_act(mob/living/carbon/M)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(health >= 0)
|
||||
if(src == M)
|
||||
visible_message("[src] examines [p_them()]self.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/LB = X
|
||||
missing -= LB.body_zone
|
||||
var/status = ""
|
||||
var/brutedamage = LB.brute_dam
|
||||
var/burndamage = LB.burn_dam
|
||||
if(hallucination)
|
||||
if(prob(30))
|
||||
brutedamage += rand(30,40)
|
||||
if(prob(30))
|
||||
burndamage += rand(30,40)
|
||||
|
||||
if(brutedamage > 0)
|
||||
status = "bruised"
|
||||
if(brutedamage > 20)
|
||||
status = "battered"
|
||||
if(brutedamage > 40)
|
||||
status = "mangled"
|
||||
if(brutedamage > 0 && burndamage > 0)
|
||||
status += " and "
|
||||
if(burndamage > 40)
|
||||
status += "peeling away"
|
||||
|
||||
else if(burndamage > 10)
|
||||
status += "blistered"
|
||||
else if(burndamage > 0)
|
||||
status += "numb"
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]."
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
src << "\t <a href='byond://?src=\ref[src];embedded_object=\ref[I];embedded_limb=\ref[LB]'>\red There is \a [I] embedded in your [LB.name]!</a>"
|
||||
|
||||
for(var/t in missing)
|
||||
src << "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>"
|
||||
|
||||
if(bleed_rate)
|
||||
src << "<span class='danger'>You are bleeding!</span>"
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
src << "<span class='info'>You're completely exhausted.</span>"
|
||||
else
|
||||
src << "<span class='info'>You feel fatigued.</span>"
|
||||
else
|
||||
if(wear_suit)
|
||||
wear_suit.add_fingerprint(M)
|
||||
else if(w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
if(damage_type != BRUTE && damage_type != BURN)
|
||||
return
|
||||
damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed
|
||||
var/list/torn_items = list()
|
||||
|
||||
//HEAD//
|
||||
if(!def_zone || def_zone == "head")
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
torn_items += head_clothes
|
||||
else if(ears)
|
||||
torn_items += ears
|
||||
|
||||
//CHEST//
|
||||
if(!def_zone || def_zone == "chest")
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
torn_items += chest_clothes
|
||||
|
||||
//ARMS & HANDS//
|
||||
if(!def_zone || def_zone == "l_arm" || def_zone == "r_arm")
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
|
||||
arm_clothes = wear_suit
|
||||
if(arm_clothes)
|
||||
torn_items += arm_clothes
|
||||
|
||||
//LEGS & FEET//
|
||||
if(!def_zone || def_zone == "l_leg" || def_zone == "r_leg")
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS)))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
torn_items += leg_clothes
|
||||
|
||||
for(var/obj/item/I in torn_items)
|
||||
I.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
@@ -3,6 +3,7 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD)
|
||||
pressure_resistance = 25
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
var/hair_style = "Bald"
|
||||
@@ -29,11 +30,7 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
//Equipment slots
|
||||
var/obj/item/wear_suit = null
|
||||
var/obj/item/w_uniform = null
|
||||
var/obj/item/shoes = null
|
||||
var/obj/item/belt = null
|
||||
var/obj/item/gloves = null
|
||||
var/obj/item/clothing/glasses/glasses = null
|
||||
var/obj/item/ears = null
|
||||
var/obj/item/wear_id = null
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
@@ -41,8 +38,6 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
|
||||
var/gender_ambiguous = 0 //if something goes wrong during gender reassignment this generates a line in examine
|
||||
|
||||
var/bleed_rate = 0 //how much are we bleeding
|
||||
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
|
||||
|
||||
|
||||
@@ -81,41 +81,23 @@
|
||||
if(wear_id)
|
||||
return wear_id.GetID()
|
||||
|
||||
///checkeyeprot()
|
||||
///Returns a number between -1 to 2
|
||||
/mob/living/carbon/human/check_eye_prot()
|
||||
var/number = ..()
|
||||
if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head
|
||||
var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item
|
||||
number += HFP.flash_protect
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
|
||||
var/obj/item/clothing/glasses/GFP = src.glasses
|
||||
number += GFP.flash_protect
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
if(istype(src.dna.species, /datum/species/xeno)) //Xenos don't have eyes.
|
||||
number += 2 //So give them protection from flashes.
|
||||
return number
|
||||
|
||||
/mob/living/carbon/human/check_ear_prot()
|
||||
if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/abiotic(full_body = 0)
|
||||
if(full_body && ((l_hand && !( src.l_hand.flags&ABSTRACT )) || (r_hand && !( src.r_hand.flags&ABSTRACT )) || (back && !(back.flags&ABSTRACT)) || (wear_mask && !(wear_mask.flags&ABSTRACT)) || (head && !(head.flags&ABSTRACT)) || (shoes && !(shoes.flags&ABSTRACT)) || (w_uniform && !(w_uniform.flags&ABSTRACT)) || (wear_suit && !(wear_suit.flags&ABSTRACT)) || (glasses && !(glasses.flags&ABSTRACT)) || (ears && !(ears.flags&ABSTRACT)) || (gloves && !(gloves.flags&ABSTRACT)) ) )
|
||||
return 1
|
||||
var/abiotic_hands = FALSE
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & NODROP))
|
||||
abiotic_hands = TRUE
|
||||
break
|
||||
if(full_body && abiotic_hands && ((back && !(back.flags&NODROP)) || (wear_mask && !(wear_mask.flags&NODROP)) || (head && !(head.flags&NODROP)) || (shoes && !(shoes.flags&NODROP)) || (w_uniform && !(w_uniform.flags&NODROP)) || (wear_suit && !(wear_suit.flags&NODROP)) || (glasses && !(glasses.flags&NODROP)) || (ears && !(ears.flags&NODROP)) || (gloves && !(gloves.flags&NODROP)) ) )
|
||||
return TRUE
|
||||
return abiotic_hands
|
||||
|
||||
if( (src.l_hand && !(src.l_hand.flags&ABSTRACT)) || (src.r_hand && !(src.r_hand.flags&ABSTRACT)) )
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/IsAdvancedToolUser()
|
||||
return 1//Humans can use guns and such
|
||||
|
||||
/mob/living/carbon/human/InCritical()
|
||||
return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
|
||||
return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
|
||||
|
||||
/mob/living/carbon/human/reagent_check(datum/reagent/R)
|
||||
return dna.species.handle_chemicals(R,src)
|
||||
@@ -159,7 +141,7 @@
|
||||
if(src.dna.check_mutation(HULK))
|
||||
src << "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>"
|
||||
return 0
|
||||
if(NOGUNS in src.dna.species.specflags)
|
||||
if(NOGUNS in src.dna.species.species_traits)
|
||||
src << "<span class='warning'>Your fingers don't fit in the trigger guard!</span>"
|
||||
return 0
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. += dna.species.movement_delay(src)
|
||||
. = 0
|
||||
. += ..()
|
||||
. += config.human_delay
|
||||
|
||||
. += dna.species.movement_delay(src)
|
||||
|
||||
/mob/living/carbon/human/slip(s_amount, w_amount, obj/O, lube)
|
||||
if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP))
|
||||
@@ -60,4 +60,4 @@
|
||||
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
|
||||
if(..())
|
||||
return 1
|
||||
return dna.species.space_move()
|
||||
return dna.species.space_move(src)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1)
|
||||
for(var/slot in slots)
|
||||
if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0))
|
||||
if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0, disable_warning = TRUE))
|
||||
return slot
|
||||
if(qdel_on_fail)
|
||||
qdel(I)
|
||||
@@ -18,14 +18,12 @@
|
||||
return back
|
||||
if(slot_wear_mask)
|
||||
return wear_mask
|
||||
if(slot_neck)
|
||||
return wear_neck
|
||||
if(slot_handcuffed)
|
||||
return handcuffed
|
||||
if(slot_legcuffed)
|
||||
return legcuffed
|
||||
if(slot_l_hand)
|
||||
return l_hand
|
||||
if(slot_r_hand)
|
||||
return r_hand
|
||||
if(slot_belt)
|
||||
return belt
|
||||
if(slot_wear_id)
|
||||
@@ -52,11 +50,48 @@
|
||||
return s_store
|
||||
return null
|
||||
|
||||
/mob/living/carbon/human/proc/get_all_slots()
|
||||
. = get_head_slots() | get_body_slots()
|
||||
|
||||
/mob/living/carbon/human/proc/get_body_slots()
|
||||
return list(
|
||||
back,
|
||||
s_store,
|
||||
handcuffed,
|
||||
legcuffed,
|
||||
wear_suit,
|
||||
gloves,
|
||||
shoes,
|
||||
belt,
|
||||
wear_id,
|
||||
l_store,
|
||||
r_store,
|
||||
w_uniform
|
||||
)
|
||||
|
||||
/mob/living/carbon/human/proc/get_head_slots()
|
||||
return list(
|
||||
head,
|
||||
wear_mask,
|
||||
glasses,
|
||||
ears,
|
||||
)
|
||||
|
||||
/mob/living/carbon/human/proc/get_storage_slots()
|
||||
return list(
|
||||
back,
|
||||
belt,
|
||||
l_store,
|
||||
r_store,
|
||||
s_store,
|
||||
)
|
||||
|
||||
//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()
|
||||
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
|
||||
if(!..()) //a check failed or the item has already found its slot
|
||||
return
|
||||
|
||||
var/not_handled = FALSE //Added in case we make this type path deeper one day
|
||||
switch(slot)
|
||||
if(slot_belt)
|
||||
belt = I
|
||||
@@ -71,6 +106,8 @@
|
||||
if(slot_glasses)
|
||||
glasses = I
|
||||
var/obj/item/clothing/glasses/G = I
|
||||
if(G.glass_colour_type)
|
||||
update_glasses_color(G, 1)
|
||||
if(G.tint)
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
@@ -108,6 +145,12 @@
|
||||
else
|
||||
src << "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>"
|
||||
|
||||
//Item is handled and in slot, valid to call callback, for this proc should always be true
|
||||
if(!not_handled)
|
||||
I.equipped(src, slot)
|
||||
|
||||
return not_handled //For future deeper overrides
|
||||
|
||||
/mob/living/carbon/human/unEquip(obj/item/I)
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
if(!. || !I)
|
||||
@@ -140,6 +183,8 @@
|
||||
else if(I == glasses)
|
||||
glasses = null
|
||||
var/obj/item/clothing/glasses/G = I
|
||||
if(G.glass_colour_type)
|
||||
update_glasses_color(G, 0)
|
||||
if(G.tint)
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
@@ -192,91 +237,6 @@
|
||||
sec_hud_set_security_status()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
//Cycles through all clothing slots and tests them for destruction
|
||||
/mob/living/carbon/human/proc/shred_clothing(bomb,shock)
|
||||
var/covered_parts = 0 //The body parts that are protected by exterior clothing/armor
|
||||
var/head_absorbed = 0 //How much of the shock the headgear absorbs when it is shredded. -1=it survives
|
||||
var/suit_absorbed = 0 //How much of the shock the exosuit absorbs when it is shredded. -1=it survives
|
||||
|
||||
//Backpacks can never be protected but are annoying as fuck to lose, so they get a lower chance to be shredded
|
||||
if(back)
|
||||
back.shred(bomb,shock-20,src)
|
||||
|
||||
if(head)
|
||||
covered_parts |= head.flags_inv
|
||||
head_absorbed = head.shred(bomb,shock,src)
|
||||
if(wear_mask)
|
||||
var/absorbed = ((covered_parts & HIDEMASK) ? head_absorbed : 0) //Check if clothing covering this part absorbed any of the shock
|
||||
if(absorbed >= 0)
|
||||
//Masks can be used to shield other parts, but are simplified to simply add their absorbsion to the head armor if it covers the face
|
||||
var/mask_absorbed = wear_mask.shred(bomb,shock-absorbed,src)
|
||||
if(wear_mask.flags_inv & HIDEFACE)
|
||||
covered_parts |= wear_mask.flags_inv
|
||||
if(mask_absorbed < 0) //If the mask didn't get shredded, everything else on the head is protected
|
||||
head_absorbed = -1
|
||||
else
|
||||
head_absorbed += mask_absorbed
|
||||
if(ears)
|
||||
var/absorbed = ((covered_parts & HIDEEARS) ? head_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
ears.shred(bomb,shock-absorbed,src)
|
||||
if(glasses)
|
||||
var/absorbed = ((covered_parts & HIDEEYES) ? head_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
glasses.shred(bomb,shock-absorbed,src)
|
||||
|
||||
if(wear_suit)
|
||||
covered_parts |= wear_suit.flags_inv
|
||||
suit_absorbed = wear_suit.shred(bomb,shock,src)
|
||||
if(gloves)
|
||||
var/absorbed = ((covered_parts & HIDEGLOVES) ? suit_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
gloves.shred(bomb,shock-absorbed,src)
|
||||
if(shoes)
|
||||
var/absorbed = ((covered_parts & HIDESHOES) ? suit_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
shoes.shred(bomb,shock-absorbed,src)
|
||||
if(w_uniform)
|
||||
var/absorbed = ((covered_parts & HIDEJUMPSUIT) ? suit_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
w_uniform.shred(bomb,shock-20-absorbed,src) //Uniforms are also annoying to get shredded
|
||||
|
||||
/obj/item/proc/shred(bomb,shock,mob/living/carbon/human/Human)
|
||||
if(flags & ABSTRACT)
|
||||
return -1
|
||||
|
||||
var/shredded
|
||||
|
||||
if(!bomb)
|
||||
if(burn_state != -1)
|
||||
shredded = 1 //No heat protection, it burns
|
||||
else
|
||||
shredded = -1 //Heat protection = Fireproof
|
||||
|
||||
else if(shock > 0)
|
||||
if(prob(max(shock-armor["bomb"],0)))
|
||||
shredded = armor["bomb"] + 10 //It gets shredded, but it also absorbs the shock the clothes underneath would recieve by this amount
|
||||
else
|
||||
shredded = -1 //It survives explosion
|
||||
|
||||
if(shredded > 0)
|
||||
if(Human) //Unequip if equipped
|
||||
Human.unEquip(src)
|
||||
|
||||
if(bomb)
|
||||
empty_object_contents()
|
||||
spawn(1) //so the shreds aren't instantly deleted by the explosion
|
||||
var/obj/effect/decal/cleanable/shreds/Shreds = new(loc)
|
||||
Shreds.desc = "The sad remains of what used to be [src.name]."
|
||||
qdel(src)
|
||||
else
|
||||
burn()
|
||||
|
||||
return shredded
|
||||
|
||||
/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
|
||||
var/datum/outfit/O = null
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
|
||||
|
||||
@@ -29,20 +29,26 @@
|
||||
if (notransform)
|
||||
return
|
||||
|
||||
if(..())
|
||||
if(..()) //not dead
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_life(src)
|
||||
|
||||
if(stat != DEAD)
|
||||
//heart attack stuff
|
||||
handle_heart()
|
||||
|
||||
if(stat != DEAD)
|
||||
//Stuff jammed in your limbs hurts
|
||||
handle_embedded_objects()
|
||||
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
name = get_visible_name()
|
||||
|
||||
dna.species.spec_life(src) // for mutantraces
|
||||
|
||||
if(stat != DEAD)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE)))
|
||||
@@ -85,9 +91,38 @@
|
||||
/mob/living/carbon/human/breathe()
|
||||
if(!dna.species.breathe(src))
|
||||
..()
|
||||
|
||||
#define HUMAN_MAX_OXYLOSS 3
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)
|
||||
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
|
||||
dna.species.check_breath(breath, src)
|
||||
|
||||
var/L = getorganslot("lungs")
|
||||
|
||||
if(!L)
|
||||
if(health >= HEALTH_THRESHOLD_CRIT)
|
||||
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
|
||||
else if(!(NOCRITDAMAGE in dna.species.species_traits))
|
||||
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
|
||||
|
||||
failed_last_breath = 1
|
||||
|
||||
if(dna && dna.species)
|
||||
var/datum/species/S = dna.species
|
||||
|
||||
if(S.breathid == "o2")
|
||||
throw_alert("oxy", /obj/screen/alert/oxy)
|
||||
else if(S.breathid == "tox")
|
||||
throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
|
||||
else if(S.breathid == "co2")
|
||||
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
|
||||
|
||||
return 0
|
||||
else
|
||||
if(istype(L,/obj/item/organ/lungs))
|
||||
var/obj/item/organ/lungs/lun = L
|
||||
lun.check_breath(breath,src)
|
||||
|
||||
#undef HUMAN_MAX_OXYLOSS
|
||||
#undef HUMAN_CRIT_MAX_OXYLOSS
|
||||
|
||||
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
|
||||
dna.species.handle_environment(environment, src)
|
||||
@@ -97,6 +132,61 @@
|
||||
if(!dna || !dna.species.handle_fire(src))
|
||||
..()
|
||||
if(on_fire)
|
||||
|
||||
//the fire tries to damage the exposed clothes and items
|
||||
var/list/burning_items = list()
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
burning_items += head_clothes
|
||||
else if(ears)
|
||||
burning_items += ears
|
||||
|
||||
//CHEST//
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
|
||||
if(chest_clothes)
|
||||
burning_items += chest_clothes
|
||||
|
||||
//ARMS & HANDS//
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
|
||||
arm_clothes = wear_suit
|
||||
if(arm_clothes)
|
||||
burning_items += arm_clothes
|
||||
|
||||
//LEGS & FEET//
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS)))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
burning_items += leg_clothes
|
||||
|
||||
for(var/X in burning_items)
|
||||
var/obj/item/I = X
|
||||
if(!(I.resistance_flags & FIRE_PROOF))
|
||||
I.take_damage(fire_stacks, BURN, "fire", 0)
|
||||
|
||||
var/thermal_protection = get_thermal_protection()
|
||||
|
||||
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
|
||||
@@ -217,7 +307,7 @@
|
||||
if(dna.check_mutation(COLDRES))
|
||||
return 1 //Fully protected from the cold.
|
||||
|
||||
if(dna && (RESISTTEMP in dna.species.specflags))
|
||||
if(dna && (RESISTCOLD in dna.species.species_traits))
|
||||
return 1
|
||||
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
@@ -277,7 +367,7 @@
|
||||
if(head)
|
||||
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
. = 1
|
||||
if(NOBREATH in dna.species.specflags)
|
||||
if(NOBREATH in dna.species.species_traits)
|
||||
. = 1
|
||||
return .
|
||||
|
||||
@@ -287,11 +377,11 @@
|
||||
var/obj/item/bodypart/BP = X
|
||||
for(var/obj/item/I in BP.embedded_objects)
|
||||
if(prob(I.embedded_pain_chance))
|
||||
BP.take_damage(I.w_class*I.embedded_pain_multiplier)
|
||||
BP.receive_damage(I.w_class*I.embedded_pain_multiplier)
|
||||
src << "<span class='userdanger'>\the [I] embedded in your [BP.name] hurts!</span>"
|
||||
|
||||
if(prob(I.embedded_fall_chance))
|
||||
BP.take_damage(I.w_class*I.embedded_fall_pain_multiplier)
|
||||
BP.receive_damage(I.w_class*I.embedded_fall_pain_multiplier)
|
||||
BP.embedded_objects -= I
|
||||
I.loc = get_turf(src)
|
||||
visible_message("<span class='danger'>\the [I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>\the [I] falls out of your [BP.name]!</span>")
|
||||
@@ -301,8 +391,8 @@
|
||||
|
||||
/mob/living/carbon/human/proc/handle_heart()
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
var/needs_heart = (!(NOBLOOD in dna.species.specflags))
|
||||
var/we_breath = (!(NOBREATH in dna.species.specflags))
|
||||
var/needs_heart = (!(NOBLOOD in dna.species.species_traits))
|
||||
var/we_breath = (!(NOBREATH in dna.species.species_traits))
|
||||
|
||||
if(heart_attack)
|
||||
if(!needs_heart)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
|
||||
// how do species that don't breathe talk? magic, that's what.
|
||||
if(!(NOBREATH in dna.species.specflags) && !getorganslot("lungs"))
|
||||
if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs"))
|
||||
return 0
|
||||
if(mind)
|
||||
return !mind.miming
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
|
||||
/mob/living/carbon/human/Stun(amount, updating = 1, ignore_canstun = 0)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/Weaken(amount, updating = 1, ignore_canstun = 0)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/cure_husk()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/become_husk()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_hair()
|
||||
@@ -4,8 +4,10 @@
|
||||
/* Keep these comments up-to-date if you -insist- on hurting my code-baby ;_;
|
||||
This system allows you to update individual mob-overlays, without regenerating them all each time.
|
||||
When we generate overlays we generate the standing version and then rotate the mob as necessary..
|
||||
|
||||
As of the time of writing there are 20 layers within this list. Please try to keep this from increasing. //22 and counting, good job guys
|
||||
var/overlays_standing[20] //For the standing stance
|
||||
|
||||
Most of the time we only wish to update one overlay:
|
||||
e.g. - we dropped the fireaxe out of our left hand and need to remove its icon from our mob
|
||||
e.g.2 - our hair colour has changed, so we need to update our hair icons on our mob
|
||||
@@ -13,21 +15,28 @@ In these cases, instead of updating every overlay using the old behaviour (regen
|
||||
the appropriate update_X proc.
|
||||
e.g. - update_l_hand()
|
||||
e.g.2 - update_hair()
|
||||
|
||||
Note: Recent changes by aranclanos+carn:
|
||||
update_icons() no longer needs to be called.
|
||||
the system is easier to use. update_icons() should not be called unless you absolutely -know- you need it.
|
||||
IN ALL OTHER CASES it's better to just call the specific update_X procs.
|
||||
|
||||
Note: The defines for layer numbers is now kept exclusvely in __DEFINES/misc.dm instead of being defined there,
|
||||
then redefined and undefiend everywhere else. If you need to change the layering of sprites (or add a new layer)
|
||||
that's where you should start.
|
||||
|
||||
All of this means that this code is more maintainable, faster and still fairly easy to use.
|
||||
|
||||
There are several things that need to be remembered:
|
||||
> Whenever we do something that should cause an overlay to update (which doesn't use standard procs
|
||||
( i.e. you do something like l_hand = /obj/item/something new(src), rather than using the helper procs)
|
||||
You will need to call the relevant update_inv_* proc
|
||||
|
||||
All of these are named after the variable they update from. They are defined at the mob/ level like
|
||||
update_clothing was, so you won't cause undefined proc runtimes with usr.update_inv_wear_id() if the usr is a
|
||||
slime etc. Instead, it'll just return without doing any work. So no harm in calling it for slimes and such.
|
||||
|
||||
|
||||
> There are also these special cases:
|
||||
update_damage_overlays() //handles damage overlays for brute/burn damage
|
||||
update_body() //Handles updating your mob's body layer and mutant bodyparts
|
||||
@@ -35,30 +44,10 @@ There are several things that need to be remembered:
|
||||
//NOTE: update_mutantrace() is now merged into this!
|
||||
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
|
||||
eyes were merged into update_body())
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//DAMAGE OVERLAYS
|
||||
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
|
||||
/mob/living/carbon/human/update_damage_overlays()
|
||||
remove_overlay(DAMAGE_LAYER)
|
||||
|
||||
var/image/standing = image("icon"='icons/mob/dam_human.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER)
|
||||
overlays_standing[DAMAGE_LAYER] = standing
|
||||
|
||||
var/dmgoverlaytype = ""
|
||||
if(dna.species.exotic_damage_overlay)
|
||||
dmgoverlaytype = dna.species.exotic_damage_overlay + "_"
|
||||
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brutestate)
|
||||
standing.overlays += "[dmgoverlaytype][BP.body_zone]_[BP.brutestate]0" //we're adding icon_states of the base image as overlays
|
||||
if(BP.burnstate)
|
||||
standing.overlays += "[dmgoverlaytype][BP.body_zone]_0[BP.burnstate]"
|
||||
|
||||
apply_overlay(DAMAGE_LAYER)
|
||||
|
||||
|
||||
//HAIR OVERLAY
|
||||
/mob/living/carbon/human/update_hair()
|
||||
dna.species.handle_hair(src)
|
||||
@@ -68,47 +57,14 @@ There are several things that need to be remembered:
|
||||
dna.species.handle_mutant_bodyparts(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/update_body()
|
||||
/mob/living/carbon/human/update_body()
|
||||
remove_overlay(BODY_LAYER)
|
||||
dna.species.handle_body(src)
|
||||
update_body_parts()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/update_fire()
|
||||
..("Standing")
|
||||
|
||||
/mob/living/carbon/human/proc/update_body_parts()
|
||||
//CHECK FOR UPDATE
|
||||
var/oldkey = icon_render_key
|
||||
icon_render_key = generate_icon_render_key()
|
||||
if(oldkey == icon_render_key)
|
||||
return
|
||||
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
|
||||
//LOAD ICONS
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
load_limb_from_cache()
|
||||
update_damage_overlays()
|
||||
update_mutant_bodyparts()
|
||||
update_hair()
|
||||
return
|
||||
|
||||
//GENERATE NEW LIMBS
|
||||
var/list/new_limbs = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(!BP.no_update)
|
||||
BP.update_limb()
|
||||
var/image/temp = BP.get_limb_icon()
|
||||
if(temp)
|
||||
new_limbs += temp
|
||||
if(new_limbs.len)
|
||||
overlays_standing[BODYPARTS_LAYER] = new_limbs
|
||||
limb_icon_cache[icon_render_key] = new_limbs
|
||||
|
||||
apply_overlay(BODYPARTS_LAYER)
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
/* --------------------------------------- */
|
||||
//For legacy support.
|
||||
@@ -130,6 +86,7 @@ There are several things that need to be remembered:
|
||||
update_inv_back()
|
||||
update_inv_wear_suit()
|
||||
update_inv_pockets()
|
||||
update_inv_neck()
|
||||
update_transform()
|
||||
//mutations
|
||||
update_mutations_overlay()
|
||||
@@ -148,10 +105,11 @@ There are several things that need to be remembered:
|
||||
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = w_uniform
|
||||
U.screen_loc = ui_iclothing
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
U.screen_loc = ui_iclothing //...draw the item in the inventory screen
|
||||
client.screen += w_uniform //Either way, add the item to the HUD
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += w_uniform
|
||||
update_observer_view(w_uniform,1)
|
||||
|
||||
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
|
||||
return
|
||||
@@ -160,8 +118,10 @@ There are several things that need to be remembered:
|
||||
var/t_color = U.item_color
|
||||
if(!t_color)
|
||||
t_color = U.icon_state
|
||||
if(U.adjusted)
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d"
|
||||
else if(U.adjusted == DIGITIGRADE_STYLE)
|
||||
t_color = "[t_color]_l"
|
||||
|
||||
var/image/standing
|
||||
|
||||
@@ -181,6 +141,7 @@ There are several things that need to be remembered:
|
||||
unEquip(thing)
|
||||
|
||||
apply_overlay(UNIFORM_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_id()
|
||||
@@ -191,9 +152,10 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_id)
|
||||
wear_id.screen_loc = ui_id
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
wear_id.screen_loc = ui_id
|
||||
client.screen += wear_id
|
||||
update_observer_view(wear_id)
|
||||
|
||||
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
|
||||
var/image/standing = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi')
|
||||
@@ -206,18 +168,25 @@ There are several things that need to be remembered:
|
||||
remove_overlay(GLOVES_LAYER)
|
||||
|
||||
if(get_num_arms() <2)
|
||||
if(!gloves && blood_DNA)
|
||||
if(has_left_hand())
|
||||
overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_left", "layer"=-GLOVES_LAYER)
|
||||
apply_overlay(GLOVES_LAYER)
|
||||
else if(has_right_hand())
|
||||
overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_right", "layer"=-GLOVES_LAYER)
|
||||
apply_overlay(GLOVES_LAYER)
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
if(client && hud_used && hud_used.inv_slots[slot_gloves])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
|
||||
inv.update_icon()
|
||||
|
||||
if(gloves)
|
||||
gloves.screen_loc = ui_gloves
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
gloves.screen_loc = ui_gloves //...draw the item in the inventory screen
|
||||
client.screen += gloves //Either way, add the item to the HUD
|
||||
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += gloves
|
||||
update_observer_view(gloves,1)
|
||||
var/t_state = gloves.item_state
|
||||
if(!t_state)
|
||||
t_state = gloves.icon_state
|
||||
@@ -233,7 +202,6 @@ There are several things that need to be remembered:
|
||||
apply_overlay(GLOVES_LAYER)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_glasses()
|
||||
remove_overlay(GLASSES_LAYER)
|
||||
|
||||
@@ -245,11 +213,11 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(glasses)
|
||||
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
|
||||
client.screen += glasses //Either way, add the item to the HUD
|
||||
|
||||
client.screen += glasses //Either way, add the item to the HUD
|
||||
update_observer_view(glasses,1)
|
||||
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
|
||||
|
||||
var/image/standing = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
|
||||
@@ -269,10 +237,11 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(ears)
|
||||
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
ears.screen_loc = ui_ears //...draw the item in the inventory screen
|
||||
client.screen += ears //Either way, add the item to the HUD
|
||||
if(hud_used.inventory_shown) //if the inventory is open
|
||||
client.screen += ears //add it to the client's screen
|
||||
update_observer_view(ears,1)
|
||||
|
||||
var/image/standing = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
|
||||
overlays_standing[EARS_LAYER] = standing
|
||||
@@ -291,11 +260,11 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(shoes)
|
||||
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
shoes.screen_loc = ui_shoes //...draw the item in the inventory screen
|
||||
client.screen += shoes //Either way, add the item to the HUD
|
||||
|
||||
if(hud_used.inventory_shown) //if the inventory is open
|
||||
client.screen += shoes //add it to client's screen
|
||||
update_observer_view(shoes,1)
|
||||
var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi')
|
||||
overlays_standing[SHOES_LAYER] = standing
|
||||
|
||||
@@ -310,10 +279,10 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(s_store)
|
||||
s_store.screen_loc = ui_sstore1
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
s_store.screen_loc = ui_sstore1
|
||||
client.screen += s_store
|
||||
|
||||
update_observer_view(s_store)
|
||||
var/t_state = s_store.item_state
|
||||
if(!t_state)
|
||||
t_state = s_store.icon_state
|
||||
@@ -322,19 +291,10 @@ There are several things that need to be remembered:
|
||||
apply_overlay(SUIT_STORE_LAYER)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_head()
|
||||
remove_overlay(HEAD_LAYER)
|
||||
if(!get_bodypart("head")) //Decapitated
|
||||
return
|
||||
..()
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head]
|
||||
inv.update_icon()
|
||||
|
||||
update_mutant_bodyparts()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_belt()
|
||||
remove_overlay(BELT_LAYER)
|
||||
|
||||
@@ -342,11 +302,12 @@ There are several things that need to be remembered:
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt]
|
||||
inv.update_icon()
|
||||
|
||||
if(hud_used.hud_shown && belt)
|
||||
client.screen += belt
|
||||
belt.screen_loc = ui_belt
|
||||
|
||||
if(belt)
|
||||
belt.screen_loc = ui_belt
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
client.screen += belt
|
||||
update_observer_view(belt)
|
||||
|
||||
var/t_state = belt.item_state
|
||||
if(!t_state)
|
||||
t_state = belt.icon_state
|
||||
@@ -367,17 +328,17 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(istype(wear_suit, /obj/item/clothing/suit))
|
||||
wear_suit.screen_loc = ui_oclothing
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
wear_suit.screen_loc = ui_oclothing //TODO //...draw the item in the inventory screen
|
||||
client.screen += wear_suit //Either way, add the item to the HUD
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += wear_suit
|
||||
update_observer_view(wear_suit,1)
|
||||
|
||||
var/image/standing = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = 'icons/mob/suit.dmi')
|
||||
overlays_standing[SUIT_LAYER] = standing
|
||||
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
if(wear_suit.breakouttime) //suit is restraining
|
||||
drop_all_held_items()
|
||||
|
||||
update_hair()
|
||||
update_mutant_bodyparts()
|
||||
@@ -395,31 +356,23 @@ There are several things that need to be remembered:
|
||||
inv = hud_used.inv_slots[slot_r_store]
|
||||
inv.update_icon()
|
||||
|
||||
if(hud_used.hud_shown)
|
||||
if(l_store)
|
||||
if(l_store)
|
||||
l_store.screen_loc = ui_storage1
|
||||
if(hud_used.hud_shown)
|
||||
client.screen += l_store
|
||||
l_store.screen_loc = ui_storage1
|
||||
update_observer_view(l_store)
|
||||
|
||||
if(r_store)
|
||||
if(r_store)
|
||||
r_store.screen_loc = ui_storage2
|
||||
if(hud_used.hud_shown)
|
||||
client.screen += r_store
|
||||
r_store.screen_loc = ui_storage2
|
||||
update_observer_view(r_store)
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_mask()
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
if(!get_bodypart("head")) //Decapitated
|
||||
return
|
||||
..()
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask]
|
||||
inv.update_icon()
|
||||
update_mutant_bodyparts()
|
||||
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
|
||||
|
||||
/mob/living/carbon/human/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
/mob/living/carbon/human/update_inv_legcuffed()
|
||||
remove_overlay(LEGCUFF_LAYER)
|
||||
@@ -439,7 +392,7 @@ There are several things that need to be remembered:
|
||||
|
||||
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
|
||||
var/list/out = new
|
||||
for(var/i=1;i<=TOTAL_LAYERS;i++)
|
||||
for(var/i in 1 to TOTAL_LAYERS)
|
||||
if(overlays_standing[i])
|
||||
if(i in unwantedLayers)
|
||||
continue
|
||||
@@ -451,23 +404,36 @@ There are several things that need to be remembered:
|
||||
|
||||
//update whether our head item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_head(obj/item/I)
|
||||
I.screen_loc = ui_head
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
I.screen_loc = ui_head
|
||||
client.screen += I
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our mask item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_wear_mask(obj/item/I)
|
||||
I.screen_loc = ui_mask
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
I.screen_loc = ui_mask
|
||||
client.screen += I
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_neck(obj/item/I)
|
||||
I.screen_loc = ui_neck
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our back item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_back(obj/item/I)
|
||||
I.screen_loc = ui_back
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
I.screen_loc = ui_back
|
||||
client.screen += I
|
||||
update_observer_view(I)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -477,15 +443,23 @@ covers:
|
||||
centering large images
|
||||
layering images on custom layers
|
||||
building images from custom icon files
|
||||
|
||||
By Remie Richards (yes I'm taking credit because this just removed 90% of the copypaste in update_icons())
|
||||
|
||||
state: A string to use as the state, this is FAR too complex to solve in this proc thanks to shitty old code
|
||||
so it's specified as an argument instead.
|
||||
|
||||
default_layer: The layer to draw this on if no other layer is specified
|
||||
|
||||
default_icon_file: The icon file to draw states from if no other icon file is specified
|
||||
|
||||
isinhands: If true then alternate_worn_icon is skipped so that default_icon_file is used,
|
||||
in this situation default_icon_file is expected to match either the lefthand_ or righthand_ file var
|
||||
|
||||
femalueuniform: A value matching a uniform item's fitted var, if this is anything but NO_FEMALE_UNIFORM, we
|
||||
generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
|
||||
*/
|
||||
/obj/item/proc/build_worn_icon(var/state = "", var/default_layer = 0, var/default_icon_file = null, var/isinhands = FALSE, var/femaleuniform = NO_FEMALE_UNIFORM)
|
||||
|
||||
@@ -517,41 +491,42 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
standing = center_image(standing, isinhands ? inhand_x_dimension : worn_x_dimension, isinhands ? inhand_y_dimension : worn_y_dimension)
|
||||
|
||||
//Handle held offsets
|
||||
var/mob/M = loc
|
||||
if(istype(M))
|
||||
var/list/L = get_held_offsets()
|
||||
if(L)
|
||||
standing.pixel_x += L["x"] //+= because of center()ing
|
||||
standing.pixel_y += L["y"]
|
||||
|
||||
standing.alpha = alpha
|
||||
standing.color = color
|
||||
|
||||
return standing
|
||||
|
||||
|
||||
/obj/item/proc/get_held_offsets()
|
||||
var/list/L
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
L = M.get_item_offsets_for_index(M.get_held_index_of_item(src))
|
||||
return L
|
||||
|
||||
|
||||
//Can't think of a better way to do this, sadly
|
||||
/mob/proc/get_item_offsets_for_index(i)
|
||||
switch(i)
|
||||
if(3) //odd = left hands
|
||||
return list("x" = 0, "y" = 16)
|
||||
if(4) //even = right hands
|
||||
return list("x" = 0, "y" = 16)
|
||||
else //No offsets or Unwritten number of hands
|
||||
return list("x" = 0, "y" = 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Limb Icon Cache //
|
||||
/////////////////////
|
||||
/*
|
||||
Called from update_body_parts() these procs handle the limb icon cache.
|
||||
the limb icon cache adds an icon_render_key to a human mob, it represents:
|
||||
- skin_tone (if applicable)
|
||||
- gender
|
||||
- limbs (stores as the limb name and whether it is removed/fine, organic/robotic)
|
||||
These procs only store limbs as to increase the number of matching icon_render_keys
|
||||
This cache exists because drawing 6/7 icons for humans constantly is quite a waste
|
||||
See RemieRichards on irc.rizon.net #coderbus
|
||||
*/
|
||||
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/icon_render_key = ""
|
||||
|
||||
|
||||
//produces a key based on the human's limbs
|
||||
/mob/living/carbon/human/proc/generate_icon_render_key()
|
||||
/mob/living/carbon/human/generate_icon_render_key()
|
||||
. = "[dna.species.limbs_id]"
|
||||
|
||||
if(dna.check_mutation(HULK))
|
||||
@@ -562,8 +537,6 @@ var/global/list/limb_icon_cache = list()
|
||||
. += "-coloured-[dna.species.fixed_mut_color]"
|
||||
else if(dna.features["mcolor"])
|
||||
. += "-coloured-[dna.features["mcolor"]]"
|
||||
else if(dna.features["mcolor"] && dna.species.use_skintones)
|
||||
. += "-coloured-[skin_tone]"
|
||||
else
|
||||
. += "-not_coloured"
|
||||
|
||||
@@ -572,18 +545,35 @@ var/global/list/limb_icon_cache = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
. += "-[BP.body_zone]"
|
||||
if(BP.status == ORGAN_ORGANIC)
|
||||
if(BP.status == BODYPART_ORGANIC)
|
||||
. += "-organic"
|
||||
else
|
||||
. += "-robotic"
|
||||
if(BP.use_digitigrade)
|
||||
. += "-digitigrade[BP.use_digitigrade]"
|
||||
if(BP.dmg_overlay_type)
|
||||
. += "-[BP.dmg_overlay_type]"
|
||||
|
||||
if(disabilities & HUSK)
|
||||
. += "-husk"
|
||||
|
||||
/mob/living/carbon/human/load_limb_from_cache()
|
||||
..()
|
||||
update_hair()
|
||||
|
||||
//change the human's icon to the one matching it's key
|
||||
/mob/living/carbon/human/proc/load_limb_from_cache()
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
|
||||
apply_overlay(BODYPARTS_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/update_observer_view(obj/item/I, inventory)
|
||||
if(observers && observers.len)
|
||||
for(var/M in observers)
|
||||
var/mob/dead/observe = M
|
||||
if(observe.client && observe.client.eye == src)
|
||||
if(observe.hud_used)
|
||||
if(inventory && !observe.hud_used.inventory_shown)
|
||||
continue
|
||||
observe.client.screen += I
|
||||
else
|
||||
observers -= observe
|
||||
if(!observers.len)
|
||||
observers = null
|
||||
break
|
||||
|
||||
@@ -37,12 +37,11 @@
|
||||
|
||||
// If whispering your last words, limit the whisper based on how close you are to death.
|
||||
if(critical)
|
||||
var/health_diff = round(-config.health_threshold_dead + health)
|
||||
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
|
||||
// If we cut our message short, abruptly end it with a-..
|
||||
var/message_len = length(message)
|
||||
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
|
||||
message = Ellipsis(message, 10, 1)
|
||||
whispers = "whispers in their final breath"
|
||||
|
||||
message = treat_message(message)
|
||||
|
||||
@@ -60,12 +59,13 @@
|
||||
watching -= eavesdropping
|
||||
|
||||
var/rendered
|
||||
|
||||
rendered = "<span class='game say'><span class='name'>[src.name]</span> [whispers] something.</span>"
|
||||
whispers = critical ? "whispers something in [p_their()] final breath." : "whispers something."
|
||||
rendered = "<span class='game say'><span class='name'>[src.name]</span> [whispers]</span>"
|
||||
for(var/mob/M in watching)
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
var/spans = list(SPAN_ITALICS)
|
||||
whispers = critical ? "whispers in [p_their()] final breath" : "whispers"
|
||||
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] [whispers], <span class='message'>\"[attach_spans(message, spans)]\"</span></span>"
|
||||
|
||||
for(var/atom/movable/AM in listening)
|
||||
|
||||
@@ -4,16 +4,14 @@
|
||||
return back
|
||||
if(slot_wear_mask)
|
||||
return wear_mask
|
||||
if(slot_neck)
|
||||
return wear_neck
|
||||
if(slot_head)
|
||||
return head
|
||||
if(slot_handcuffed)
|
||||
return handcuffed
|
||||
if(slot_legcuffed)
|
||||
return legcuffed
|
||||
if(slot_l_hand)
|
||||
return l_hand
|
||||
if(slot_r_hand)
|
||||
return r_hand
|
||||
return null
|
||||
|
||||
|
||||
@@ -24,19 +22,26 @@
|
||||
if(!istype(I))
|
||||
return
|
||||
|
||||
if(I == l_hand)
|
||||
l_hand = null
|
||||
else if(I == r_hand)
|
||||
r_hand = null
|
||||
var/index = get_held_index_of_item(I)
|
||||
if(index)
|
||||
held_items[index] = null
|
||||
|
||||
if(I.pulledby)
|
||||
I.pulledby.stop_pulling()
|
||||
|
||||
I.screen_loc = null // will get moved if inventory is visible
|
||||
I.screen_loc = null
|
||||
if(client)
|
||||
client.screen -= I
|
||||
if(observers && observers.len)
|
||||
for(var/M in observers)
|
||||
var/mob/dead/observe = M
|
||||
if(observe.client)
|
||||
observe.client.screen -= I
|
||||
I.loc = src
|
||||
I.equipped(src, slot)
|
||||
I.layer = ABOVE_HUD_LAYER
|
||||
|
||||
I.plane = ABOVE_HUD_PLANE
|
||||
I.appearance_flags |= NO_CLIENT_COLOR
|
||||
var/not_handled = FALSE
|
||||
switch(slot)
|
||||
if(slot_back)
|
||||
back = I
|
||||
@@ -47,25 +52,34 @@
|
||||
if(slot_head)
|
||||
head = I
|
||||
head_update(I)
|
||||
if(slot_neck)
|
||||
wear_neck = I
|
||||
update_inv_neck(I)
|
||||
if(slot_handcuffed)
|
||||
handcuffed = I
|
||||
update_handcuffed()
|
||||
if(slot_legcuffed)
|
||||
legcuffed = I
|
||||
update_inv_legcuffed()
|
||||
if(slot_l_hand)
|
||||
l_hand = I
|
||||
update_inv_l_hand()
|
||||
if(slot_r_hand)
|
||||
r_hand = I
|
||||
update_inv_r_hand()
|
||||
if(slot_hands)
|
||||
put_in_hands(I)
|
||||
update_inv_hands()
|
||||
if(slot_in_backpack)
|
||||
if(I == get_active_hand())
|
||||
unEquip(I)
|
||||
I.loc = back
|
||||
var/obj/item/weapon/storage/B = back
|
||||
var/prev_jimmies = B.rustle_jimmies
|
||||
B.rustle_jimmies = FALSE //don't conspicously rustle
|
||||
B.handle_item_insertion(I, 1, src)
|
||||
B.rustle_jimmies = prev_jimmies
|
||||
else
|
||||
return 1
|
||||
not_handled = TRUE
|
||||
|
||||
//Item has been handled at this point and equipped callback can be safely called
|
||||
//We cannot call it for items that have not been handled as they are not yet correctly
|
||||
//in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot
|
||||
if(!not_handled)
|
||||
I.equipped(src, slot)
|
||||
|
||||
return not_handled
|
||||
|
||||
/mob/living/carbon/unEquip(obj/item/I)
|
||||
. = ..() //Sets the default return value to what the parent returns.
|
||||
@@ -81,6 +95,9 @@
|
||||
else if(I == wear_mask)
|
||||
wear_mask = null
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(I == wear_neck)
|
||||
wear_neck = null
|
||||
update_inv_neck(I)
|
||||
else if(I == handcuffed)
|
||||
handcuffed = null
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
@@ -108,3 +125,4 @@
|
||||
if(I.flags_inv & HIDEMASK || forced)
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
|
||||
|
||||
@@ -4,24 +4,25 @@
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
if(!loc)
|
||||
return
|
||||
|
||||
if(damageoverlaytemp)
|
||||
damageoverlaytemp = 0
|
||||
update_damage_hud()
|
||||
|
||||
if(..())
|
||||
. = 1
|
||||
|
||||
if(..()) //not dead
|
||||
handle_blood()
|
||||
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(stat != DEAD)
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
O.on_life()
|
||||
|
||||
//Updates the number of stored chemicals for powers
|
||||
handle_changeling()
|
||||
|
||||
if(stat != DEAD)
|
||||
return 1
|
||||
|
||||
///////////////
|
||||
// BREATHING //
|
||||
///////////////
|
||||
@@ -42,15 +43,15 @@
|
||||
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
return
|
||||
|
||||
if(ismob(loc)) return
|
||||
|
||||
var/datum/gas_mixture/environment
|
||||
if(loc)
|
||||
environment = loc.return_air()
|
||||
|
||||
if(ismob(loc)) return
|
||||
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
if(health <= config.health_threshold_crit || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
|
||||
if(health <= HEALTH_THRESHOLD_CRIT || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
|
||||
losebreath++
|
||||
|
||||
//Suffocate
|
||||
@@ -284,7 +285,6 @@
|
||||
|
||||
|
||||
/mob/living/carbon/handle_stomach()
|
||||
/*
|
||||
set waitfor = 0
|
||||
for(var/mob/living/M in stomach_contents)
|
||||
if(M.loc != src)
|
||||
@@ -300,7 +300,7 @@
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
*/
|
||||
|
||||
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
|
||||
/mob/living/carbon/handle_status_effects()
|
||||
..()
|
||||
@@ -314,7 +314,7 @@
|
||||
if(sleeping)
|
||||
handle_dreams()
|
||||
AdjustSleeping(-1)
|
||||
if(prob(10) && health>config.health_threshold_crit)
|
||||
if(prob(10) && health>HEALTH_THRESHOLD_CRIT)
|
||||
emote("snore")
|
||||
|
||||
var/restingpwr = 1 + 4 * resting
|
||||
@@ -389,8 +389,6 @@
|
||||
var/body_temperature_difference = 310.15 - bodytemperature
|
||||
switch(bodytemperature)
|
||||
if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
|
||||
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
|
||||
nutrition -= 2
|
||||
bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
|
||||
if(260.15 to 310.15)
|
||||
bodytemperature += max(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, min(body_temperature_difference, BODYTEMP_AUTORECOVERY_MINIMUM/4))
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
switch(slot)
|
||||
if(slot_l_hand)
|
||||
if(l_hand)
|
||||
return 0
|
||||
return 1
|
||||
if(slot_r_hand)
|
||||
if(r_hand)
|
||||
return 0
|
||||
return 1
|
||||
if(slot_hands)
|
||||
if(get_empty_held_indexes())
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(slot_wear_mask)
|
||||
if(wear_mask)
|
||||
return 0
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_MASK) )
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(slot_neck)
|
||||
if(wear_neck)
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_NECK) )
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(slot_head)
|
||||
if(head)
|
||||
return 0
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_HEAD) )
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(slot_back)
|
||||
if(back)
|
||||
return 0
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_BACK) )
|
||||
return 0
|
||||
return 1
|
||||
return 0 //Unsupported slot
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE //Unsupported slot
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
|
||||
@@ -22,22 +22,24 @@
|
||||
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
if(!weakened)
|
||||
emote("collapse")
|
||||
Weaken(10)
|
||||
src << "<span class='danger'>You feel weak.</span>"
|
||||
emote("collapse")
|
||||
|
||||
switch(radiation)
|
||||
|
||||
if(50 to 75)
|
||||
if(prob(5))
|
||||
if(!weakened)
|
||||
emote("collapse")
|
||||
Weaken(3)
|
||||
src << "<span class='danger'>You feel weak.</span>"
|
||||
emote("collapse")
|
||||
|
||||
if(75 to 100)
|
||||
if(prob(1))
|
||||
src << "<span class='danger'>You mutate!</span>"
|
||||
randmutb(src)
|
||||
randmutb()
|
||||
emote("gasp")
|
||||
domutcheck()
|
||||
..()
|
||||
@@ -81,29 +83,29 @@
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 1)
|
||||
adjustFireLoss(2)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 2)
|
||||
adjustFireLoss(3)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
if(on_fire)
|
||||
adjustFireLoss(8)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
adjustFireLoss(3)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
|
||||
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
adjustFireLoss(0.5)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1, BURN)
|
||||
if(120 to 200)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
adjustFireLoss(1.5)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2, BURN)
|
||||
if(-INFINITY to 120)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
adjustFireLoss(3)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
@@ -140,7 +142,29 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/handle_fire()
|
||||
if(..())
|
||||
return
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
return
|
||||
. = ..()
|
||||
if(on_fire)
|
||||
|
||||
//the fire tries to damage the exposed clothes and items
|
||||
var/list/burning_items = list()
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
burning_items += head_clothes
|
||||
|
||||
if(back)
|
||||
burning_items += back
|
||||
|
||||
for(var/X in burning_items)
|
||||
var/obj/item/I = X
|
||||
if(!(I.resistance_flags & FIRE_PROOF))
|
||||
I.take_damage(fire_stacks, BURN, "fire", 0)
|
||||
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
|
||||
|
||||
@@ -3,16 +3,20 @@
|
||||
voice_name = "monkey"
|
||||
verb_say = "chimpers"
|
||||
icon = 'icons/mob/monkey.dmi'
|
||||
icon_state = "monkey1"
|
||||
icon_state = ""
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
languages_spoken = MONKEY
|
||||
languages_understood = MONKEY
|
||||
ventcrawler = 1
|
||||
ventcrawler = VENTCRAWLER_NUDE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey
|
||||
gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
unique_name = 1
|
||||
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/New()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
@@ -22,24 +26,13 @@
|
||||
gender = pick(MALE, FEMALE)
|
||||
real_name = name
|
||||
|
||||
//initialize limbs, currently only used to handle cavity implant surgery, no dismemberment.
|
||||
bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/O = X
|
||||
O.owner = src
|
||||
//initialize limbs
|
||||
create_bodyparts()
|
||||
|
||||
if(good_mutations.len) //genetic mutations have been set up.
|
||||
initialize()
|
||||
initialize() //initialize monkey dna
|
||||
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
internal_organs += new /obj/item/organ/tongue
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.Insert(src)
|
||||
create_internal_organs()
|
||||
|
||||
..()
|
||||
|
||||
@@ -47,6 +40,15 @@
|
||||
create_dna(src)
|
||||
dna.initialize_dna(random_blood_type())
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
internal_organs += new /obj/item/organ/tongue
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/movement_delay()
|
||||
if(reagents)
|
||||
if(reagents.has_reagent("morphine"))
|
||||
@@ -64,133 +66,6 @@
|
||||
. += (283.222 - bodytemperature) / 10 * 1.75
|
||||
return . + config.monkey_delay
|
||||
|
||||
/mob/living/carbon/monkey/attack_paw(mob/living/M)
|
||||
if(..()) //successful monkey bite.
|
||||
var/damage = rand(1, 5)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //To allow surgery to return properly.
|
||||
return
|
||||
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
grabbedby(M)
|
||||
if("harm")
|
||||
M.do_attack_animation(src)
|
||||
if (prob(75))
|
||||
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [name]!</span>")
|
||||
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
var/damage = rand(5, 10)
|
||||
if (prob(40))
|
||||
damage = rand(10, 15)
|
||||
if ( (paralysis < 5) && (health > 0) )
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has knocked out [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has knocked out [name]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to punch [name]!</span>")
|
||||
if("disarm")
|
||||
if (!( paralysis ))
|
||||
M.do_attack_animation(src)
|
||||
if (prob(25))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if(drop_item())
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>")
|
||||
|
||||
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent.
|
||||
if (M.a_intent == "harm")
|
||||
if ((prob(95) && health > 0))
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
var/damage = rand(15, 30)
|
||||
if (damage >= 25)
|
||||
damage = rand(20, 40)
|
||||
if (paralysis < 15)
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [name]!</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed [name]!</span>")
|
||||
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
add_logs(M, src, "attacked")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>")
|
||||
|
||||
if (M.a_intent == "disarm")
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(prob(95))
|
||||
Weaken(10)
|
||||
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [name]!</span>")
|
||||
else
|
||||
if(drop_item())
|
||||
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [name]!</span>")
|
||||
add_logs(M, src, "disarmed")
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
switch(M.melee_damage_type)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage)
|
||||
if(BURN)
|
||||
adjustFireLoss(damage)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/monkey/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
@@ -209,24 +84,6 @@
|
||||
internal = null
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/ex_act(severity, target)
|
||||
..()
|
||||
switch(severity)
|
||||
if(1)
|
||||
gib()
|
||||
return
|
||||
if(2)
|
||||
adjustBruteLoss(60)
|
||||
adjustFireLoss(60)
|
||||
adjustEarDamage(30,120)
|
||||
if(3)
|
||||
adjustBruteLoss(30)
|
||||
if (prob(50))
|
||||
Paralyse(10)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
|
||||
return 0
|
||||
@@ -249,46 +106,27 @@
|
||||
//Lasertag bullshit
|
||||
if(lasercolor)
|
||||
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
|
||||
threatcount += 4
|
||||
|
||||
if(lasercolor == "r")
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
|
||||
threatcount += 4
|
||||
|
||||
return threatcount
|
||||
|
||||
//Check for weapons
|
||||
if(judgebot.weaponscheck)
|
||||
if(judgebot.check_for_weapons(l_hand))
|
||||
threatcount += 4
|
||||
if(judgebot.check_for_weapons(r_hand))
|
||||
threatcount += 4
|
||||
for(var/obj/item/I in held_items)
|
||||
if(judgebot.check_for_weapons(I))
|
||||
threatcount += 4
|
||||
|
||||
//mindshield implants imply trustworthyness
|
||||
if(isloyal(src))
|
||||
if(isloyal())
|
||||
threatcount -= 1
|
||||
|
||||
return threatcount
|
||||
|
||||
/mob/living/carbon/monkey/acid_act(acidpwr, toxpwr, acid_volume)
|
||||
if(wear_mask)
|
||||
if(!wear_mask.unacidable)
|
||||
wear_mask.acid_act(acidpwr)
|
||||
update_inv_wear_mask()
|
||||
else
|
||||
src << "<span class='warning'>Your mask protects you from the acid.</span>"
|
||||
return
|
||||
|
||||
take_organ_damage(min(6*toxpwr, acid_volume * acidpwr/10))
|
||||
|
||||
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
|
||||
if(health < 0 && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.do_cpr(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/get_permeability_protection()
|
||||
var/protection = 0
|
||||
if(head)
|
||||
@@ -298,13 +136,6 @@
|
||||
protection = protection/7 //the rest of the body isn't covered.
|
||||
return protection
|
||||
|
||||
/mob/living/carbon/monkey/check_eye_prot()
|
||||
var/number = ..()
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/monkey/fully_heal(admin_revive = 0)
|
||||
if(!getorganslot("lungs"))
|
||||
var/obj/item/organ/lungs/L = new()
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
|
||||
/mob/living/carbon/monkey/get_eye_protection()
|
||||
var/number = ..()
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
|
||||
if(health < 0 && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.do_cpr(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/attack_paw(mob/living/M)
|
||||
if(..()) //successful monkey bite.
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
if(M.limb_destroyer)
|
||||
dismembering_strike(M, affecting.body_zone)
|
||||
if(stat != DEAD)
|
||||
var/dmg = rand(1, 5)
|
||||
apply_damage(dmg, BRUTE, affecting)
|
||||
damage_clothes(dmg, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //To allow surgery to return properly.
|
||||
return
|
||||
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
grabbedby(M)
|
||||
if("harm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
if (prob(75))
|
||||
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
var/damage = rand(5, 10)
|
||||
if (prob(40))
|
||||
damage = rand(10, 15)
|
||||
if ( (paralysis < 5) && (health > 0) )
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has knocked out [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has knocked out [name]!</span>", null, 5)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
add_logs(M, src, "attacked")
|
||||
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to punch [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if("disarm")
|
||||
if (!paralysis)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if (prob(25))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
if(drop_item())
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent.
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if ((prob(95) && health > 0))
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
var/damage = rand(15, 30)
|
||||
if (damage >= 25)
|
||||
damage = rand(20, 40)
|
||||
if (paralysis < 15)
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
add_logs(M, src, "attacked")
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful
|
||||
return 1
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if (M.a_intent == INTENT_DISARM)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(prob(95))
|
||||
Weaken(10)
|
||||
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
if(drop_item())
|
||||
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "disarmed")
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, M.melee_damage_type, affecting)
|
||||
damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit)
|
||||
. = 1
|
||||
if(!bodyzone_hit || bodyzone_hit == "head")
|
||||
if(wear_mask)
|
||||
if(!(wear_mask.resistance_flags & UNACIDABLE))
|
||||
wear_mask.acid_act(acidpwr)
|
||||
else
|
||||
src << "<span class='warning'>Your mask protects you from the acid.</span>"
|
||||
return
|
||||
if(head)
|
||||
if(!(head.resistance_flags & UNACIDABLE))
|
||||
head.acid_act(acidpwr)
|
||||
else
|
||||
src << "<span class='warning'>Your hat protects you from the acid.</span>"
|
||||
return
|
||||
take_bodypart_damage(acidpwr * min(0.6, acid_volume*0.1))
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
take_overall_damage(60, 60)
|
||||
damage_clothes(200, BRUTE, "bomb")
|
||||
adjustEarDamage(30, 120)
|
||||
if(prob(70))
|
||||
Paralyse(10)
|
||||
|
||||
if(3)
|
||||
take_overall_damage(30, 0)
|
||||
damage_clothes(50, BRUTE, "bomb")
|
||||
adjustEarDamage(15,60)
|
||||
if (prob(50))
|
||||
Paralyse(8)
|
||||
|
||||
|
||||
//attempt to dismember bodyparts
|
||||
if(severity <= 2)
|
||||
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob(50/severity) && BP.body_zone != "chest")
|
||||
BP.brute_dam = BP.max_damage
|
||||
BP.dismember()
|
||||
max_limb_loss--
|
||||
if(!max_limb_loss)
|
||||
break
|
||||
@@ -11,14 +11,10 @@
|
||||
|
||||
/mob/living/carbon/monkey/punpun/New()
|
||||
Read_Memory()
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
if(relic_mask)
|
||||
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
|
||||
if(ancestor_name)
|
||||
name = ancestor_name
|
||||
if(ancestor_chain > 1)
|
||||
name += " [num2roman(ancestor_chain)]"
|
||||
name += " \Roman[ancestor_chain]"
|
||||
else
|
||||
if(prob(5))
|
||||
name = pick(rare_pet_monkey_names)
|
||||
@@ -27,6 +23,14 @@
|
||||
gender = pick(MALE, FEMALE)
|
||||
..()
|
||||
|
||||
//These have to be after the parent new to ensure that the monkey
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//those slots
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
if(relic_mask)
|
||||
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/Life()
|
||||
if(ticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory(0)
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
|
||||
/mob/living/carbon/monkey/regenerate_icons()
|
||||
if(!..())
|
||||
update_body_parts()
|
||||
update_hair()
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
update_inv_back()
|
||||
update_icons()
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/monkey/update_icons()
|
||||
cut_overlays()
|
||||
icon_state = "monkey1"
|
||||
for(var/image/I in overlays_standing)
|
||||
add_overlay(I)
|
||||
|
||||
////////
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_hair()
|
||||
remove_overlay(HAIR_LAYER)
|
||||
|
||||
var/obj/item/bodypart/head/HD = get_bodypart("head")
|
||||
if(!HD) //Decapitated
|
||||
return
|
||||
|
||||
if(disabilities & HUSK)
|
||||
return
|
||||
|
||||
var/hair_hidden = 0
|
||||
|
||||
if(head)
|
||||
var/obj/item/I = head
|
||||
if(I.flags_inv & HIDEHAIR)
|
||||
hair_hidden = 1
|
||||
if(wear_mask)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
if(M.flags_inv & HIDEHAIR)
|
||||
hair_hidden = 1
|
||||
if(!hair_hidden)
|
||||
if(!getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
|
||||
var/image/I = image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained_s", "layer" = -HAIR_LAYER)
|
||||
overlays_standing[HAIR_LAYER] = I
|
||||
apply_overlay(HAIR_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_fire()
|
||||
..("Monkey_burning")
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_legcuffed()
|
||||
remove_overlay(LEGCUFF_LAYER)
|
||||
if(legcuffed)
|
||||
@@ -47,6 +65,12 @@
|
||||
I.screen_loc = ui_monkey_mask
|
||||
client.screen += I
|
||||
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/monkey/update_hud_neck(obj/item/I)
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
I.screen_loc = ui_monkey_mask
|
||||
client.screen += I
|
||||
|
||||
//update whether our back item appears on our hud.
|
||||
/mob/living/carbon/monkey/update_hud_back(obj/item/I)
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
|
||||
@@ -24,3 +24,7 @@
|
||||
var/obj/item/organ/tongue/T = getorganslot("tongue")
|
||||
if(T)
|
||||
. |= T.get_spans()
|
||||
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(I)
|
||||
. |= I.get_held_item_speechspans(src)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//Here are the procs used to modify status effects of a mob.
|
||||
//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
|
||||
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
|
||||
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, NEARSIGHT disability, and HUSK disability.
|
||||
|
||||
/mob/living/carbon/damage_eyes(amount)
|
||||
if(amount>0)
|
||||
@@ -76,4 +76,19 @@
|
||||
if(!(disabilities & NEARSIGHT))
|
||||
disabilities |= NEARSIGHT
|
||||
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/cure_husk()
|
||||
if(disabilities & HUSK)
|
||||
disabilities &= ~HUSK
|
||||
status_flags &= ~DISFIGURED
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/become_husk()
|
||||
if(disabilities & HUSK)
|
||||
return
|
||||
disabilities |= HUSK
|
||||
status_flags |= DISFIGURED //makes them unknown
|
||||
update_body()
|
||||
return 1
|
||||
|
||||
@@ -40,43 +40,51 @@
|
||||
overlays -= overlays_standing[cache_index]
|
||||
overlays_standing[cache_index] = null
|
||||
|
||||
/mob/living/carbon/update_inv_r_hand()
|
||||
remove_overlay(R_HAND_LAYER)
|
||||
/mob/living/carbon/regenerate_icons()
|
||||
if(notransform)
|
||||
return 1
|
||||
update_inv_hands()
|
||||
update_inv_handcuffed()
|
||||
update_inv_legcuffed()
|
||||
update_fire()
|
||||
|
||||
|
||||
/mob/living/carbon/update_inv_hands()
|
||||
remove_overlay(HANDS_LAYER)
|
||||
if (handcuffed)
|
||||
drop_r_hand()
|
||||
drop_all_held_items()
|
||||
return
|
||||
if(r_hand)
|
||||
|
||||
var/list/hands = list()
|
||||
for(var/obj/item/I in held_items)
|
||||
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
|
||||
r_hand.screen_loc = ui_rhand
|
||||
client.screen += r_hand
|
||||
I.screen_loc = ui_hand_position(get_held_index_of_item(I))
|
||||
client.screen += I
|
||||
if(observers && observers.len)
|
||||
for(var/M in observers)
|
||||
var/mob/dead/observe = M
|
||||
if(observe.client && observe.client.eye == src)
|
||||
observe.client.screen += I
|
||||
else
|
||||
observers -= observe
|
||||
if(!observers.len)
|
||||
observers = null
|
||||
break
|
||||
|
||||
var/t_state = r_hand.item_state
|
||||
var/t_state = I.item_state
|
||||
if(!t_state)
|
||||
t_state = r_hand.icon_state
|
||||
t_state = I.icon_state
|
||||
|
||||
var/image/standing = r_hand.build_worn_icon(state = t_state, default_layer = R_HAND_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
|
||||
overlays_standing[R_HAND_LAYER] = standing
|
||||
var/icon_file = I.lefthand_file
|
||||
if(get_held_index_of_item(I) % 2 == 0)
|
||||
icon_file = I.righthand_file
|
||||
|
||||
apply_overlay(R_HAND_LAYER)
|
||||
var/image/standing = I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE)
|
||||
hands += standing
|
||||
|
||||
/mob/living/carbon/update_inv_l_hand()
|
||||
remove_overlay(L_HAND_LAYER)
|
||||
if(handcuffed)
|
||||
drop_l_hand()
|
||||
return
|
||||
if(l_hand)
|
||||
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
|
||||
l_hand.screen_loc = ui_lhand
|
||||
client.screen += l_hand
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
apply_overlay(HANDS_LAYER)
|
||||
|
||||
var/t_state = l_hand.item_state
|
||||
if(!t_state)
|
||||
t_state = l_hand.icon_state
|
||||
|
||||
var/image/standing = l_hand.build_worn_icon(state = t_state, default_layer = L_HAND_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
|
||||
overlays_standing[L_HAND_LAYER] = standing
|
||||
|
||||
apply_overlay(L_HAND_LAYER)
|
||||
|
||||
/mob/living/carbon/update_fire(var/fire_icon = "Generic_mob_burning")
|
||||
remove_overlay(FIRE_LAYER)
|
||||
@@ -85,24 +93,58 @@
|
||||
|
||||
apply_overlay(FIRE_LAYER)
|
||||
|
||||
/mob/living/carbon/regenerate_icons()
|
||||
if(notransform)
|
||||
return 1
|
||||
update_inv_r_hand()
|
||||
update_inv_l_hand()
|
||||
update_inv_handcuffed()
|
||||
update_inv_legcuffed()
|
||||
update_fire()
|
||||
|
||||
|
||||
/mob/living/carbon/update_damage_overlays()
|
||||
remove_overlay(DAMAGE_LAYER)
|
||||
|
||||
var/image/standing = image("icon"='icons/mob/dam_mob.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER)
|
||||
overlays_standing[DAMAGE_LAYER] = standing
|
||||
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.dmg_overlay_type)
|
||||
if(BP.brutestate)
|
||||
standing.overlays += "[BP.dmg_overlay_type]_[BP.body_zone]_[BP.brutestate]0" //we're adding icon_states of the base image as overlays
|
||||
if(BP.burnstate)
|
||||
standing.overlays += "[BP.dmg_overlay_type]_[BP.body_zone]_0[BP.burnstate]"
|
||||
|
||||
apply_overlay(DAMAGE_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/update_inv_wear_mask()
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
if(istype(wear_mask, /obj/item/clothing/mask))
|
||||
|
||||
if(!get_bodypart("head")) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[slot_wear_mask])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_mask)
|
||||
if(!(head && (head.flags_inv & HIDEMASK)))
|
||||
var/image/standing = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi')
|
||||
overlays_standing[FACEMASK_LAYER] = standing
|
||||
update_hud_wear_mask(wear_mask)
|
||||
|
||||
apply_overlay(FACEMASK_LAYER)
|
||||
|
||||
/mob/living/carbon/update_inv_neck()
|
||||
remove_overlay(NECK_LAYER)
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[slot_neck])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_neck]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_neck)
|
||||
if(!(head && (head.flags_inv & HIDENECK)))
|
||||
var/image/standing = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi')
|
||||
overlays_standing[NECK_LAYER] = standing
|
||||
update_hud_neck(wear_neck)
|
||||
|
||||
apply_overlay(NECK_LAYER)
|
||||
|
||||
/mob/living/carbon/update_inv_back()
|
||||
remove_overlay(BACK_LAYER)
|
||||
|
||||
@@ -118,14 +160,27 @@
|
||||
|
||||
/mob/living/carbon/update_inv_head()
|
||||
remove_overlay(HEAD_LAYER)
|
||||
|
||||
if(!get_bodypart("head")) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[slot_back])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head]
|
||||
inv.update_icon()
|
||||
|
||||
if(head)
|
||||
var/image/standing = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi')
|
||||
overlays_standing[HEAD_LAYER] = standing
|
||||
update_hud_head(head)
|
||||
|
||||
apply_overlay(HEAD_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/update_inv_handcuffed()
|
||||
return
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
|
||||
//mob HUD updates for items in our inventory
|
||||
@@ -133,11 +188,10 @@
|
||||
//update whether handcuffs appears on our hud.
|
||||
/mob/living/carbon/proc/update_hud_handcuffed()
|
||||
if(hud_used)
|
||||
var/obj/screen/inventory/R = hud_used.inv_slots[slot_r_hand]
|
||||
var/obj/screen/inventory/L = hud_used.inv_slots[slot_l_hand]
|
||||
if(R && L)
|
||||
R.update_icon()
|
||||
L.update_icon()
|
||||
for(var/hand in hud_used.hand_slots)
|
||||
var/obj/screen/inventory/hand/H = hud_used.hand_slots[hand]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
|
||||
//update whether our head item appears on our hud.
|
||||
/mob/living/carbon/proc/update_hud_head(obj/item/I)
|
||||
@@ -147,17 +201,102 @@
|
||||
/mob/living/carbon/proc/update_hud_wear_mask(obj/item/I)
|
||||
return
|
||||
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/proc/update_hud_neck(obj/item/I)
|
||||
return
|
||||
|
||||
//update whether our back item appears on our hud.
|
||||
/mob/living/carbon/proc/update_hud_back(obj/item/I)
|
||||
return
|
||||
|
||||
|
||||
|
||||
//Overlays for the worn overlay so you can overlay while you overlay
|
||||
//eg: ammo counters, primed grenade flashing, etc.
|
||||
/obj/item/proc/worn_overlays(var/isinhands = FALSE)
|
||||
/obj/item/proc/worn_overlays(isinhands = FALSE)
|
||||
. = list()
|
||||
|
||||
|
||||
/mob/living/carbon/update_body()
|
||||
update_body_parts()
|
||||
|
||||
/mob/living/carbon/proc/update_body_parts()
|
||||
//CHECK FOR UPDATE
|
||||
var/oldkey = icon_render_key
|
||||
icon_render_key = generate_icon_render_key()
|
||||
if(oldkey == icon_render_key)
|
||||
return
|
||||
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.update_limb()
|
||||
|
||||
//LOAD ICONS
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
load_limb_from_cache()
|
||||
return
|
||||
|
||||
//GENERATE NEW LIMBS
|
||||
var/list/new_limbs = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
var/image/temp = BP.get_limb_icon()
|
||||
if(temp)
|
||||
new_limbs += temp
|
||||
if(new_limbs.len)
|
||||
overlays_standing[BODYPARTS_LAYER] = new_limbs
|
||||
limb_icon_cache[icon_render_key] = new_limbs
|
||||
|
||||
apply_overlay(BODYPARTS_LAYER)
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Limb Icon Cache //
|
||||
/////////////////////
|
||||
/*
|
||||
Called from update_body_parts() these procs handle the limb icon cache.
|
||||
the limb icon cache adds an icon_render_key to a human mob, it represents:
|
||||
- skin_tone (if applicable)
|
||||
- gender
|
||||
- limbs (stores as the limb name and whether it is removed/fine, organic/robotic)
|
||||
These procs only store limbs as to increase the number of matching icon_render_keys
|
||||
This cache exists because drawing 6/7 icons for humans constantly is quite a waste
|
||||
See RemieRichards on irc.rizon.net #coderbus
|
||||
*/
|
||||
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/mob/living/carbon
|
||||
var/icon_render_key = ""
|
||||
|
||||
|
||||
//produces a key based on the mob's limbs
|
||||
|
||||
/mob/living/carbon/proc/generate_icon_render_key()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
. += "-[BP.body_zone]"
|
||||
if(BP.use_digitigrade)
|
||||
. += "-digitigrade[BP.use_digitigrade]"
|
||||
if(BP.animal_origin)
|
||||
. += "-[BP.animal_origin]"
|
||||
if(BP.status == BODYPART_ORGANIC)
|
||||
. += "-organic"
|
||||
else
|
||||
. += "-robotic"
|
||||
|
||||
if(disabilities & HUSK)
|
||||
. += "-husk"
|
||||
|
||||
|
||||
//change the mob's icon to the one matching its key
|
||||
/mob/living/carbon/proc/load_limb_from_cache()
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
|
||||
apply_overlay(BODYPARTS_LAYER)
|
||||
update_damage_overlays()
|
||||
|
||||
@@ -9,23 +9,22 @@
|
||||
standard 0 if fail
|
||||
*/
|
||||
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
blocked = (100-blocked)/100
|
||||
if(!damage || (blocked <= 0))
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (hit_percent <= 0))
|
||||
return 0
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage * blocked)
|
||||
adjustBruteLoss(damage * hit_percent)
|
||||
if(BURN)
|
||||
adjustFireLoss(damage * blocked)
|
||||
adjustFireLoss(damage * hit_percent)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage * blocked)
|
||||
adjustToxLoss(damage * hit_percent)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage * blocked)
|
||||
adjustOxyLoss(damage * hit_percent)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage * blocked)
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage * blocked)
|
||||
updatehealth()
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -49,30 +48,30 @@
|
||||
|
||||
|
||||
/mob/living/proc/apply_effect(effect = 0,effecttype = STUN, blocked = 0)
|
||||
blocked = (100-blocked)/100
|
||||
if(!effect || (blocked <= 0))
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!effect || (hit_percent <= 0))
|
||||
return 0
|
||||
switch(effecttype)
|
||||
if(STUN)
|
||||
Stun(effect * blocked)
|
||||
Stun(effect * hit_percent)
|
||||
if(WEAKEN)
|
||||
Weaken(effect * blocked)
|
||||
Weaken(effect * hit_percent)
|
||||
if(PARALYZE)
|
||||
Paralyse(effect * blocked)
|
||||
Paralyse(effect * hit_percent)
|
||||
if(IRRADIATE)
|
||||
radiation += max(effect * blocked, 0)
|
||||
radiation += max(effect * hit_percent, 0)
|
||||
if(SLUR)
|
||||
slurring = max(slurring,(effect * blocked))
|
||||
slurring = max(slurring,(effect * hit_percent))
|
||||
if(STUTTER)
|
||||
if(status_flags & CANSTUN) // stun is usually associated with stutter
|
||||
stuttering = max(stuttering,(effect * blocked))
|
||||
stuttering = max(stuttering,(effect * hit_percent))
|
||||
if(EYE_BLUR)
|
||||
blur_eyes(effect * blocked)
|
||||
blur_eyes(effect * hit_percent)
|
||||
if(DROWSY)
|
||||
drowsyness = max(drowsyness,(effect * blocked))
|
||||
drowsyness = max(drowsyness,(effect * hit_percent))
|
||||
if(JITTER)
|
||||
if(status_flags & CANSTUN)
|
||||
jitteriness = max(jitteriness,(effect * blocked))
|
||||
jitteriness = max(jitteriness,(effect * hit_percent))
|
||||
return 1
|
||||
|
||||
|
||||
@@ -99,4 +98,128 @@
|
||||
apply_damage(stamina, STAMINA, null, blocked)
|
||||
if(jitter)
|
||||
apply_effect(jitter, JITTER, blocked)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/proc/getBruteLoss()
|
||||
return bruteloss
|
||||
|
||||
/mob/living/proc/adjustBruteLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
bruteloss = Clamp((bruteloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getOxyLoss()
|
||||
return oxyloss
|
||||
|
||||
/mob/living/proc/adjustOxyLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
oxyloss = Clamp((oxyloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/setOxyLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
oxyloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getToxLoss()
|
||||
return toxloss
|
||||
|
||||
/mob/living/proc/adjustToxLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
toxloss = Clamp((toxloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
/mob/living/proc/setToxLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
toxloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getFireLoss()
|
||||
return fireloss
|
||||
|
||||
/mob/living/proc/adjustFireLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
fireloss = Clamp((fireloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getCloneLoss()
|
||||
return cloneloss
|
||||
|
||||
/mob/living/proc/adjustCloneLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
cloneloss = Clamp((cloneloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/setCloneLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
cloneloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getBrainLoss()
|
||||
return brainloss
|
||||
|
||||
/mob/living/proc/adjustBrainLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
brainloss = Clamp((brainloss + (amount * config.damage_multiplier)), 0, maxHealth*2)
|
||||
|
||||
/mob/living/proc/setBrainLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
brainloss = amount
|
||||
|
||||
/mob/living/proc/getStaminaLoss()
|
||||
return staminaloss
|
||||
|
||||
/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/proc/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
|
||||
// heal ONE external organ, organ gets randomly selected from damaged ones.
|
||||
/mob/living/proc/heal_bodypart_damage(brute, burn, updating_health = 1)
|
||||
adjustBruteLoss(-brute, 0) //zero as argument for no instant health update
|
||||
adjustFireLoss(-burn, 0)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
// damage ONE external organ, organ gets randomly selected from damaged ones.
|
||||
/mob/living/proc/take_bodypart_damage(brute, burn, updating_health = 1)
|
||||
adjustBruteLoss(brute, 0) //zero as argument for no instant health update
|
||||
adjustFireLoss(burn, 0)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
// heal MANY bodyparts, in random order
|
||||
/mob/living/proc/heal_overall_damage(brute, burn, only_robotic = 0, only_organic = 1, updating_health = 1)
|
||||
adjustBruteLoss(-brute, 0) //zero as argument for no instant health update
|
||||
adjustFireLoss(-burn, 0)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/proc/take_overall_damage(brute, burn, updating_health = 1)
|
||||
adjustBruteLoss(brute, 0) //zero as argument for no instant health update
|
||||
adjustFireLoss(burn, 0)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
@@ -1,27 +1,30 @@
|
||||
/mob/living/gib(no_brain, no_organs)
|
||||
/mob/living/gib(no_brain, no_organs, no_bodyparts)
|
||||
var/prev_lying = lying
|
||||
if(stat != DEAD)
|
||||
death(1)
|
||||
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src,force=1) //to update alien nest overlay, forced because we don't exist anymore
|
||||
|
||||
if(!prev_lying)
|
||||
gib_animation()
|
||||
if(!no_organs)
|
||||
spill_organs(no_brain)
|
||||
spawn_gibs()
|
||||
|
||||
spill_organs(no_brain, no_organs, no_bodyparts)
|
||||
|
||||
if(!no_bodyparts)
|
||||
spread_bodyparts(no_brain, no_organs)
|
||||
|
||||
spawn_gibs(no_bodyparts)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/proc/gib_animation()
|
||||
return
|
||||
|
||||
/mob/living/proc/spawn_gibs()
|
||||
gibs(loc, viruses)
|
||||
new /obj/effect/gibspawner/generic(loc, viruses)
|
||||
|
||||
/mob/living/proc/spill_organs(no_brain)
|
||||
/mob/living/proc/spill_organs()
|
||||
return
|
||||
|
||||
/mob/living/proc/spread_bodyparts()
|
||||
return
|
||||
|
||||
/mob/living/dust()
|
||||
death(1)
|
||||
@@ -57,8 +60,6 @@
|
||||
living_mob_list -= src
|
||||
if(!gibbed)
|
||||
dead_mob_list += src
|
||||
else if(buckled)
|
||||
buckled.unbuckle_mob(src,force=1)
|
||||
paralysis = 0
|
||||
stunned = 0
|
||||
weakened = 0
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
|
||||
/mob/living/emote(act, m_type=1, message = null)
|
||||
if(stat)
|
||||
if(stat == DEAD && (act != "deathgasp") || (status_flags & FAKEDEATH))
|
||||
return
|
||||
|
||||
var/param = null
|
||||
@@ -19,7 +19,7 @@
|
||||
switch(act)//Hello, how would you like to order? Alphabetically!
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps its wings ANGRILY!"
|
||||
message = "<B>[src]</B> flaps [p_their()] wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if ("blush","blushes")
|
||||
@@ -51,7 +51,7 @@
|
||||
m_type = 2
|
||||
|
||||
if ("cross","crosses")
|
||||
message = "<B>[src]</B> crosses their arms."
|
||||
message = "<B>[src]</B> crosses [p_their()] arms."
|
||||
m_type = 2
|
||||
|
||||
if ("chuckle","chuckles")
|
||||
@@ -73,7 +73,7 @@
|
||||
m_type = 1
|
||||
|
||||
if ("deathgasp","deathgasps")
|
||||
message = "<B>[src]</B> seizes up and falls limp, its eyes dead and lifeless..."
|
||||
message = "<B>[src]</B> seizes up and falls limp, [p_their()] eyes dead and lifeless..."
|
||||
m_type = 1
|
||||
|
||||
if ("drool","drools")
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
if ("flap","flaps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps its wings."
|
||||
message = "<B>[src]</B> flaps [p_their()] wings."
|
||||
m_type = 2
|
||||
|
||||
if ("flip","flips")
|
||||
@@ -212,7 +212,7 @@
|
||||
if ("pout","pouts")
|
||||
message = "<B>[src]</B> pouts."
|
||||
m_type = 2
|
||||
|
||||
|
||||
if ("scream","screams")
|
||||
message = "<B>[src]</B> screams!"
|
||||
m_type = 2
|
||||
@@ -222,7 +222,7 @@
|
||||
m_type = 1
|
||||
|
||||
if ("shake","shakes")
|
||||
message = "<B>[src]</B> shakes its head."
|
||||
message = "<B>[src]</B> shakes [p_their()] head."
|
||||
m_type = 1
|
||||
|
||||
if ("sigh","sighs")
|
||||
@@ -268,7 +268,7 @@
|
||||
message = "<B>[src]</B> stares."
|
||||
|
||||
if ("stretch","stretches")
|
||||
message = "<B>[src]</B> stretches their arms."
|
||||
message = "<B>[src]</B> stretches [p_their()] arms."
|
||||
m_type = 2
|
||||
|
||||
if ("sulk","sulks")
|
||||
@@ -276,20 +276,12 @@
|
||||
m_type = 1
|
||||
|
||||
if ("surrender","surrenders")
|
||||
message = "<B>[src]</B> puts their hands on their head and falls to the ground, they surrender!"
|
||||
message = "<B>[src]</B> puts [p_their()] hands on [p_their()] head and falls to the ground, [p_they()] surrender[p_s()]!"
|
||||
if(sleeping)
|
||||
return //Can't surrender while asleep.
|
||||
Weaken(20) //So you can't resist.
|
||||
m_type = 1
|
||||
|
||||
if ("faint","faints")
|
||||
message = "<B>[src]</B> faints."
|
||||
if(sleeping)
|
||||
return //Can't faint while asleep
|
||||
SetSleeping(10) //Short-short nap
|
||||
m_type = 1
|
||||
|
||||
|
||||
if ("sway","sways")
|
||||
message = "<B>[src]</B> sways around dizzily."
|
||||
m_type = 1
|
||||
@@ -339,7 +331,7 @@
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
if(!M.client || isnewplayer(M))
|
||||
continue //skip monkeys, leavers and new players
|
||||
var/T = get_turf(src)
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T,null)))
|
||||
|
||||
@@ -8,25 +8,29 @@
|
||||
if (notransform)
|
||||
return
|
||||
if(!loc)
|
||||
return
|
||||
if(client)
|
||||
for(var/obj/effect/landmark/error/E in landmarks_list)
|
||||
loc = E.loc
|
||||
break
|
||||
message_admins("[key_name_admin(src)] was found to have no .loc with an attached client, if the cause is unknown it would be wise to ask how this was accomplished.")
|
||||
log_game("[key_name(src)] was found to have no .loc with an attached client.")
|
||||
else
|
||||
return
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
if(stat != DEAD)
|
||||
|
||||
//Breathing, if applicable
|
||||
handle_breathing()
|
||||
|
||||
if(stat != DEAD)
|
||||
//Mutations and radiation
|
||||
handle_mutations_and_radiation()
|
||||
|
||||
if(stat != DEAD)
|
||||
//Chemicals in the body
|
||||
handle_chemicals_in_body()
|
||||
|
||||
if(stat != DEAD)
|
||||
//Random events (vomiting etc)
|
||||
handle_random_events()
|
||||
|
||||
. = 1
|
||||
|
||||
//Handle temperature/pressure differences between body and environment
|
||||
if(environment)
|
||||
handle_environment(environment)
|
||||
@@ -41,12 +45,13 @@
|
||||
if(machine)
|
||||
machine.check_eye(src)
|
||||
|
||||
|
||||
if(stat != DEAD)
|
||||
handle_disabilities() // eye, ear, brain damages
|
||||
if(stat != DEAD)
|
||||
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
|
||||
|
||||
|
||||
if(stat != DEAD)
|
||||
return 1
|
||||
|
||||
/mob/living/proc/handle_breathing()
|
||||
return
|
||||
@@ -72,13 +77,30 @@
|
||||
/mob/living/proc/handle_environment(datum/gas_mixture/environment)
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_fire()
|
||||
if(fire_stacks < 0) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
fire_stacks = min(0, fire_stacks + 1)//So we dry ourselves back to default, nonflammable.
|
||||
if(!on_fire)
|
||||
return 1
|
||||
if(fire_stacks > 0)
|
||||
adjust_fire_stacks(-0.1) //the fire is slowly consumed
|
||||
else
|
||||
ExtinguishMob()
|
||||
return
|
||||
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
|
||||
if(!G.gases["o2"] || G.gases["o2"][MOLES] < 1)
|
||||
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
|
||||
return
|
||||
var/turf/location = get_turf(src)
|
||||
location.hotspot_expose(700, 50, 1)
|
||||
|
||||
/mob/living/proc/handle_stomach()
|
||||
return
|
||||
|
||||
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
|
||||
/mob/living/proc/handle_status_effects()
|
||||
if(paralysis)
|
||||
AdjustParalysis(-1)
|
||||
AdjustParalysis(-1, 1, 1)
|
||||
if(stunned)
|
||||
AdjustStunned(-1, 1, 1)
|
||||
if(weakened)
|
||||
|
||||
+183
-346
@@ -1,13 +1,3 @@
|
||||
/* I am informed this was added by Giacom to reduce mob-stacking in escape pods.
|
||||
It's sorta problematic atm due to the shuttle changes I am trying to do
|
||||
Sorry Giacom. Please don't be mad :(
|
||||
/mob/living/Life()
|
||||
..()
|
||||
var/area/A = get_area(loc)
|
||||
if(A && A.push_dir)
|
||||
push_mob_back(src, A.push_dir)
|
||||
*/
|
||||
|
||||
/mob/living/New()
|
||||
. = ..()
|
||||
generateStaticOverlay()
|
||||
@@ -37,7 +27,10 @@ Sorry Giacom. Please don't be mad :(
|
||||
med_hud_set_status()
|
||||
|
||||
/mob/living/Destroy()
|
||||
..()
|
||||
if(ranged_ability)
|
||||
ranged_ability.remove_ranged_ability(src)
|
||||
if(buckled)
|
||||
buckled.unbuckle_mob(src,force=1)
|
||||
|
||||
for(var/mob/living/simple_animal/drone/D in player_list)
|
||||
for(var/image/I in staticOverlays)
|
||||
@@ -46,7 +39,15 @@ Sorry Giacom. Please don't be mad :(
|
||||
qdel(I)
|
||||
staticOverlays.len = 0
|
||||
remove_from_all_data_huds()
|
||||
return QDEL_HINT_HARDDEL
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/ghostize(can_reenter_corpse = 1)
|
||||
var/prev_client = client
|
||||
. = ..()
|
||||
if(.)
|
||||
if(ranged_ability && prev_client)
|
||||
ranged_ability.remove_mousepointer(prev_client)
|
||||
|
||||
|
||||
/mob/living/proc/OpenCraftingMenu()
|
||||
@@ -124,10 +125,10 @@ Sorry Giacom. Please don't be mad :(
|
||||
if(!M.buckled && !M.has_buckled_mobs())
|
||||
var/mob_swap
|
||||
//the puller can always swap with its victim if on grab intent
|
||||
if(M.pulledby == src && a_intent == "grab")
|
||||
if(M.pulledby == src && a_intent == INTENT_GRAB)
|
||||
mob_swap = 1
|
||||
//restrained people act if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
|
||||
else if((M.restrained() || M.a_intent == "help") && (restrained() || a_intent == "help"))
|
||||
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
|
||||
mob_swap = 1
|
||||
if(mob_swap)
|
||||
//switch our position with M
|
||||
@@ -159,10 +160,10 @@ Sorry Giacom. Please don't be mad :(
|
||||
if(!(M.status_flags & CANPUSH))
|
||||
return 1
|
||||
//anti-riot equipment is also anti-push
|
||||
if(M.r_hand && (prob(M.r_hand.block_chance * 2)) && !istype(M.r_hand, /obj/item/clothing))
|
||||
return 1
|
||||
if(M.l_hand && (prob(M.l_hand.block_chance * 2)) && !istype(M.l_hand, /obj/item/clothing))
|
||||
return 1
|
||||
for(var/obj/item/I in M.held_items)
|
||||
if(!istype(M, /obj/item/clothing))
|
||||
if(prob(I.block_chance*2))
|
||||
return 1
|
||||
|
||||
//Called when we bump onto an obj
|
||||
/mob/living/proc/ObjBump(obj/O)
|
||||
@@ -216,26 +217,19 @@ Sorry Giacom. Please don't be mad :(
|
||||
set hidden = 1
|
||||
if (InCritical())
|
||||
src.attack_log += "[src] has [whispered ? "whispered his final words" : "succumbed to death"] with [round(health, 0.1)] points of health!"
|
||||
src.adjustOxyLoss(src.health - config.health_threshold_dead)
|
||||
src.adjustOxyLoss(src.health - HEALTH_THRESHOLD_DEAD)
|
||||
updatehealth()
|
||||
if(!whispered)
|
||||
src << "<span class='notice'>You have given up life and succumbed to death.</span>"
|
||||
death()
|
||||
|
||||
/mob/living/incapacitated(ignore_restraints, ignore_grab)
|
||||
if(stat || paralysis || stunned || weakened || (!ignore_restraints && restrained(ignore_grab)))
|
||||
return 1
|
||||
|
||||
/mob/living/proc/InCritical()
|
||||
return (src.health < 0 && src.health > -95 && stat == UNCONSCIOUS)
|
||||
|
||||
/mob/living/ex_act(severity, target)
|
||||
..()
|
||||
flash_eyes()
|
||||
|
||||
/mob/living/proc/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
|
||||
update_stat()
|
||||
med_hud_set_health()
|
||||
|
||||
//This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually
|
||||
//affects them once clothing is factored in. ~Errorage
|
||||
/mob/living/proc/calculate_affecting_pressure(pressure)
|
||||
@@ -258,125 +252,9 @@ Sorry Giacom. Please don't be mad :(
|
||||
temperature -= change
|
||||
if(actual < desired)
|
||||
temperature = desired
|
||||
// if(istype(src, /mob/living/carbon/human))
|
||||
// world << "[src] ~ [src.bodytemperature] ~ [temperature]"
|
||||
return temperature
|
||||
|
||||
|
||||
// MOB PROCS
|
||||
/mob/living/proc/getBruteLoss()
|
||||
return bruteloss
|
||||
|
||||
/mob/living/proc/adjustBruteLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
bruteloss = Clamp(bruteloss + amount, 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getOxyLoss()
|
||||
return oxyloss
|
||||
|
||||
/mob/living/proc/adjustOxyLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
oxyloss = Clamp(oxyloss + amount, 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/setOxyLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
oxyloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getToxLoss()
|
||||
return toxloss
|
||||
|
||||
/mob/living/proc/adjustToxLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
toxloss = Clamp(toxloss + amount, 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
/mob/living/proc/setToxLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
toxloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getFireLoss()
|
||||
return fireloss
|
||||
|
||||
/mob/living/proc/adjustFireLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
fireloss = Clamp(fireloss + amount, 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getCloneLoss()
|
||||
return cloneloss
|
||||
|
||||
/mob/living/proc/adjustCloneLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
cloneloss = Clamp(cloneloss + amount, 0, maxHealth*2)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/setCloneLoss(amount, updating_health=1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
cloneloss = amount
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/getBrainLoss()
|
||||
return brainloss
|
||||
|
||||
/mob/living/proc/adjustBrainLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
brainloss = Clamp(brainloss + amount, 0, maxHealth*2)
|
||||
|
||||
/mob/living/proc/setBrainLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
brainloss = amount
|
||||
|
||||
/mob/living/proc/getStaminaLoss()
|
||||
return staminaloss
|
||||
|
||||
/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
staminaloss = Clamp(staminaloss + amount, 0, maxHealth*2)
|
||||
if(updating_stamina)
|
||||
update_stamina()
|
||||
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/proc/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/setStaminaLoss(amount, updating_stamina = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
staminaloss = amount
|
||||
if(updating_stamina)
|
||||
update_stamina()
|
||||
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/proc/getMaxHealth()
|
||||
return maxHealth
|
||||
@@ -433,16 +311,6 @@ Sorry Giacom. Please don't be mad :(
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0)
|
||||
return 0 //only carbon liveforms have this proc
|
||||
|
||||
/mob/living/emp_act(severity)
|
||||
var/list/L = src.get_contents()
|
||||
for(var/obj/O in L)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/proc/can_inject()
|
||||
return 1
|
||||
|
||||
@@ -454,33 +322,14 @@ Sorry Giacom. Please don't be mad :(
|
||||
var/def_zone = ran_zone(t)
|
||||
return def_zone
|
||||
|
||||
// heal ONE external organ, organ gets randomly selected from damaged ones.
|
||||
/mob/living/proc/heal_organ_damage(brute, burn, updating_health=1)
|
||||
adjustBruteLoss(-brute, updating_health)
|
||||
adjustFireLoss(-burn, updating_health)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
// damage ONE external organ, organ gets randomly selected from damaged ones.
|
||||
/mob/living/proc/take_organ_damage(brute, burn, updating_health=1)
|
||||
adjustBruteLoss(brute)
|
||||
adjustFireLoss(burn)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
// heal MANY bodyparts, in random order
|
||||
/mob/living/proc/heal_overall_damage(brute, burn, updating_health=1)
|
||||
adjustBruteLoss(-brute, updating_health)
|
||||
adjustFireLoss(-burn, updating_health)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/proc/take_overall_damage(brute, burn, updating_health=1)
|
||||
adjustBruteLoss(brute, updating_health)
|
||||
adjustFireLoss(burn, updating_health)
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
/mob/living/proc/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
|
||||
update_stat()
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
|
||||
//proc used to ressuscitate a mob
|
||||
/mob/living/proc/revive(full_heal = 0, admin_revive = 0)
|
||||
@@ -501,7 +350,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
//proc used to completely heal a mob.
|
||||
/mob/living/proc/fully_heal(admin_revive = 0)
|
||||
restore_blood()
|
||||
setToxLoss(0, 0)
|
||||
setToxLoss(0, 0) //zero as second argument not automatically call updatehealth().
|
||||
setOxyLoss(0, 0)
|
||||
setCloneLoss(0, 0)
|
||||
setBrainLoss(0)
|
||||
@@ -518,26 +367,26 @@ Sorry Giacom. Please don't be mad :(
|
||||
set_eye_damage(0)
|
||||
cure_nearsighted()
|
||||
cure_blind()
|
||||
cure_husk()
|
||||
disabilities = 0
|
||||
ear_deaf = 0
|
||||
ear_damage = 0
|
||||
hallucination = 0
|
||||
heal_overall_damage(100000, 100000)
|
||||
heal_overall_damage(100000, 100000, 0, 0, 1) //heal brute and burn dmg on both organic and robotic limbs, and update health right away.
|
||||
ExtinguishMob()
|
||||
fire_stacks = 0
|
||||
updatehealth()
|
||||
update_canmove()
|
||||
|
||||
|
||||
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
|
||||
/mob/living/proc/can_be_revived()
|
||||
. = 1
|
||||
if(health <= config.health_threshold_dead)
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
return 0
|
||||
|
||||
/mob/living/proc/update_damage_overlays()
|
||||
return
|
||||
/*
|
||||
|
||||
/mob/living/proc/Examine_OOC()
|
||||
set name = "Examine Meta-Info (OOC)"
|
||||
set category = "OOC"
|
||||
@@ -552,7 +401,6 @@ Sorry Giacom. Please don't be mad :(
|
||||
src << "OOC Metadata is not supported by this server!"
|
||||
|
||||
return
|
||||
*/
|
||||
|
||||
/mob/living/Move(atom/newloc, direct)
|
||||
if (buckled && buckled.loc != newloc) //not updating position
|
||||
@@ -587,25 +435,27 @@ Sorry Giacom. Please don't be mad :(
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if (s_active && !(s_active in contents) && !(s_active.loc in contents))
|
||||
// It's ugly. But everything related to inventory/storage is. -- c0
|
||||
if (s_active && !(s_active.ClickAccessible(src, depth=STORAGE_VIEW_DEPTH) || s_active.Adjacent(src)))
|
||||
s_active.close(src)
|
||||
|
||||
/mob/living/movement_delay()
|
||||
/mob/living/movement_delay(ignorewalk = 0)
|
||||
. = ..()
|
||||
if(isturf(loc, /turf/open))
|
||||
if(isopenturf(loc) && !is_flying())
|
||||
var/turf/open/T = loc
|
||||
. += T.slowdown
|
||||
switch(m_intent)
|
||||
if("run")
|
||||
if(drowsyness > 0)
|
||||
. += 6
|
||||
. += config.run_speed
|
||||
if("walk")
|
||||
. += config.walk_speed
|
||||
if(ignorewalk)
|
||||
. += config.run_speed
|
||||
else
|
||||
switch(m_intent)
|
||||
if(MOVE_INTENT_RUN)
|
||||
if(drowsyness > 0)
|
||||
. += 6
|
||||
. += config.run_speed
|
||||
if(MOVE_INTENT_WALK)
|
||||
. += config.walk_speed
|
||||
|
||||
/mob/living/proc/makeTrail(turf/T)
|
||||
if(!has_gravity(src))
|
||||
if(!has_gravity())
|
||||
return
|
||||
var/blood_exists = 0
|
||||
|
||||
@@ -635,30 +485,42 @@ Sorry Giacom. Please don't be mad :(
|
||||
TH.transfer_mob_blood_dna(src)
|
||||
|
||||
/mob/living/carbon/human/makeTrail(turf/T)
|
||||
if((NOBLOOD in dna.species.specflags) || !bleed_rate || bleedsuppress)
|
||||
if((NOBLOOD in dna.species.species_traits) || !bleed_rate || bleedsuppress)
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/proc/getTrail()
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/species = H.dna.species.id
|
||||
if(species == "xeno") //Here we can define custom blood trails for different species; copy+paste the xenos species to add new ones.
|
||||
if(getBruteLoss() < 300)
|
||||
return pick (list("xltrails_1", "xltrails2"))
|
||||
else
|
||||
return pick (list("xttrails_1", "xttrails2"))
|
||||
else
|
||||
if(getBruteLoss() < 300)
|
||||
return pick("ltrails_1", "ltrails_2")
|
||||
else
|
||||
return pick("trails_1", "trails_2")
|
||||
|
||||
if(getBruteLoss() < 300)
|
||||
return pick("ltrails_1", "ltrails_2")
|
||||
else
|
||||
if(getBruteLoss() < 300)
|
||||
return pick("ltrails_1", "ltrails_2")
|
||||
else
|
||||
return pick("trails_1", "trails_2")
|
||||
return pick("trails_1", "trails_2")
|
||||
|
||||
/mob/living/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0)
|
||||
if (client && client.move_delay >= world.time + world.tick_lag*2)
|
||||
pressure_resistance_prob_delta -= 30
|
||||
|
||||
var/list/turfs_to_check = list()
|
||||
|
||||
if (has_limbs)
|
||||
var/turf/T = get_step(src, angle2dir(dir2angle(direction)+90))
|
||||
if (T)
|
||||
turfs_to_check += T
|
||||
|
||||
T = get_step(src, angle2dir(dir2angle(direction)-90))
|
||||
if (T)
|
||||
turfs_to_check += T
|
||||
|
||||
for (var/t in turfs_to_check)
|
||||
T = t
|
||||
if (T.density)
|
||||
pressure_resistance_prob_delta -= 20
|
||||
continue
|
||||
for (var/atom/movable/AM in T)
|
||||
if (AM.density && AM.anchored)
|
||||
pressure_resistance_prob_delta -= 20
|
||||
break
|
||||
if(!slipping)
|
||||
..(pressure_difference, direction, pressure_resistance_prob_delta)
|
||||
|
||||
/mob/living/verb/resist()
|
||||
set name = "Resist"
|
||||
@@ -683,6 +545,14 @@ Sorry Giacom. Please don't be mad :(
|
||||
var/obj/C = loc
|
||||
C.container_resist(src)
|
||||
|
||||
else if(has_status_effect(/datum/status_effect/freon))
|
||||
src << "You start breaking out of the ice cube!"
|
||||
if(do_mob(src, src, 40))
|
||||
if(has_status_effect(/datum/status_effect/freon))
|
||||
src << "You break out of the ice cube!"
|
||||
remove_status_effect(/datum/status_effect/freon)
|
||||
update_canmove()
|
||||
|
||||
else if(canmove)
|
||||
if(on_fire)
|
||||
resist_fire() //stop, drop, and roll
|
||||
@@ -736,26 +606,13 @@ Sorry Giacom. Please don't be mad :(
|
||||
fixed = 1
|
||||
if(on && !floating && !fixed)
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
floating = 1
|
||||
else if(((!on || fixed) && floating))
|
||||
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
|
||||
floating = 0
|
||||
|
||||
//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)))
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(src, "clear_fullscreen", 25, FALSE, "flash", 25)
|
||||
return 1
|
||||
|
||||
//this returns the mob's protection against eye damage (number between -1 and 2)
|
||||
/mob/living/proc/check_eye_prot()
|
||||
return 0
|
||||
|
||||
//this returns the mob's protection against ear damage (0 or 1)
|
||||
/mob/living/proc/check_ear_prot()
|
||||
return 0
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
|
||||
/mob/living/stripPanelUnequip(obj/item/what, mob/who, where)
|
||||
@@ -766,33 +623,44 @@ Sorry Giacom. Please don't be mad :(
|
||||
"<span class='userdanger'>[src] tries to remove [who]'s [what.name].</span>")
|
||||
what.add_fingerprint(src)
|
||||
if(do_mob(src, who, what.strip_delay))
|
||||
if(what && what == who.get_item_by_slot(where) && Adjacent(who))
|
||||
who.unEquip(what)
|
||||
add_logs(src, who, "stripped", addition="of [what]")
|
||||
if(what && Adjacent(who))
|
||||
if(islist(where))
|
||||
var/list/L = where
|
||||
if(what == who.get_item_for_held_index(L[2]))
|
||||
who.unEquip(what)
|
||||
add_logs(src, who, "stripped", addition="of [what]")
|
||||
if(what == who.get_item_by_slot(where))
|
||||
who.unEquip(what)
|
||||
add_logs(src, who, "stripped", addition="of [what]")
|
||||
|
||||
// The src mob is trying to place an item on someone
|
||||
// Override if a certain mob should be behave differently when placing items (can't, for example)
|
||||
/mob/living/stripPanelEquip(obj/item/what, mob/who, where)
|
||||
what = src.get_active_hand()
|
||||
what = src.get_active_held_item()
|
||||
if(what && (what.flags & NODROP))
|
||||
src << "<span class='warning'>You can't put \the [what.name] on [who], it's stuck to your hand!</span>"
|
||||
return
|
||||
if(what)
|
||||
if(!what.mob_can_equip(who, where, 1))
|
||||
src << "<span class='warning'>\The [what.name] doesn't fit in that place!</span>"
|
||||
return
|
||||
var/list/where_list
|
||||
if(islist(where))
|
||||
where_list = where
|
||||
if(!what.mob_can_equip(who, src, where[1], 1))
|
||||
src << "<span class='warning'>\The [what.name] doesn't fit in that place!</span>"
|
||||
return
|
||||
else
|
||||
if(!what.mob_can_equip(who, src, where, 1))
|
||||
src << "<span class='warning'>\The [what.name] doesn't fit in that place!</span>"
|
||||
return
|
||||
visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>")
|
||||
if(do_mob(src, who, what.put_on_delay))
|
||||
if(what && Adjacent(who))
|
||||
unEquip(what)
|
||||
who.equip_to_slot_if_possible(what, where, 0, 1)
|
||||
if(where_list)
|
||||
who.put_in_hand(what, where_list[2])
|
||||
else
|
||||
who.equip_to_slot_if_possible(what, where, 0, 1)
|
||||
add_logs(src, who, "equipped", what)
|
||||
|
||||
/mob/living/singularity_act()
|
||||
var/gain = 20
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/singularity_pull(S, current_size)
|
||||
if(current_size >= STAGE_SIX)
|
||||
@@ -800,97 +668,6 @@ Sorry Giacom. Please don't be mad :(
|
||||
else
|
||||
step_towards(src,S)
|
||||
|
||||
/mob/living/narsie_act()
|
||||
if(is_servant_of_ratvar(src) && !stat)
|
||||
src << "<span class='userdanger'>You resist Nar-Sie's influence... but not all of it. <i>Run!</i></span>"
|
||||
adjustBruteLoss(35)
|
||||
if(src && reagents)
|
||||
reagents.add_reagent("heparin", 5)
|
||||
return 0
|
||||
if(client)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, null, 0)
|
||||
else
|
||||
new /mob/living/simple_animal/hostile/construct/harvester/hostile(get_turf(src))
|
||||
spawn_dust()
|
||||
gib()
|
||||
return
|
||||
|
||||
/mob/living/ratvar_act()
|
||||
if(!add_servant_of_ratvar(src) && !is_servant_of_ratvar(src))
|
||||
src << "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>"
|
||||
adjustFireLoss(35)
|
||||
if(src)
|
||||
adjust_fire_stacks(1)
|
||||
IgniteMob()
|
||||
|
||||
/atom/movable/proc/do_attack_animation(atom/A, final_pixel_y, final_pixel_x)
|
||||
var/pixel_x_diff = 0
|
||||
var/pixel_y_diff = 0
|
||||
if(!final_pixel_y)
|
||||
final_pixel_y = initial(pixel_y)
|
||||
|
||||
if(!final_pixel_x)
|
||||
final_pixel_x = initial(pixel_x) //lol copypasta
|
||||
|
||||
var/direction = get_dir(src, A)
|
||||
if(direction & NORTH)
|
||||
pixel_y_diff = 8
|
||||
else if(direction & SOUTH)
|
||||
pixel_y_diff = -8
|
||||
|
||||
if(direction & EAST)
|
||||
pixel_x_diff = 8
|
||||
else if(direction & WEST)
|
||||
pixel_x_diff = -8
|
||||
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
|
||||
//animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2)
|
||||
animate(pixel_x = pixel_x - pixel_x_diff, pixel_y = final_pixel_y, time = 2) //Why reset when you can just reverse? 99% less shit-breaking.
|
||||
|
||||
/mob/living/do_attack_animation(atom/A)
|
||||
var/final_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
..(A, final_pixel_y)
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
|
||||
// What icon do we use for the attack?
|
||||
var/image/I
|
||||
if(hand && l_hand) // Attacked with item in left hand.
|
||||
I = image(l_hand.icon, A, l_hand.icon_state, A.layer + 0.1)
|
||||
else if(!hand && r_hand) // Attacked with item in right hand.
|
||||
I = image(r_hand.icon, A, r_hand.icon_state, A.layer + 0.1)
|
||||
else // Attacked with a fist?
|
||||
return
|
||||
|
||||
// Who can see the attack?
|
||||
var/list/viewing = list()
|
||||
for(var/mob/M in viewers(A))
|
||||
if(M.client)
|
||||
viewing |= M.client
|
||||
flick_overlay(I, viewing, 5) // 5 ticks/half a second
|
||||
|
||||
// Scale the icon.
|
||||
I.transform *= 0.75
|
||||
// The icon should not rotate.
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
|
||||
// Set the direction of the icon animation.
|
||||
var/direction = get_dir(src, A)
|
||||
if(direction & NORTH)
|
||||
I.pixel_y = -16
|
||||
else if(direction & SOUTH)
|
||||
I.pixel_y = 16
|
||||
|
||||
if(direction & EAST)
|
||||
I.pixel_x = -16
|
||||
else if(direction & WEST)
|
||||
I.pixel_x = 16
|
||||
|
||||
if(!direction) // Attacked self?!
|
||||
I.pixel_z = 16
|
||||
|
||||
// And animate the attack!
|
||||
animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3)
|
||||
|
||||
/mob/living/proc/do_jitter_animation(jitteriness)
|
||||
var/amplitude = min(4, (jitteriness/100) + 1)
|
||||
var/pixel_x_diff = rand(-amplitude, amplitude)
|
||||
@@ -910,7 +687,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
else if(istype(loc, /obj/structure/transit_tube_pod))
|
||||
loc_temp = environment.temperature
|
||||
|
||||
else if(istype(get_turf(src), /turf/open/space))
|
||||
else if(isspaceturf(get_turf(src)))
|
||||
var/turf/heat_turf = get_turf(src)
|
||||
loc_temp = heat_turf.temperature
|
||||
|
||||
@@ -936,12 +713,16 @@ Sorry Giacom. Please don't be mad :(
|
||||
|
||||
/mob/living/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
if(ticker)
|
||||
if(ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(ticker && ticker.mode)
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(G.is_dominating)
|
||||
stat(null, "[G.name] Gang Takeover: [max(G.domination_time_remaining(), 0)]")
|
||||
if(istype(ticker.mode, /datum/game_mode/blob))
|
||||
var/datum/game_mode/blob/B = ticker.mode
|
||||
if(B.message_sent)
|
||||
stat(null, "Blobs to Blob Win: [blobs_legit.len]/[B.blobwincount]")
|
||||
|
||||
/mob/living/cancel_camera()
|
||||
..()
|
||||
@@ -982,7 +763,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
new path(src.loc)
|
||||
butcher_results.Remove(path) //In case you want to have things like simple_animals drop their butcher results on gib, so it won't double up below.
|
||||
visible_message("<span class='notice'>[user] butchers [src].</span>")
|
||||
gib()
|
||||
gib(0, 0, 1)
|
||||
|
||||
/mob/living/canUseTopic(atom/movable/M, be_close = 0, no_dextery = 0)
|
||||
if(incapacitated())
|
||||
@@ -1005,7 +786,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
/mob/living/carbon/human/update_stamina()
|
||||
if(staminaloss)
|
||||
var/total_health = (health - staminaloss)
|
||||
if(total_health <= config.health_threshold_crit && !stat)
|
||||
if(total_health <= HEALTH_THRESHOLD_CRIT && !stat)
|
||||
src << "<span class='notice'>You're too exhausted to keep going...</span>"
|
||||
Weaken(5)
|
||||
setStaminaLoss(health - 2)
|
||||
@@ -1020,7 +801,10 @@ Sorry Giacom. Please don't be mad :(
|
||||
return 1
|
||||
|
||||
/mob/living/proc/return_soul()
|
||||
hellbound = 0
|
||||
if(mind)
|
||||
if(mind.soulOwner.devilinfo)//Not sure how this could happen, but whatever.
|
||||
mind.soulOwner.devilinfo.remove_soul(mind)
|
||||
mind.soulOwner = mind
|
||||
|
||||
/mob/living/proc/has_bane(banetype)
|
||||
@@ -1061,3 +845,56 @@ Sorry Giacom. Please don't be mad :(
|
||||
G.Recall()
|
||||
G << "<span class='holoparasite'>Your summoner has changed \
|
||||
form!</span>"
|
||||
|
||||
/mob/living/proc/fakefireextinguish()
|
||||
return
|
||||
|
||||
/mob/living/proc/fakefire()
|
||||
return
|
||||
|
||||
|
||||
|
||||
//Mobs on Fire
|
||||
/mob/living/proc/IgniteMob()
|
||||
if(fire_stacks > 0 && !on_fire)
|
||||
on_fire = 1
|
||||
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
|
||||
"<span class='userdanger'>You're set on fire!</span>")
|
||||
src.AddLuminosity(3)
|
||||
throw_alert("fire", /obj/screen/alert/fire)
|
||||
update_fire()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/ExtinguishMob()
|
||||
if(on_fire)
|
||||
on_fire = 0
|
||||
fire_stacks = 0
|
||||
src.AddLuminosity(-3)
|
||||
clear_alert("fire")
|
||||
update_fire()
|
||||
|
||||
/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)
|
||||
if(on_fire && fire_stacks <= 0)
|
||||
ExtinguishMob()
|
||||
|
||||
//Share fire evenly between the two mobs
|
||||
//Called in MobBump() and Crossed()
|
||||
/mob/living/proc/spreadFire(mob/living/L)
|
||||
if(!istype(L))
|
||||
return
|
||||
var/L_old_on_fire = L.on_fire
|
||||
|
||||
if(on_fire) //Only spread fire stacks if we're on fire
|
||||
fire_stacks /= 2
|
||||
L.fire_stacks += fire_stacks
|
||||
if(L.IgniteMob())
|
||||
log_game("[key_name(src)] bumped into [key_name(L)] and set them on fire")
|
||||
|
||||
if(L_old_on_fire) //Only ignite us and gain their stacks if they were onfire before we bumped them
|
||||
L.fire_stacks /= 2
|
||||
fire_stacks += L.fire_stacks
|
||||
IgniteMob()
|
||||
|
||||
//Mobs on Fire end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
|
||||
var/armor = getarmor(def_zone, attack_flag)
|
||||
|
||||
@@ -24,22 +25,33 @@
|
||||
/mob/living/proc/getarmor(def_zone, type)
|
||||
return 0
|
||||
|
||||
/mob/living/proc/on_hit(obj/item/projectile/proj_type)
|
||||
//this returns the mob's protection against eye damage (number between -1 and 2)
|
||||
/mob/living/proc/get_eye_protection()
|
||||
return 0
|
||||
|
||||
//this returns the mob's protection against ear damage (0:no protection; 1: some ear protection; 2: has no ears)
|
||||
/mob/living/proc/get_ear_protection()
|
||||
return 0
|
||||
|
||||
/mob/living/proc/on_hit(obj/item/projectile/P)
|
||||
return
|
||||
|
||||
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
|
||||
var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
|
||||
if(!P.nodamage)
|
||||
apply_damage(P.damage, P.damage_type, def_zone, armor)
|
||||
return P.on_hit(src, armor, def_zone)
|
||||
if(P.dismemberment)
|
||||
check_projectile_dismemberment(P, def_zone)
|
||||
return P.on_hit(src, armor)
|
||||
|
||||
/proc/vol_by_throwforce_and_or_w_class(obj/item/I)
|
||||
if(!I)
|
||||
return 0
|
||||
if(I.throwforce && I.w_class)
|
||||
return Clamp((I.throwforce + I.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(I.w_class)
|
||||
return Clamp(I.w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
|
||||
/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
return 0
|
||||
|
||||
/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
|
||||
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
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -48,7 +60,7 @@
|
||||
var/obj/item/I = AM
|
||||
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
|
||||
var/dtype = BRUTE
|
||||
var/volume = vol_by_throwforce_and_or_w_class(I)
|
||||
var/volume = I.get_volume_by_throwforce_and_or_w_class()
|
||||
if(istype(I,/obj/item/weapon)) //If the item is a weapon...
|
||||
var/obj/item/weapon/W = I
|
||||
dtype = W.damtype
|
||||
@@ -69,155 +81,48 @@
|
||||
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
|
||||
"<span class='userdanger'>[src] has been hit by [I].</span>")
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, zone, armor, I)
|
||||
apply_damage(I.throwforce, dtype, zone, armor)
|
||||
if(I.thrownby)
|
||||
add_logs(I.thrownby, src, "hit", I)
|
||||
else
|
||||
return 1
|
||||
else
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == "harm")
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(BRUTE)
|
||||
Paralyse(1)
|
||||
take_overall_damage(rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if("fire")
|
||||
if(BURN)
|
||||
take_overall_damage(0, rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
if("tox")
|
||||
if(TOX)
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
updatehealth()
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>")
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
else
|
||||
step_away(src,M)
|
||||
add_logs(M.occupant, src, "pushed", M)
|
||||
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>")
|
||||
|
||||
|
||||
//Mobs on Fire
|
||||
/mob/living/proc/IgniteMob()
|
||||
if(fire_stacks > 0 && !on_fire)
|
||||
on_fire = 1
|
||||
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
|
||||
"<span class='userdanger'>You're set on fire!</span>")
|
||||
src.set_light(light_range + 3)
|
||||
throw_alert("fire", /obj/screen/alert/fire)
|
||||
update_fire()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/ExtinguishMob()
|
||||
if(on_fire)
|
||||
on_fire = 0
|
||||
fire_stacks = 0
|
||||
src.set_light(light_range - 3)
|
||||
clear_alert("fire")
|
||||
update_fire()
|
||||
|
||||
/mob/living/proc/update_fire()
|
||||
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)
|
||||
if(on_fire && fire_stacks <= 0)
|
||||
ExtinguishMob()
|
||||
|
||||
/mob/living/proc/handle_fire()
|
||||
if(fire_stacks < 0) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
fire_stacks = min(0, fire_stacks + 1)//So we dry ourselves back to default, nonflammable.
|
||||
if(!on_fire)
|
||||
return 1
|
||||
if(fire_stacks > 0)
|
||||
adjust_fire_stacks(-0.1) //the fire is slowly consumed
|
||||
else
|
||||
ExtinguishMob()
|
||||
return
|
||||
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
|
||||
if(!G.gases["o2"] || G.gases["o2"][MOLES] < 1)
|
||||
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
|
||||
return
|
||||
var/turf/location = get_turf(src)
|
||||
location.hotspot_expose(700, 50, 1)
|
||||
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", null, null, 5)
|
||||
|
||||
/mob/living/fire_act()
|
||||
adjust_fire_stacks(3)
|
||||
IgniteMob()
|
||||
|
||||
|
||||
//Share fire evenly between the two mobs
|
||||
//Called in MobBump() and Crossed()
|
||||
/mob/living/proc/spreadFire(mob/living/L)
|
||||
if(!istype(L))
|
||||
return
|
||||
var/L_old_on_fire = L.on_fire
|
||||
|
||||
if(on_fire) //Only spread fire stacks if we're on fire
|
||||
fire_stacks /= 2
|
||||
L.fire_stacks += fire_stacks
|
||||
if(L.IgniteMob())
|
||||
log_game("[key_name(src)] bumped into [key_name(L)] and set them on fire")
|
||||
|
||||
if(L_old_on_fire) //Only ignite us and gain their stacks if they were onfire before we bumped them
|
||||
L.fire_stacks /= 2
|
||||
fire_stacks += L.fire_stacks
|
||||
IgniteMob()
|
||||
|
||||
//Mobs on Fire end
|
||||
|
||||
/mob/living/proc/dominate_mind(mob/living/target, duration = 100, silent) //Allows one mob to assume control of another while imprisoning the old consciousness for a time
|
||||
if(!target)
|
||||
return 0
|
||||
if(target.mental_dominator)
|
||||
src << "<span class='warning'>[target] is already being controlled by someone else!</span>"
|
||||
return 0
|
||||
if(!target.mind)
|
||||
src << "<span class='warning'>[target] is mindless and would make you permanently catatonic!</span>"
|
||||
return 0
|
||||
if(!silent)
|
||||
src << "<span class='userdanger'>You pounce upon [target]'s mind and seize control of their body!</span>"
|
||||
target << "<span class='userdanger'>Your control over your body is wrenched away from you!</span>"
|
||||
target.mind_control_holder = new/mob/living/mind_control_holder(target)
|
||||
target.mind_control_holder.real_name = "imprisoned mind of [target.real_name]"
|
||||
target.mind.transfer_to(target.mind_control_holder)
|
||||
mind.transfer_to(target)
|
||||
target.mental_dominator = src
|
||||
spawn(duration)
|
||||
if(!src)
|
||||
if(!silent)
|
||||
target << "<span class='userdanger'>You try to return to your own body, but sense nothing! You're being forced out!</span>"
|
||||
target.ghostize(1)
|
||||
target.mind_control_holder.mind.transfer_to(target)
|
||||
if(!silent)
|
||||
target << "<span class='userdanger'>You take control of your own body again!</span>"
|
||||
return 0
|
||||
if(!silent)
|
||||
target << "<span class='userdanger'>You're forced out! You return to your own body.</span>"
|
||||
target.mind.transfer_to(src)
|
||||
target.mind_control_holder.mind.transfer_to(target)
|
||||
qdel(mind_control_holder)
|
||||
if(!silent)
|
||||
target << "<span class='userdanger'>You take control of your own body again!</span>"
|
||||
return 1
|
||||
|
||||
/mob/living/acid_act(acidpwr, toxpwr, acid_volume)
|
||||
take_organ_damage(min(10*toxpwr, acid_volume * toxpwr))
|
||||
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, mob/living/target, supress_message = 0)
|
||||
|
||||
// if(grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling) && user.zone_selected == "mouth")
|
||||
// src.vore_attack(src, devour_time = 100) //It would be better to define it on this level instead of human_defense.dm, but you'd probably need to do more work down the line. ex: xeno devour code
|
||||
// return
|
||||
|
||||
if(anchored)
|
||||
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src || anchored)
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src)
|
||||
user.start_pulling(src, supress_message)
|
||||
@@ -237,11 +142,11 @@
|
||||
if(user.grab_state) //only the first upgrade is instantaneous
|
||||
var/old_grab_state = user.grab_state
|
||||
var/grab_upgrade_time = 30
|
||||
visible_message("<span class='danger'>[user] starts to tighten \his grip on [src]!</span>", \
|
||||
"<span class='userdanger'>[user] starts to tighten \his grip on you!</span>")
|
||||
visible_message("<span class='danger'>[user] starts to tighten [user.p_their()] grip on [src]!</span>", \
|
||||
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>")
|
||||
if(!do_mob(user, src, grab_upgrade_time))
|
||||
return 0
|
||||
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != "grab")
|
||||
if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state || user.a_intent != INTENT_GRAB)
|
||||
return 0
|
||||
user.grab_state++
|
||||
switch(user.grab_state)
|
||||
@@ -249,8 +154,7 @@
|
||||
add_logs(user, src, "grabbed", addition="aggressively")
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
|
||||
"<span class='userdanger'>[user] has grabbed [src] aggressively!</span>")
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
drop_all_held_items()
|
||||
stop_pulling()
|
||||
if(GRAB_NECK)
|
||||
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
|
||||
@@ -281,7 +185,7 @@
|
||||
add_logs(M, src, "attacked")
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
|
||||
"<span class='userdanger'>The [M.name] glomps [src]!</span>")
|
||||
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
/mob/living/attack_animal(mob/living/simple_animal/M)
|
||||
@@ -294,38 +198,33 @@
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
|
||||
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>")
|
||||
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "attacked")
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
M << "You cannot attack people before the game has started."
|
||||
return 0
|
||||
|
||||
if (istype(loc, /turf) && istype(loc.loc, /area/start))
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
M << "No attacking people at spawn, you jackass."
|
||||
return 0
|
||||
|
||||
if (M.a_intent == "harm")
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
|
||||
M << "<span class='warning'>You can't bite with your mouth covered!</span>"
|
||||
return 0
|
||||
M.do_attack_animation(src)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
if (prob(75))
|
||||
add_logs(M, src, "attacked")
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>")
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>")
|
||||
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 0
|
||||
|
||||
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
switch(L.a_intent)
|
||||
if("help")
|
||||
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
|
||||
@@ -336,20 +235,16 @@
|
||||
if(prob(90))
|
||||
add_logs(L, src, "attacked")
|
||||
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[L.name] bites [src]!</span>")
|
||||
"<span class='userdanger'>[L.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
return 1
|
||||
else
|
||||
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>")
|
||||
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 0
|
||||
|
||||
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
M << "You cannot attack people before the game has started."
|
||||
return 0
|
||||
|
||||
if (istype(loc, /turf) && istype(loc.loc, /area/start))
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
M << "No attacking people at spawn, you jackass."
|
||||
return 0
|
||||
|
||||
@@ -361,26 +256,103 @@
|
||||
if ("grab")
|
||||
grabbedby(M)
|
||||
return 0
|
||||
else
|
||||
if("harm")
|
||||
M.do_attack_animation(src)
|
||||
return 1
|
||||
if("disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return 1
|
||||
|
||||
/mob/living/incapacitated(ignore_restraints, ignore_grab)
|
||||
if(stat || paralysis || stunned || weakened || (!ignore_restraints && restrained(ignore_grab)))
|
||||
return 1
|
||||
/mob/living/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
flash_act()
|
||||
|
||||
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.
|
||||
|
||||
/mob/living/Stun(amount, updating = 1, ignore_canstun = 0)
|
||||
if(stun_absorption && !stat)
|
||||
visible_message("<span class='warning'>[src]'s yellow aura momentarily intensifies!</span>", "<span class='userdanger'>Your ward absorbs the stun!</span>")
|
||||
stun_absorption_count += amount
|
||||
return 0
|
||||
/mob/living/acid_act(acidpwr, acid_volume)
|
||||
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0)
|
||||
if(shock_damage > 0)
|
||||
if(!illusion)
|
||||
adjustFireLoss(shock_damage)
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
return shock_damage
|
||||
|
||||
/mob/living/emp_act(severity)
|
||||
var/list/L = src.get_contents()
|
||||
for(var/obj/O in L)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/Weaken(amount, updating = 1, ignore_canweaken = 0)
|
||||
if(stun_absorption && !stat)
|
||||
visible_message("<span class='warning'>[src]'s yellow aura momentarily intensifies!</span>", "<span class='userdanger'>Your ward absorbs the stun!</span>")
|
||||
stun_absorption_count += amount
|
||||
return 0
|
||||
/mob/living/singularity_act()
|
||||
var/gain = 20
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/narsie_act()
|
||||
if(is_servant_of_ratvar(src) && !stat)
|
||||
src << "<span class='userdanger'>You resist Nar-Sie's influence... but not all of it. <i>Run!</i></span>"
|
||||
adjustBruteLoss(35)
|
||||
if(src && reagents)
|
||||
reagents.add_reagent("heparin", 5)
|
||||
return FALSE
|
||||
if(client)
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, null, 0)
|
||||
else
|
||||
switch(rand(1, 10))
|
||||
if(1)
|
||||
new /mob/living/simple_animal/hostile/construct/armored/hostile(get_turf(src))
|
||||
if(2)
|
||||
new /mob/living/simple_animal/hostile/construct/wraith/hostile(get_turf(src))
|
||||
if(3 to 6)
|
||||
new /mob/living/simple_animal/hostile/construct/builder/hostile(get_turf(src))
|
||||
if(6 to 10)
|
||||
new /mob/living/simple_animal/hostile/construct/harvester/hostile(get_turf(src))
|
||||
spawn_dust()
|
||||
gib()
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/ratvar_act()
|
||||
if(!is_servant_of_ratvar(src) && !add_servant_of_ratvar(src))
|
||||
src << "<span class='userdanger'>A blinding light boils you alive! <i>Run!</i></span>"
|
||||
adjustFireLoss(35)
|
||||
if(src)
|
||||
adjust_fire_stacks(1)
|
||||
IgniteMob()
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
//called when the mob receives a bright flash
|
||||
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
|
||||
if(get_eye_protection() < intensity && (override_blindness_check || !(disabilities & BLIND)))
|
||||
overlay_fullscreen("flash", type)
|
||||
addtimer(src, "clear_fullscreen", 25, TIMER_NORMAL, "flash", 25)
|
||||
return 1
|
||||
|
||||
//called when the mob receives a loud bang
|
||||
/mob/living/proc/soundbang_act()
|
||||
return 0
|
||||
|
||||
//to damage the clothes worn by a mob
|
||||
/mob/living/proc/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
return
|
||||
|
||||
|
||||
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(A != src)
|
||||
end_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
used_item = get_active_held_item()
|
||||
..()
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
sight = 0
|
||||
see_in_dark = 2
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD)
|
||||
pressure_resistance = 10
|
||||
|
||||
//Health and life related vars
|
||||
var/maxHealth = 100 //Maximum health that should be possible.
|
||||
@@ -41,6 +42,8 @@
|
||||
var/bloodcrawl = 0 //0 No blood crawling, BLOODCRAWL for bloodcrawling, BLOODCRAWL_EAT for 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
|
||||
var/limb_destroyer = 0 //1 Sets AI behavior that allows mobs to target and dismember limbs with their basic attack.
|
||||
|
||||
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..
|
||||
@@ -64,11 +67,11 @@
|
||||
|
||||
var/list/weather_immunities = list()
|
||||
|
||||
var/stun_absorption = FALSE //If all incoming stuns are being absorbed
|
||||
var/stun_absorption_count = 0 //How many seconds of stun that have been absorbed
|
||||
|
||||
var/mob/living/mental_dominator //The person controlling the mind of this person, if applicable
|
||||
var/mob/living/mind_control_holder/mind_control_holder //If the mob is being mind controlled, where their old mind is stored (check clock_mobs.dm)
|
||||
var/stun_absorption = null //converted to a list of stun absorption sources this mob has when one is added
|
||||
|
||||
var/blood_volume = 0 //how much blood the mob has
|
||||
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
|
||||
|
||||
var/list/status_effects //a list of all status effects the mob has
|
||||
|
||||
var/slipping = FALSE
|
||||
@@ -18,5 +18,4 @@
|
||||
src << "<span class='notice'>You can ventcrawl! Use alt+click on vents to quickly travel about the station.</span>"
|
||||
|
||||
if(ranged_ability)
|
||||
client.click_intercept = ranged_ability
|
||||
src << "<span class='notice'>You currently have <b>[ranged_ability.name]</b> active!</span>"
|
||||
ranged_ability.add_ranged_ability(src, "<span class='notice'>You currently have <b>[ranged_ability]</b> active!</span>")
|
||||
@@ -1,4 +1,6 @@
|
||||
/mob/living/Logout()
|
||||
if(ranged_ability && client)
|
||||
ranged_ability.remove_mousepointer(client)
|
||||
..()
|
||||
if(!key && mind) //key and mind have become seperated.
|
||||
mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body.
|
||||
@@ -60,6 +60,9 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
/mob/living/say(message, bubble_type,var/list/spans = list())
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
if(!message || message == "")
|
||||
return
|
||||
|
||||
|
||||
if(stat == DEAD)
|
||||
say_dead(message)
|
||||
@@ -92,10 +95,8 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
if(message_mode != MODE_WHISPER) //whisper() calls treat_message(); double process results in "hisspering"
|
||||
message = treat_message(message)
|
||||
spans += get_spans()
|
||||
|
||||
if(!message)
|
||||
return
|
||||
spans += get_spans()
|
||||
|
||||
//Log of what we've said, plain message, no spans or junk
|
||||
say_log += message
|
||||
@@ -144,7 +145,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans)
|
||||
var/list/listening = get_hearers_in_view(message_range, source)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7 && M.z == z)) && client) // client is so that ghosts don't have to listen to mice
|
||||
listening |= M
|
||||
|
||||
var/rendered = compose_message(src, languages_spoken, message, , spans)
|
||||
@@ -219,7 +220,6 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if(1)
|
||||
if(prob(40))
|
||||
M << "<i><font color=#800080>We can faintly sense an outsider trying to communicate through the hivemind...</font></i>"
|
||||
return 1
|
||||
if(2)
|
||||
var/msg = "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
|
||||
log_say("[mind.changeling.changelingID]/[src.key] : [message]")
|
||||
@@ -236,14 +236,13 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if(1)
|
||||
if(prob(40))
|
||||
M << "<i><font color=#800080>We can faintly sense another of our kind trying to communicate through the hivemind...</font></i>"
|
||||
return 1
|
||||
if(1)
|
||||
src << "<i><font color=#800080>Our senses have not evolved enough to be able to communicate this way...</font></i>"
|
||||
return 1
|
||||
return 1
|
||||
if(message_mode == MODE_ALIEN)
|
||||
if(hivecheck())
|
||||
alien_talk(message)
|
||||
return 1
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/proc/treat_message(message)
|
||||
@@ -266,14 +265,15 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
/mob/living/proc/radio(message, message_mode, list/spans)
|
||||
switch(message_mode)
|
||||
if(MODE_R_HAND)
|
||||
if (r_hand)
|
||||
r_hand.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE))
|
||||
if (r_hand)
|
||||
return r_hand.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
if(MODE_L_HAND)
|
||||
if (l_hand)
|
||||
l_hand.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
for(var/obj/item/l_hand in get_held_items_for_side("l", all = TRUE))
|
||||
if (l_hand)
|
||||
return l_hand.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_INTERCOM)
|
||||
for (var/obj/item/device/radio/intercom/I in view(1, null))
|
||||
|
||||
@@ -14,11 +14,13 @@ var/list/ai_list = list()
|
||||
|
||||
/mob/living/silicon/ai
|
||||
name = "AI"
|
||||
icon = 'icons/mob/AI.dmi'//
|
||||
icon = 'icons/mob/AI.dmi'
|
||||
icon_state = "ai"
|
||||
anchored = 1
|
||||
density = 1
|
||||
canmove = 0
|
||||
status_flags = CANSTUN|CANPUSH
|
||||
a_intent = INTENT_HARM //so we always get pushed instead of trying to swap
|
||||
force_compose = 1 //This ensures that the AI always composes it's own hear message. Needed for hrefs and job display.
|
||||
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS
|
||||
see_in_dark = 8
|
||||
@@ -29,6 +31,7 @@ var/list/ai_list = list()
|
||||
var/obj/machinery/camera/current = null
|
||||
var/list/connected_robots = list()
|
||||
var/aiRestorePowerRoutine = 0
|
||||
var/requires_power = POWER_REQ_ALL
|
||||
//var/list/laws = list()
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
|
||||
var/viewalerts = 0
|
||||
@@ -45,7 +48,6 @@ var/list/ai_list = list()
|
||||
//MALFUNCTION
|
||||
var/datum/module_picker/malf_picker
|
||||
var/list/datum/AI_Module/current_modules = list()
|
||||
var/fire_res_on_core = 0
|
||||
var/can_dominate_mechs = 0
|
||||
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
|
||||
|
||||
@@ -78,14 +80,36 @@ var/list/ai_list = list()
|
||||
|
||||
var/obj/machinery/camera/portable/builtInCamera
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
/mob/living/silicon/ai/New(loc, datum/ai_laws/L, obj/item/device/mmi/B, safety = 0)
|
||||
..()
|
||||
if(!safety) //Only used by AIize() to successfully spawn an AI.
|
||||
if(!B) //If there is no player/brain inside.
|
||||
new/obj/structure/AIcore/deactivated(loc) //New empty terminal.
|
||||
qdel(src)//Delete AI.
|
||||
return
|
||||
else
|
||||
if(B.brainmob.mind)
|
||||
B.brainmob.mind.transfer_to(src)
|
||||
rename_self("ai")
|
||||
if(mind.special_role)
|
||||
mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.")
|
||||
src << "<span class='userdanger'>You have been installed as an AI! </span>"
|
||||
src << "<span class='danger'>You must obey your silicon laws above all else. Your objectives will consider you to be dead.</span>"
|
||||
|
||||
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
|
||||
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
|
||||
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
|
||||
src << "To use something, simply click on it."
|
||||
src << "Use say :b to speak to your cyborgs through binary."
|
||||
src << "For department channels, use the following say commands:"
|
||||
src << ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science."
|
||||
show_laws()
|
||||
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
|
||||
|
||||
job = "AI"
|
||||
|
||||
rename_self("ai")
|
||||
name = real_name
|
||||
anchored = 1
|
||||
canmove = 0
|
||||
density = 1
|
||||
loc = loc
|
||||
|
||||
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
|
||||
|
||||
@@ -110,37 +134,12 @@ var/list/ai_list = list()
|
||||
radio = new /obj/item/device/radio/headset/ai(src)
|
||||
aicamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
|
||||
|
||||
if (istype(loc, /turf))
|
||||
if(isturf(loc))
|
||||
verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \
|
||||
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/botcall,\
|
||||
/mob/living/silicon/ai/proc/control_integrated_radio, /mob/living/silicon/ai/proc/set_automatic_say_channel)
|
||||
|
||||
if(!safety)//Only used by AIize() to successfully spawn an AI.
|
||||
if (!B)//If there is no player/brain inside.
|
||||
new/obj/structure/AIcore/deactivated(loc)//New empty terminal.
|
||||
qdel(src)//Delete AI.
|
||||
return
|
||||
else
|
||||
if (B.brainmob.mind)
|
||||
B.brainmob.mind.transfer_to(src)
|
||||
rename_self("ai")
|
||||
if(mind.special_role)
|
||||
mind.store_memory("As an AI, you must obey your silicon laws above all else. Your objectives will consider you to be dead.")
|
||||
src << "<span class='userdanger'>You have been installed as an AI! </span>"
|
||||
src << "<span class='danger'>You must obey your silicon laws above all else. Your objectives will consider you to be dead.</span>"
|
||||
|
||||
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
|
||||
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
|
||||
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
|
||||
src << "To use something, simply click on it."
|
||||
src << "Use say :b to speak to your cyborgs through binary."
|
||||
src << "For department channels, use the following say commands:"
|
||||
src << ":o - AI Private, :c - Command, :s - Security, :e - Engineering, :u - Supply, :v - Service, :m - Medical, :n - Science."
|
||||
show_laws()
|
||||
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
|
||||
|
||||
job = "AI"
|
||||
ai_list += src
|
||||
shuttle_caller_list += src
|
||||
|
||||
@@ -157,7 +156,9 @@ var/list/ai_list = list()
|
||||
shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
return ..()
|
||||
malfhack = null
|
||||
|
||||
. = ..()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/verb/pick_icon()
|
||||
@@ -293,8 +294,7 @@ var/list/ai_list = list()
|
||||
/mob/living/silicon/ai/proc/ai_roster()
|
||||
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
|
||||
|
||||
for(var/datum/data/record/t in sortRecord(data_core.general))
|
||||
dat += t.fields["name"] + " - " + t.fields["rank"] + "<br>"
|
||||
dat += data_core.get_manifest()
|
||||
dat += "</body></html>"
|
||||
|
||||
src << browse(dat, "window=airoster")
|
||||
@@ -303,7 +303,7 @@ var/list/ai_list = list()
|
||||
/mob/living/silicon/ai/proc/ai_call_shuttle()
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
if(istype(usr,/mob/living/silicon/ai))
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = src
|
||||
if(AI.control_disabled)
|
||||
usr << "Wireless control is disabled!"
|
||||
@@ -320,10 +320,8 @@ var/list/ai_list = list()
|
||||
if(C)
|
||||
C.post_status("shuttle")
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
src.view_core()
|
||||
view_core()
|
||||
|
||||
/mob/living/silicon/ai/verb/toggle_anchor()
|
||||
set category = "AI Commands"
|
||||
@@ -334,7 +332,7 @@ var/list/ai_list = list()
|
||||
return //won't work if dead
|
||||
anchored = !anchored // Toggles the anchor
|
||||
|
||||
src << "[anchored ? "<b>You are now anchored.</b>" : "<b>You are now unanchored.</b>"]"
|
||||
src << "<b>You are now [anchored ? "" : "un"]anchored.</b>"
|
||||
// the message in the [] will change depending whether or not the AI is anchored
|
||||
|
||||
/mob/living/silicon/ai/update_canmove() //If the AI dies, mobs won't go through it anymore
|
||||
@@ -344,7 +342,7 @@ var/list/ai_list = list()
|
||||
set category = "Malfunction"
|
||||
if(stat == DEAD)
|
||||
return //won't work if dead
|
||||
if(istype(usr,/mob/living/silicon/ai))
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = src
|
||||
if(AI.control_disabled)
|
||||
src << "Wireless control is disabled!"
|
||||
@@ -352,41 +350,9 @@ var/list/ai_list = list()
|
||||
SSshuttle.cancelEvac(src)
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/blob_act(obj/effect/blob/B)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(60)
|
||||
updatehealth()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/restrained(ignore_grab)
|
||||
. = 0
|
||||
|
||||
/mob/living/silicon/ai/emp_act(severity)
|
||||
if (prob(30))
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
view_core()
|
||||
if(2)
|
||||
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/ex_act(severity, target)
|
||||
..()
|
||||
|
||||
switch(severity)
|
||||
if(1)
|
||||
gib()
|
||||
if(2)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(60)
|
||||
adjustFireLoss(60)
|
||||
if(3)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(30)
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/Topic(href, href_list)
|
||||
if(usr != src)
|
||||
return
|
||||
@@ -411,7 +377,7 @@ var/list/ai_list = list()
|
||||
src << browse(last_paper_seen, "window=show_paper")
|
||||
//Carn: holopad requests
|
||||
if(href_list["jumptoholopad"])
|
||||
var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"])
|
||||
var/obj/machinery/holopad/H = locate(href_list["jumptoholopad"])
|
||||
if(stat == CONSCIOUS)
|
||||
if(H)
|
||||
H.attack_ai(src) //may as well recycle
|
||||
@@ -458,19 +424,6 @@ var/list/ai_list = list()
|
||||
if(M)
|
||||
M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself.
|
||||
|
||||
/mob/living/silicon/ai/bullet_act(obj/item/projectile/Proj)
|
||||
..(Proj)
|
||||
updatehealth()
|
||||
return 2
|
||||
|
||||
|
||||
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
M << "You cannot attack people before the game has started."
|
||||
return
|
||||
|
||||
..()
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
|
||||
|
||||
@@ -738,7 +691,7 @@ var/list/ai_list = list()
|
||||
src << "Camera lights deactivated."
|
||||
|
||||
for (var/obj/machinery/camera/C in lit_cameras)
|
||||
C.set_light(0)
|
||||
C.SetLuminosity(0)
|
||||
lit_cameras = list()
|
||||
|
||||
return
|
||||
@@ -746,7 +699,6 @@ var/list/ai_list = list()
|
||||
light_cameras()
|
||||
|
||||
src << "Camera lights activated."
|
||||
return
|
||||
|
||||
//AI_CAMERA_LUMINOSITY
|
||||
|
||||
@@ -795,9 +747,6 @@ var/list/ai_list = list()
|
||||
return //won't work if dead
|
||||
set_autosay()
|
||||
|
||||
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
|
||||
if(!..())
|
||||
return
|
||||
@@ -809,19 +758,11 @@ var/list/ai_list = list()
|
||||
ai_restore_power()//So the AI initially has power.
|
||||
control_disabled = 1//Can't control things remotely if you're stuck in a card!
|
||||
radio_enabled = 0 //No talking on the built-in radio for you either!
|
||||
loc = card//Throw AI into the card.
|
||||
forceMove(card)
|
||||
card.AI = src
|
||||
src << "You have been downloaded to a mobile storage device. Remote device connection severed."
|
||||
user << "<span class='boldnotice'>Transfer successful</span>: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
|
||||
/mob/living/silicon/ai/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/silicon/ai/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W.force && W.damtype != STAMINA && src.stat != DEAD) //only sparks if real damage is dealt.
|
||||
spark_system.start()
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/can_buckle()
|
||||
return 0
|
||||
|
||||
@@ -898,3 +839,32 @@ var/list/ai_list = list()
|
||||
if(..()) //successfully ressuscitated from death
|
||||
icon_state = "ai"
|
||||
. = 1
|
||||
|
||||
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
|
||||
malfhack = null
|
||||
malfhacking = 0
|
||||
clear_alert("hackingapc")
|
||||
|
||||
if(!istype(apc) || qdeleted(apc) || apc.stat & BROKEN)
|
||||
src << "<span class='danger'>Hack aborted. The designated APC no \
|
||||
longer exists on the power network.</span>"
|
||||
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
|
||||
else if(apc.aidisabled)
|
||||
src << "<span class='danger'>Hack aborted. \The [apc] is no \
|
||||
longer responding to our systems.</span>"
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
else
|
||||
malf_picker.processing_time += 10
|
||||
|
||||
apc.malfai = parent || src
|
||||
apc.malfhack = TRUE
|
||||
apc.locked = TRUE
|
||||
apc.coverlocked = TRUE
|
||||
|
||||
playsound(get_turf(src), 'sound/machines/ding.ogg', 50, 1)
|
||||
src << "Hack complete. \The [apc] is now under your \
|
||||
exclusive control."
|
||||
apc.update_icon()
|
||||
|
||||
/mob/living/silicon/ai/spawned/New(loc, datum/ai_laws/L, obj/item/device/mmi/B, safety = 0)
|
||||
..(loc,L,B,1)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
/mob/living/silicon/ai/attacked_by(obj/item/I, mob/living/user, def_zone)
|
||||
if(I.force && I.damtype != STAMINA && stat != DEAD) //only sparks if real damage is dealt.
|
||||
spark_system.start()
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
M << "You cannot attack people before the game has started."
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
|
||||
return //immune to slimes
|
||||
|
||||
/mob/living/silicon/ai/blob_act(obj/structure/blob/B)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(60)
|
||||
updatehealth()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/emp_act(severity)
|
||||
if (prob(30))
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
view_core()
|
||||
if(2)
|
||||
SSshuttle.requestEvac(src,"ALERT: Energy surge detected in AI core! Station integrity may be compromised! Initiati--%m091#ar-BZZT")
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/ex_act(severity, target)
|
||||
switch(severity)
|
||||
if(1)
|
||||
gib()
|
||||
if(2)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(60)
|
||||
adjustFireLoss(60)
|
||||
if(3)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(30)
|
||||
|
||||
|
||||
|
||||
/mob/living/silicon/ai/bullet_act(obj/item/projectile/Proj)
|
||||
..(Proj)
|
||||
updatehealth()
|
||||
return 2
|
||||
|
||||
/mob/living/silicon/ai/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
@@ -23,17 +23,14 @@
|
||||
|
||||
if(nuking)
|
||||
set_security_level("red")
|
||||
nuking = 0
|
||||
SSshuttle.emergencyNoEscape = 0
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
|
||||
SSshuttle.emergency.mode = SHUTTLE_DOCKED
|
||||
SSshuttle.emergency.timer = world.time
|
||||
priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
|
||||
for(var/obj/item/weapon/pinpointer/point in pinpointer_list)
|
||||
point.the_disk = null //Point back to the disk.
|
||||
nuking = FALSE
|
||||
for(var/obj/item/weapon/pinpointer/P in pinpointer_list)
|
||||
P.switch_mode_to(TRACK_NUKE_DISK) //Party's over, back to work, everyone
|
||||
P.nuke_warning = FALSE
|
||||
|
||||
if(doomsday_device)
|
||||
doomsday_device.timing = 0
|
||||
doomsday_device.timing = FALSE
|
||||
SSshuttle.clearHostileEnvironment(doomsday_device)
|
||||
qdel(doomsday_device)
|
||||
if(explosive)
|
||||
spawn(10)
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
var/turf/t = turf
|
||||
if(obscuredTurfs[t])
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 16)
|
||||
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1)
|
||||
t.obscured.plane = LIGHTING_PLANE+1
|
||||
obscured += t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/camera/aiEye/m = eye
|
||||
@@ -169,7 +169,8 @@
|
||||
for(var/turf in obscuredTurfs)
|
||||
var/turf/t = turf
|
||||
if(!t.obscured)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 16)
|
||||
t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1)
|
||||
t.obscured.plane = LIGHTING_PLANE+1
|
||||
obscured += t.obscured
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
@@ -24,9 +24,10 @@
|
||||
cameranet.visibility(src)
|
||||
if(ai.client)
|
||||
ai.client.eye = src
|
||||
update_parallax_contents()
|
||||
//Holopad
|
||||
if(istype(ai.current, /obj/machinery/hologram/holopad))
|
||||
var/obj/machinery/hologram/holopad/H = ai.current
|
||||
if(istype(ai.current, /obj/machinery/holopad))
|
||||
var/obj/machinery/holopad/H = ai.current
|
||||
H.move_hologram(ai)
|
||||
|
||||
/mob/camera/aiEye/Move()
|
||||
@@ -42,7 +43,7 @@
|
||||
return ..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.eyeobj && AI.client.eye == AI.eyeobj)
|
||||
AI.cameraFollow = null
|
||||
@@ -76,7 +77,7 @@
|
||||
|
||||
//user.unset_machine() //Uncomment this if it causes problems.
|
||||
//user.lightNearbyCamera()
|
||||
if (user.camera_light_on)
|
||||
if(user.camera_light_on)
|
||||
user.light_cameras()
|
||||
|
||||
// Return to the Core.
|
||||
@@ -86,13 +87,11 @@
|
||||
cameraFollow = null
|
||||
unset_machine()
|
||||
|
||||
if(src.eyeobj && src.loc)
|
||||
src.eyeobj.loc = src.loc
|
||||
else
|
||||
if(!eyeobj || !eyeobj.loc || qdeleted(eyeobj))
|
||||
src << "ERROR: Eyeobj not found. Creating new eye..."
|
||||
src.eyeobj = new(src.loc)
|
||||
src.eyeobj.ai = src
|
||||
src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
eyeobj = new(loc)
|
||||
eyeobj.ai = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
|
||||
eyeobj.setLoc(loc)
|
||||
|
||||
@@ -107,4 +106,4 @@
|
||||
|
||||
/mob/camera/aiEye/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
|
||||
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
|
||||
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
|
||||
|
||||
@@ -4,18 +4,21 @@
|
||||
#define POWER_RESTORATION_APC_FOUND 3
|
||||
|
||||
/mob/living/silicon/ai/Life()
|
||||
if (src.stat == DEAD)
|
||||
if (stat == DEAD)
|
||||
return
|
||||
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
|
||||
//Being dead doesn't mean your temperature never changes
|
||||
|
||||
update_gravity(mob_has_gravity())
|
||||
|
||||
if(malfhack)
|
||||
if(malfhack.aidisabled)
|
||||
src << "<span class='danger'>ERROR: APC access disabled, hack attempt canceled.</span>"
|
||||
malfhacking = 0
|
||||
malfhack = null
|
||||
if(malfhack && malfhack.aidisabled)
|
||||
deltimer(malfhacking)
|
||||
// This proc handles cleanup of screen notifications and
|
||||
// messenging the client
|
||||
malfhacked(malfhack)
|
||||
|
||||
if(!eyeobj || qdeleted(eyeobj) || !eyeobj.loc)
|
||||
view_core()
|
||||
|
||||
if(machine)
|
||||
machine.check_eye(src)
|
||||
@@ -44,14 +47,20 @@
|
||||
/mob/living/silicon/ai/proc/lacks_power()
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(src)
|
||||
return !T || !A || ((!A.master.power_equip || istype(T, /turf/open/space)) && !is_type_in_list(src.loc, list(/obj/item, /obj/mecha)))
|
||||
switch(requires_power)
|
||||
if(POWER_REQ_NONE)
|
||||
return FALSE
|
||||
if(POWER_REQ_ALL)
|
||||
return !T || !A || ((!A.master.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
|
||||
if(POWER_REQ_CLOCKCULT)
|
||||
for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, 1))
|
||||
return FALSE
|
||||
return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.master.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
|
||||
|
||||
/mob/living/silicon/ai/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss()
|
||||
if(!fire_res_on_core)
|
||||
health -= getFireLoss()
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getBruteLoss() - getFireLoss()
|
||||
update_stat()
|
||||
diag_hud_set_health()
|
||||
|
||||
@@ -59,7 +68,7 @@
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
if(health <= config.health_threshold_dead)
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
death()
|
||||
return
|
||||
else if(stat == UNCONSCIOUS)
|
||||
@@ -87,7 +96,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/AIarea = get_area(src)
|
||||
if(AIarea && AIarea.master.power_equip)
|
||||
if(!istype(T, /turf/open/space))
|
||||
if(!isspaceturf(T))
|
||||
ai_restore_power()
|
||||
return
|
||||
src << "Fault confirmed: missing external power. Shutting down main control system to save power."
|
||||
@@ -95,7 +104,7 @@
|
||||
src << "Emergency control system online. Verifying connection to power network."
|
||||
sleep(50)
|
||||
T = get_turf(src)
|
||||
if (istype(T, /turf/open/space))
|
||||
if(isspaceturf(T))
|
||||
src << "Unable to verify! No power connection detected!"
|
||||
aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC
|
||||
return
|
||||
@@ -122,7 +131,7 @@
|
||||
aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC
|
||||
return
|
||||
if(AIarea.master.power_equip)
|
||||
if (!istype(T, /turf/open/space))
|
||||
if(!isspaceturf(T))
|
||||
ai_restore_power()
|
||||
return
|
||||
switch(PRP)
|
||||
@@ -158,10 +167,9 @@
|
||||
blind_eyes(1)
|
||||
update_sight()
|
||||
src << "You've lost power!"
|
||||
spawn(20)
|
||||
start_RestorePowerRoutine()
|
||||
addtimer(src, "start_RestorePowerRoutine", 20)
|
||||
|
||||
#undef POWER_RESTORATION_OFF
|
||||
#undef POWER_RESTORATION_START
|
||||
#undef POWER_RESTORATION_SEARCH_APC
|
||||
#undef POWER_RESTORATION_APC_FOUND
|
||||
#undef POWER_RESTORATION_APC_FOUND
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user