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:
Poojawa
2016-12-22 03:57:55 -06:00
committed by GitHub
parent f5e143a452
commit cf59ac1c3d
2215 changed files with 707445 additions and 87041 deletions
+1 -1
View File
@@ -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)
+7
View File
@@ -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.
+95 -29
View File
@@ -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!"
+1 -13
View File
@@ -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
View File
@@ -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
View File
@@ -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
+26 -48
View File
@@ -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)
+7 -8
View File
@@ -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)
@@ -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>"
+67
View File
@@ -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
@@ -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
..()
@@ -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)
@@ -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)
@@ -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
@@ -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
@@ -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
+12 -53
View File
@@ -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
+5 -16
View File
@@ -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)
+28 -1
View File
@@ -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
+148 -168
View File
@@ -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]"
+232 -36
View File
@@ -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()
+32 -8
View File
@@ -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)
+1 -30
View File
@@ -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)
+70 -44
View File
@@ -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)
+7 -17
View File
@@ -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
+30 -77
View File
@@ -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)
+60 -94
View File
@@ -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
+106 -259
View File
@@ -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>&nbsp;</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>&nbsp;</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
+100 -10
View File
@@ -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)
+1 -1
View File
@@ -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)
+39 -21
View File
@@ -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()
+12 -14
View File
@@ -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
+39 -15
View File
@@ -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
+25 -194
View File
@@ -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)
+4
View File
@@ -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)
+17 -2
View File
@@ -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
+183 -44
View File
@@ -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()
+144 -21
View File
@@ -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()
+12 -11
View File
@@ -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
+10 -18
View File
@@ -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)))
+32 -10
View File
@@ -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
View File
@@ -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
+139 -167
View File
@@ -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.
+8 -5
View File
@@ -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
+1 -2
View File
@@ -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>")
+2
View File
@@ -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.
+15 -15
View File
@@ -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))
+72 -102
View File
@@ -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
+6 -9
View File
@@ -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)
+25 -17
View File
@@ -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