Initial Commit

This commit is contained in:
skull132
2014-03-11 09:03:52 +02:00
commit a8d9450c7e
3486 changed files with 415920 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
/*
Creature-level abilities.
*/
/var/global/list/ability_verbs = list( )
/*
Example ability:
/client/proc/test_ability()
set category = "Ability"
set name = "Test ability"
set desc = "An ability for testing."
// Check if the client has a mob and if the mob is valid and alive.
if(!mob || !istype(mob,/mob/living) || mob.stat)
src << "\red You must be corporeal and alive to do that."
return 0
//Handcuff check.
if(mob.restrained())
src << "\red You cannot do this while restrained."
return 0
if(istype(mob,/mob/living/carbon))
var/mob/living/carbon/M = mob
if(M.handcuffed)
src << "\red You cannot do this while cuffed."
return 0
src << "\blue You perform an ability."
*/
+5
View File
@@ -0,0 +1,5 @@
/mob/dead/dust() //ghosts can't be vaporised.
return
/mob/dead/gib() //ghosts can't be gibbed.
return
+2
View File
@@ -0,0 +1,2 @@
/mob/dead/observer/Login()
..()
+5
View File
@@ -0,0 +1,5 @@
/mob/dead/observer/Logout()
..()
spawn(0)
if(src && !key) //we've transferred to another mob. This ghost should be deleted.
del(src)
+635
View File
@@ -0,0 +1,635 @@
/mob/dead/observer
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
icon = 'icons/mob/mob.dmi'
icon_state = "ghost"
layer = 4
stat = DEAD
density = 0
canmove = 0
blinded = 0
anchored = 1 // don't get pushed around
invisibility = INVISIBILITY_OBSERVER
var/can_reenter_corpse
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
//If you died in the game and are a ghsot - this will remain as null.
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
var/has_enabled_antagHUD = 0
var/medHUD = 0
var/antagHUD = 0
universal_speak = 1
var/atom/movable/following = null
/mob/dead/observer/New(mob/body)
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = 100
verbs += /mob/dead/observer/proc/dead_tele
stat = DEAD
var/turf/T
if(ismob(body))
T = get_turf(body) //Where is the body located?
attack_log = body.attack_log //preserve our attack logs by copying them to our ghost
if (ishuman(body))
var/mob/living/carbon/human/H = body
icon = H.stand_icon
overlays = H.overlays_standing
else
icon = body.icon
icon_state = body.icon_state
overlays = body.overlays
alpha = 127
gender = body.gender
if(body.mind && body.mind.name)
name = body.mind.name
else
if(body.real_name)
name = body.real_name
else
if(gender == MALE)
name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
else
name = capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
mind = body.mind //we don't transfer the mind but we keep a reference to it.
if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position
loc = T
if(!name) //To prevent nameless ghosts
name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
real_name = name
..()
/mob/dead/attackby(obj/item/W, mob/user)
if(istype(W,/obj/item/weapon/tome))
var/mob/dead/M = src
if(src.invisibility != 0)
M.invisibility = 0
user.visible_message( \
"\red [user] drags ghost, [M], to our plan of reality!", \
"\red You drag [M] to our plan of reality!" \
)
else
user.visible_message ( \
"\red [user] just tried to smash his book into that ghost! It's not very effective", \
"\red You get the feeling that the ghost can't become any more visible." \
)
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
return 1
/*
Transfer_mind is there to check if mob is being deleted/not going to have a body.
Works together with spawning an observer, noted above.
*/
/mob/dead/observer/Life()
..()
if(!loc) return
if(!client) return 0
if(client.images.len)
for(var/image/hud in client.images)
if(copytext(hud.icon_state,1,4) == "hud")
client.images.Remove(hud)
if(antagHUD)
var/list/target_list = list()
for(var/mob/living/target in oview(src))
if( target.mind&&(target.mind.special_role||issilicon(target)) )
target_list += target
if(target_list.len)
assess_targets(target_list, src)
if(medHUD)
process_medHUD(src)
// Direct copied from medical HUD glasses proc, used to determine what health bar to put over the targets head.
/mob/dead/proc/RoundHealth(var/health)
switch(health)
if(100 to INFINITY)
return "health100"
if(70 to 100)
return "health80"
if(50 to 70)
return "health60"
if(30 to 50)
return "health40"
if(18 to 30)
return "health25"
if(5 to 18)
return "health10"
if(1 to 5)
return "health1"
if(-99 to 0)
return "health0"
else
return "health-100"
return "0"
// Pretty much a direct copy of Medical HUD stuff, except will show ill if they are ill instead of also checking for known illnesses.
/mob/dead/proc/process_medHUD(var/mob/M)
var/client/C = M.client
var/image/holder
for(var/mob/living/carbon/human/patient in oview(M))
var/foundVirus = 0
if(patient.virus2.len)
foundVirus = 1
if(!C) return
holder = patient.hud_list[HEALTH_HUD]
if(patient.stat == 2)
holder.icon_state = "hudhealth-100"
else
holder.icon_state = "hud[RoundHealth(patient.health)]"
C.images += holder
holder = patient.hud_list[STATUS_HUD]
if(patient.stat == 2)
holder.icon_state = "huddead"
else if(patient.status_flags & XENO_HOST)
holder.icon_state = "hudxeno"
else if(foundVirus)
holder.icon_state = "hudill"
else if(patient.has_brain_worms())
var/mob/living/simple_animal/borer/B = patient.has_brain_worms()
if(B.controlling)
holder.icon_state = "hudbrainworm"
else
holder.icon_state = "hudhealthy"
else
holder.icon_state = "hudhealthy"
C.images += holder
/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U)
var/icon/tempHud = 'icons/mob/hud.dmi'
for(var/mob/living/target in target_list)
if(iscarbon(target))
switch(target.mind.special_role)
if("traitor","Syndicate")
U.client.images += image(tempHud,target,"hudsyndicate")
if("Revolutionary")
U.client.images += image(tempHud,target,"hudrevolutionary")
if("Head Revolutionary")
U.client.images += image(tempHud,target,"hudheadrevolutionary")
if("Cultist")
U.client.images += image(tempHud,target,"hudcultist")
if("Changeling")
U.client.images += image(tempHud,target,"hudchangeling")
if("Wizard","Fake Wizard")
U.client.images += image(tempHud,target,"hudwizard")
if("Hunter","Sentinel","Drone","Queen")
U.client.images += image(tempHud,target,"hudalien")
if("Death Commando")
U.client.images += image(tempHud,target,"huddeathsquad")
if("Ninja")
U.client.images += image(tempHud,target,"hudninja")
else//If we don't know what role they have but they have one.
U.client.images += image(tempHud,target,"hudunknown1")
else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud.
var/mob/living/silicon/silicon_target = target
if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))||silicon_target.mind.special_role=="traitor")
if(isrobot(silicon_target))//Different icons for robutts and AI.
U.client.images += image(tempHud,silicon_target,"hudmalborg")
else
U.client.images += image(tempHud,silicon_target,"hudmalai")
return 1
/mob/proc/ghostize(var/can_reenter_corpse = 1)
if(key)
var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
if(!ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
return ghost
/*
This is the proc mobs get to turn into a ghost. Forked from ghostize due to compatibility issues.
*/
/mob/living/verb/ghost()
set category = "OOC"
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(stat == DEAD)
ghostize(1)
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to play this round for another 30 minutes! You can't change your mind so choose wisely!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost") return //didn't want to ghost after-all
resting = 1
var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
return
/mob/dead/observer/Move(NewLoc, direct)
dir = direct
if(NewLoc)
loc = NewLoc
for(var/obj/effect/step_trigger/S in NewLoc)
S.HasEntered(src)
return
loc = get_turf(src) //Get out of closets and such as a ghost
if((direct & NORTH) && y < world.maxy)
y++
else if((direct & SOUTH) && y > 1)
y--
if((direct & EAST) && x < world.maxx)
x++
else if((direct & WEST) && x > 1)
x--
for(var/obj/effect/step_trigger/S in locate(x, y, z)) //<-- this is dumb
S.HasEntered(src)
/mob/dead/observer/examine()
if(usr)
usr << desc
/mob/dead/observer/can_use_hands() return 0
/mob/dead/observer/is_active() return 0
/mob/dead/observer/Stat()
..()
statpanel("Status")
if (client.statpanel == "Status")
stat(null, "Station Time: [worldtime2text()]")
if(ticker)
if(ticker.mode)
//world << "DEBUG: ticker not null"
if(ticker.mode.name == "AI malfunction")
//world << "DEBUG: malf mode ticker test"
if(ticker.mode:malf_mode_declared)
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
if(emergency_shuttle)
if(emergency_shuttle.online && emergency_shuttle.location < 2)
var/timeleft = emergency_shuttle.timeleft()
if (timeleft)
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
/mob/dead/observer/verb/reenter_corpse()
set category = "Ghost"
set name = "Re-enter Corpse"
if(!client) return
if(!(mind && mind.current && can_reenter_corpse))
src << "<span class='warning'>You have no body.</span>"
return
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
usr << "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>"
return
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
var/obj/effect/rune/R = locate() in mind.current.loc //whilst corpse is alive, we can only reenter the body if it's on the rune
if(!(R && R.word1 == cultwords["hell"] && R.word2 == cultwords["travel"] && R.word3 == cultwords["self"])) //astral journeying rune
usr << "<span class='warning'>The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you.</span>"
return
mind.current.ajourn=0
mind.current.key = key
return 1
/mob/dead/observer/verb/toggle_medHUD()
set category = "Ghost"
set name = "Toggle MedicHUD"
set desc = "Toggles Medical HUD allowing you to see how everyone is doing"
if(!client)
return
if(medHUD)
medHUD = 0
src << "\blue <B>Medical HUD Disabled</B>"
else
medHUD = 1
src << "\blue <B>Medical HUD Enabled</B>"
/mob/dead/observer/verb/toggle_antagHUD()
set category = "Ghost"
set name = "Toggle AntagHUD"
set desc = "Toggles AntagHUD allowing you to see who is the antagonist"
if(!config.antag_hud_allowed && !client.holder)
src << "\red Admins have disabled this for this round."
return
if(!client)
return
var/mob/dead/observer/M = src
if(jobban_isbanned(M, "AntagHUD"))
src << "\red <B>You have been banned from using this feature</B>"
return
if(config.antag_hud_restricted && !M.has_enabled_antagHUD &&!client.holder)
var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No")
if(response == "No") return
M.can_reenter_corpse = 0
if(!M.has_enabled_antagHUD && !client.holder)
M.has_enabled_antagHUD = 1
if(M.antagHUD)
M.antagHUD = 0
src << "\blue <B>AntagHUD Disabled</B>"
else
M.antagHUD = 1
src << "\blue <B>AntagHUD Enabled</B>"
/mob/dead/observer/proc/dead_tele()
set category = "Ghost"
set name = "Teleport"
set desc= "Teleport to a location"
if(!istype(usr, /mob/dead/observer))
usr << "Not when you're not dead!"
return
usr.verbs -= /mob/dead/observer/proc/dead_tele
spawn(30)
usr.verbs += /mob/dead/observer/proc/dead_tele
var/A
A = input("Area to jump to", "BOOYEA", A) as null|anything in ghostteleportlocs
var/area/thearea = ghostteleportlocs[A]
if(!thearea) return
var/list/L = list()
for(var/turf/T in get_area_turfs(thearea.type))
L+=T
if(!L || !L.len)
usr << "No area available."
usr.loc = pick(L)
/mob/dead/observer/verb/follow()
set category = "Ghost"
set name = "Follow" // "Haunt"
set desc = "Follow and haunt a mob."
var/list/mobs = getmobs()
var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs
var/mob/target = mobs[input]
ManualFollow(target)
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
if(target && target != src)
if(following && following == target)
return
following = target
src << "\blue Now following [target]"
spawn(0)
var/turf/pos = get_turf(src)
while(loc == pos && target && following == target && client)
var/turf/T = get_turf(target)
if(!T)
break
// To stop the ghost flickering.
if(loc != T)
loc = T
pos = loc
sleep(15)
following = null
/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!
var/list/dest = list() //List of possible destinations (mobs)
var/target = null //Chosen target.
dest += getmobs() //Fill list, prompt user with list
target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in dest
if (!target)//Make sure we actually have a target
return
else
var/mob/M = dest[target] //Destination mob
var/mob/A = src //Source mob
var/turf/T = get_turf(M) //Turf of the destination mob
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
A.loc = T
else
A << "This mob is not located in the game world."
/*
/mob/dead/observer/verb/boo()
set category = "Ghost"
set name = "Boo!"
set desc= "Scare your crew members because of boredom!"
if(bootime > world.time) return
var/obj/machinery/light/L = locate(/obj/machinery/light) in view(1, src)
if(L)
L.flicker()
bootime = world.time + 600
return
//Maybe in the future we can add more <i>spooky</i> code here!
return
*/
/mob/dead/observer/memory()
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
/mob/dead/observer/add_memory()
set hidden = 1
src << "\red You are dead! You have no mind to store memory!"
/mob/dead/observer/verb/analyze_air()
set name = "Analyze Air"
set category = "Ghost"
if(!istype(usr, /mob/dead/observer)) return
// Shamelessly copied from the Gas Analyzers
if (!( istype(usr.loc, /turf) ))
return
var/datum/gas_mixture/environment = usr.loc.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
src << "\blue <B>Results:</B>"
if(abs(pressure - ONE_ATMOSPHERE) < 10)
src << "\blue Pressure: [round(pressure,0.1)] kPa"
else
src << "\red Pressure: [round(pressure,0.1)] kPa"
if(total_moles)
var/o2_concentration = environment.oxygen/total_moles
var/n2_concentration = environment.nitrogen/total_moles
var/co2_concentration = environment.carbon_dioxide/total_moles
var/plasma_concentration = environment.toxins/total_moles
var/unknown_concentration = 1-(o2_concentration+n2_concentration+co2_concentration+plasma_concentration)
if(abs(n2_concentration - N2STANDARD) < 20)
src << "\blue Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)"
else
src << "\red Nitrogen: [round(n2_concentration*100)]% ([round(environment.nitrogen,0.01)] moles)"
if(abs(o2_concentration - O2STANDARD) < 2)
src << "\blue Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)"
else
src << "\red Oxygen: [round(o2_concentration*100)]% ([round(environment.oxygen,0.01)] moles)"
if(co2_concentration > 0.01)
src << "\red CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)"
else
src << "\blue CO2: [round(co2_concentration*100)]% ([round(environment.carbon_dioxide,0.01)] moles)"
if(plasma_concentration > 0.01)
src << "\red Plasma: [round(plasma_concentration*100)]% ([round(environment.toxins,0.01)] moles)"
if(unknown_concentration > 0.01)
src << "\red Unknown: [round(unknown_concentration*100)]% ([round(unknown_concentration*total_moles,0.01)] moles)"
src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]&deg;C"
src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]"
/mob/dead/observer/verb/toggle_darkness()
set name = "Toggle Darkness"
set category = "Ghost"
if (see_invisible == SEE_INVISIBLE_OBSERVER_NOLIGHTING)
see_invisible = SEE_INVISIBLE_OBSERVER
else
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
/mob/dead/observer/verb/become_mouse()
set name = "Become mouse"
set category = "Ghost"
if(config.disable_player_mice)
src << "<span class='warning'>Spawning as a mouse is currently disabled.</span>"
return
var/mob/dead/observer/M = usr
if(config.antag_hud_restricted && M.has_enabled_antagHUD == 1)
src << "<span class='warning'>antagHUD restrictions prevent you from spawning in as a mouse.</span>"
return
var/timedifference = world.time - client.time_died_as_mouse
if(client.time_died_as_mouse && timedifference <= mouse_respawn_time * 600)
var/timedifference_text
timedifference_text = time2text(mouse_respawn_time * 600 - timedifference,"mm:ss")
src << "<span class='warning'>You may only spawn again as a mouse more than [mouse_respawn_time] minutes after your death. You have [timedifference_text] left.</span>"
return
var/response = alert(src, "Are you -sure- you want to become a mouse?","Are you sure you want to squeek?","Squeek!","Nope!")
if(response != "Squeek!") return //Hit the wrong key...again.
//find a viable mouse candidate
var/mob/living/simple_animal/mouse/host
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
var/list/found_vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/v in world)
if(!v.welded && v.z == src.z)
found_vents.Add(v)
if(found_vents.len)
vent_found = pick(found_vents)
host = new /mob/living/simple_animal/mouse(vent_found.loc)
else
src << "<span class='warning'>Unable to find any unwelded vents to spawn mice at.</span>"
if(host)
if(config.uneducated_mice)
host.universal_understand = 0
host.ckey = src.ckey
host << "<span class='info'>You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent.</span>"
/mob/dead/observer/verb/view_manfiest()
set name = "View Crew Manifest"
set category = "Ghost"
var/dat
dat += "<h4>Crew Manifest</h4>"
dat += data_core.get_manifest()
src << browse(dat, "window=manifest;size=370x420;can_close=1")
//Used for drawing on walls with blood puddles as a spooky ghost.
/mob/dead/verb/bloody_doodle()
set category = "Ghost"
set name = "Write in blood"
set desc = "If the round is sufficiently spooky, write a short message in blood on the floor or a wall. Remember, no IC in OOC or OOC in IC."
if(!(config.cult_ghostwriter))
src << "\red That verb is not currently permitted."
return
if (!src.stat)
return
if (usr != src)
return 0 //something is terribly wrong
var/ghosts_can_write
if(ticker.mode.name == "cult")
var/datum/game_mode/cult/C = ticker.mode
if(C.cult.len > config.cult_ghostwriter_req_cultists)
ghosts_can_write = 1
if(!ghosts_can_write)
src << "\red The veil is not thin enough for you to do that."
return
var/list/choices = list()
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
if(B.amount > 0)
choices += B
if(!choices.len)
src << "<span class = 'warning'>There is no blood to use nearby.</span>"
return
var/obj/effect/decal/cleanable/blood/choice = input(src,"What blood would you like to use?") in null|choices
var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West")
var/turf/simulated/T = src.loc
if (direction != "Here")
T = get_step(T,text2dir(direction))
if (!istype(T))
src << "<span class='warning'>You cannot doodle there.</span>"
return
if(!choice || choice.amount == 0 || !(src.Adjacent(choice)))
return
var/doodle_color = (choice.basecolor) ? choice.basecolor : "#A10808"
var/num_doodles = 0
for (var/obj/effect/decal/cleanable/blood/writing/W in T)
num_doodles++
if (num_doodles > 4)
src << "<span class='warning'>There is no space to write on!</span>"
return
var/max_length = 50
var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")
if (message)
if (length(message) > max_length)
message += "-"
src << "<span class='warning'>You ran out of blood to write with!</span>"
var/obj/effect/decal/cleanable/blood/writing/W = new(T)
W.basecolor = doodle_color
W.update_icon()
W.message = message
W.add_hiddenprint(src)
W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...")
+65
View File
@@ -0,0 +1,65 @@
/mob/dead/observer/say(var/message)
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
if (!message)
return
log_say("Ghost/[src.key] : [message]")
if (src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot talk in deadchat (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
return
. = src.say_dead(message)
/mob/dead/observer/emote(var/act, var/type, var/message)
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
if(!message)
return
if(act != "me")
return
log_emote("Ghost/[src.key] : [message]")
if(src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot emote in deadchat (muted)."
return
if(src.client.handle_spam_prevention(message, MUTE_DEADCHAT))
return
. = src.emote_dead(message)
/*
for (var/mob/M in hearers(null, null))
if (!M.stat)
if(M.job == "Chaplain")
if (prob (49))
M.show_message("<span class='game'><i>You hear muffled speech... but nothing is there...</i></span>", 2)
if(prob(20))
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
else
M.show_message("<span class='game'><i>You hear muffled speech... you can almost make out some words...</i></span>", 2)
// M.show_message("<span class='game'><i>[stutter(message)]</i></span>", 2)
if(prob(30))
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
else
if (prob(50))
return
else if (prob (95))
M.show_message("<span class='game'><i>You hear muffled speech... but nothing is there...</i></span>", 2)
if(prob(20))
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
else
M.show_message("<span class='game'><i>You hear muffled speech... you can almost make out some words...</i></span>", 2)
// M.show_message("<span class='game'><i>[stutter(message)]</i></span>", 2)
playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
*/
+55
View File
@@ -0,0 +1,55 @@
//This is the proc for gibbing a mob. Cannot gib ghosts.
//added different sort of gibs and animations. N
/mob/proc/gib()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("gibbed-m", animation)
gibs(loc, viruses, dna)
dead_mob_list -= src
spawn(15)
if(animation) del(animation)
if(src) del(src)
//This is the proc for turning a mob into ash. Mostly a copy of gib code (above).
//Originally created for wizard disintegrate. I've removed the virus code since it's irrelevant here.
//Dusting robots does not eject the MMI, so it's a bit more powerful than gib() /N
/mob/proc/dust()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("dust-m", animation)
new /obj/effect/decal/cleanable/ash(loc)
dead_mob_list -= src
spawn(15)
if(animation) del(animation)
if(src) del(src)
/mob/proc/death(gibbed)
timeofdeath = world.time
living_mob_list -= src
dead_mob_list += src
return ..(gibbed)
+91
View File
@@ -0,0 +1,91 @@
// All mobs should have custom emote, really..
/mob/proc/custom_emote(var/m_type=1,var/message = null)
if(stat || !use_me && usr == src)
usr << "You are unable to emote."
return
var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
if(m_type == 2 && muzzled) return
var/input
if(!message)
input = copytext(sanitize(input(src,"Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
else
input = message
if(input)
message = "<B>[src]</B> [input]"
else
return
if (message)
log_emote("[name]/[key] : [message]")
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
for(var/mob/M in player_list)
if (!M.client)
continue //skip monkeys and leavers
if (istype(M, /mob/new_player))
continue
if(findtext(message," snores.")) //Because we have so many sleeping people.
break
if(M.stat == 2 && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
// Type 1 (Visual) emotes are sent to anyone in view of the item
if (m_type & 1)
var/list/can_see = get_mobs_in_view(1,src) //Allows silicon & mmi mobs carried around to see the emotes of the person carrying them around.
can_see |= viewers(src,null)
for (var/mob/O in can_see)
O.show_message(message, m_type)
// Type 2 (Audible) emotes are sent to anyone in hear range
// of the *LOCATION* -- this is important for pAIs to be heard
else if (m_type & 2)
for (var/mob/O in get_mobs_in_view(7,src))
O.show_message(message, m_type)
/mob/proc/emote_dead(var/message)
if(client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot send deadchat emotes (muted)."
return
if(!(client.prefs.toggles & CHAT_DEAD))
src << "\red You have deadchat muted."
return
if(!src.client.holder)
if(!dsay_allowed)
src << "\red Deadchat is globally muted"
return
var/input
if(!message)
input = copytext(sanitize(input(src, "Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
else
input = message
if(input)
message = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <b>[src]</b> [message]</span>"
else
return
if(message)
log_emote("Ghost/[src.key] : [message]")
for(var/mob/M in player_list)
if(istype(M, /mob/new_player))
continue
if(M.client && M.client.holder && (M.client.holder.rights & R_ADMIN|R_MOD) && (M.client.prefs.toggles & CHAT_DEAD)) // Show the emote to admins/mods
M << message
else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // Show the emote to regular ghosts with deadchat toggled on
M.show_message(message, 2)
+319
View File
@@ -0,0 +1,319 @@
//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting l_hand = ...etc
//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(issilicon(src))
if(isrobot(src))
if(src:module_active)
return src:module_active
else
if(hand) return l_hand
else return r_hand
//Returns the thing in our inactive hand
/mob/proc/get_inactive_hand()
if(hand) return r_hand
else return l_hand
//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(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(!l_hand)
W.loc = src //TODO: move to equipped?
l_hand = W
W.layer = 20 //TODO: move to equipped?
// l_hand.screen_loc = ui_lhand
W.equipped(src,slot_l_hand)
if(client) client.screen |= W
if(pulling == W) stop_pulling()
update_inv_l_hand()
return 1
return 0
//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(var/obj/item/W)
if(lying) return 0
if(!istype(W)) return 0
if(!r_hand)
W.loc = src
r_hand = W
W.layer = 20
// r_hand.screen_loc = ui_rhand
W.equipped(src,slot_r_hand)
if(client) client.screen |= W
if(pulling == W) stop_pulling()
update_inv_r_hand()
return 1
return 0
//Puts the item into our active hand if possible. returns 1 on success.
/mob/proc/put_in_active_hand(var/obj/item/W)
if(hand) return put_in_l_hand(W)
else return put_in_r_hand(W)
//Puts the item into our inactive hand if possible. returns 1 on success.
/mob/proc/put_in_inactive_hand(var/obj/item/W)
if(hand) return put_in_r_hand(W)
else return put_in_l_hand(W)
//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.
//This is probably the main one you need to know :)
/mob/proc/put_in_hands(var/obj/item/W)
if(!W) return 0
if(put_in_active_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else if(put_in_inactive_hand(W))
update_inv_l_hand()
update_inv_r_hand()
return 1
else
W.loc = get_turf(src)
W.layer = initial(W.layer)
W.dropped()
return 0
/mob/proc/drop_item_v() //this is dumb.
if(stat == CONSCIOUS && isturf(loc))
return drop_item()
return 0
/mob/proc/drop_from_inventory(var/obj/item/W)
if(W)
if(client) client.screen -= W
u_equip(W)
if(!W) return 1 // self destroying objects (tk, grabs)
W.layer = initial(W.layer)
W.loc = loc
var/turf/T = get_turf(loc)
if(isturf(T))
T.Entered(W)
W.dropped(src)
update_icons()
return 1
return 0
//Drops the item in our left hand
/mob/proc/drop_l_hand(var/atom/Target)
if(l_hand)
if(client) client.screen -= l_hand
l_hand.layer = initial(l_hand.layer)
if(Target) l_hand.loc = Target.loc
else l_hand.loc = loc
var/turf/T = get_turf(loc)
if(isturf(T))
T.Entered(l_hand)
l_hand.dropped(src)
l_hand = null
update_inv_l_hand()
return 1
return 0
//Drops the item in our right hand
/mob/proc/drop_r_hand(var/atom/Target)
if(r_hand)
if(client) client.screen -= r_hand
r_hand.layer = initial(r_hand.layer)
if(Target) r_hand.loc = Target.loc
else r_hand.loc = loc
var/turf/T = get_turf(Target)
if(istype(T))
T.Entered(r_hand)
r_hand.dropped(src)
r_hand = null
update_inv_r_hand()
return 1
return 0
//Drops the item in our active hand.
/mob/proc/drop_item(var/atom/Target)
if(hand) return drop_l_hand(Target)
else return drop_r_hand(Target)
//TODO: phase out this proc
/mob/proc/before_take_item(var/obj/item/W) //TODO: what is this?
W.loc = null
W.layer = initial(W.layer)
u_equip(W)
update_icons()
return
/mob/proc/u_equip(W as obj)
if (W == r_hand)
r_hand = null
update_inv_r_hand(0)
else if (W == l_hand)
l_hand = null
update_inv_l_hand(0)
else if (W == back)
back = null
update_inv_back(0)
else if (W == wear_mask)
wear_mask = null
update_inv_wear_mask(0)
return
//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)
src.u_equip(O)
if (src.client)
src.client.screen -= O
O.layer = initial(O.layer)
O.screen_loc = null
return 1
//Outdated but still in use apparently. This should at least be a human proc.
/mob/proc/get_equipped_items()
var/list/items = new/list()
if(hasvar(src,"back")) if(src:back) items += src:back
if(hasvar(src,"belt")) if(src:belt) items += src:belt
if(hasvar(src,"l_ear")) if(src:l_ear) items += src:l_ear
if(hasvar(src,"r_ear")) if(src:r_ear) items += src:r_ear
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
return items
/** BS12's proc to get the item in the active hand. Couldn't find the /tg/ equivalent. **/
/mob/proc/equipped()
if(issilicon(src))
if(isrobot(src))
if(src:module_active)
return src:module_active
else
if (hand)
return l_hand
else
return r_hand
return
/mob/living/carbon/human/proc/equip_if_possible(obj/item/W, slot, del_on_fail = 1) // since byond doesn't seem to have pointers, this seems like the best way to do this :/
//warning: icky code
var/equipped = 0
switch(slot)
if(slot_back)
if(!src.back)
src.back = W
equipped = 1
if(slot_wear_mask)
if(!src.wear_mask)
src.wear_mask = W
equipped = 1
if(slot_handcuffed)
if(!src.handcuffed)
src.handcuffed = W
equipped = 1
if(slot_l_hand)
if(!src.l_hand)
src.l_hand = W
equipped = 1
if(slot_r_hand)
if(!src.r_hand)
src.r_hand = W
equipped = 1
if(slot_belt)
if(!src.belt && src.w_uniform)
src.belt = W
equipped = 1
if(slot_wear_id)
if(!src.wear_id && src.w_uniform)
src.wear_id = W
equipped = 1
if(slot_l_ear)
if(!src.l_ear)
src.l_ear = W
equipped = 1
if(slot_r_ear)
if(!src.r_ear)
src.r_ear = W
equipped = 1
if(slot_glasses)
if(!src.glasses)
src.glasses = W
equipped = 1
if(slot_gloves)
if(!src.gloves)
src.gloves = W
equipped = 1
if(slot_head)
if(!src.head)
src.head = W
equipped = 1
if(slot_shoes)
if(!src.shoes)
src.shoes = W
equipped = 1
if(slot_wear_suit)
if(!src.wear_suit)
src.wear_suit = W
equipped = 1
if(slot_w_uniform)
if(!src.w_uniform)
src.w_uniform = W
equipped = 1
if(slot_l_store)
if(!src.l_store && src.w_uniform)
src.l_store = W
equipped = 1
if(slot_r_store)
if(!src.r_store && src.w_uniform)
src.r_store = W
equipped = 1
if(slot_s_store)
if(!src.s_store && src.wear_suit)
src.s_store = W
equipped = 1
if(slot_in_backpack)
if (src.back && istype(src.back, /obj/item/weapon/storage/backpack))
var/obj/item/weapon/storage/backpack/B = src.back
if(B.contents.len < B.storage_slots && W.w_class <= B.max_w_class)
W.loc = B
equipped = 1
if(equipped)
W.layer = 20
if(src.back && W.loc != src.back)
W.loc = src
else
if (del_on_fail)
del(W)
return equipped
+105
View File
@@ -0,0 +1,105 @@
/*
Datum based languages. Easily editable and modular.
*/
/datum/language
var/name = "an unknown language" // Fluff name of language if any.
var/desc = "A language." // Short description for 'Check Languages'.
var/speech_verb = "says" // 'says', 'hisses', 'farts'.
var/colour = "body" // CSS style to use for strings in this language.
var/key = "x" // Character used to speak in language eg. :o for Unathi.
var/flags = 0 // Various language flags.
var/native // If set, non-native speakers will have trouble speaking.
/datum/language/unathi
name = "Sinta'unathi"
desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi."
speech_verb = "hisses"
colour = "soghun"
key = "o"
flags = WHITELISTED
/datum/language/tajaran
name = "Siik'tajr"
desc = "An expressive language that combines yowls and chirps with posture, tail and ears. Native to the Tajaran."
speech_verb = "mrowls"
colour = "tajaran"
key = "j"
flags = WHITELISTED
/datum/language/skrell
name = "Skrellian"
desc = "A melodic and complex language spoken by the Skrell of Qerrbalak. Some of the notes are inaudible to humans."
speech_verb = "warbles"
colour = "skrell"
key = "k"
flags = WHITELISTED
/datum/language/vox
name = "Vox-pidgin"
desc = "The common tongue of the various Vox ships making up the Shoal. It sounds like chaotic shrieking to everyone else."
speech_verb = "shrieks"
colour = "vox"
key = "v"
flags = RESTRICTED
/datum/language/diona
name = "Rootspeak"
desc = "A creaking, subvocal language spoken instinctively by the Dionaea. Due to the unique makeup of the average Diona, a phrase of Rootspeak can be a combination of anywhere from one to twelve individual voices and notes."
speech_verb = "creaks and rustles"
colour = "soghun"
key = "q"
flags = RESTRICTED
/datum/language/human
name = "Sol Common"
desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system."
colour = "rough"
key = "1"
flags = RESTRICTED
// Galactic common languages (systemwide accepted standards).
/datum/language/trader
name = "Tradeband"
desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining."
speech_verb = "enunciates"
colour = "say_quote"
key = "2"
/datum/language/gutter
name = "Gutter"
desc = "Much like Standard, this crude pidgin tongue descended from numerous languages and serves as Tradeband for criminal elements."
speech_verb = "growls"
colour = "rough"
key = "3"
// Language handling.
/mob/proc/add_language(var/language)
var/datum/language/new_language = all_languages[language]
if(!istype(new_language) || new_language in languages)
return 0
languages.Add(new_language)
return 1
/mob/proc/remove_language(var/rem_language)
languages.Remove(all_languages[rem_language])
return 0
//TBD
/mob/verb/check_languages()
set name = "Check Known Languages"
set category = "IC"
set src = usr
var/dat = "<b><font size = 5>Known Languages</font></b><br/><br/>"
for(var/datum/language/L in languages)
dat += "<b>[L.name] (:[L.key])</b><br/>[L.desc]<br/><br/>"
src << browse(dat, "window=checklanguage")
return
+259
View File
@@ -0,0 +1,259 @@
/mob/living/blob
name = "blob fragment"
real_name = "blob fragment"
icon = 'icons/mob/blob.dmi'
icon_state = "blob_spore_temp"
pass_flags = PASSBLOB
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
var/ghost_name = "Unknown"
var/creating_blob = 0
faction = "blob"
use_me = 0 //Blobs can't emote
New()
real_name += " [pick(rand(1, 99))]"
name = real_name
..()
say(var/message)
return//No talking for you
emote(var/act,var/m_type=1,var/message = null)
return
Life()
set invisibility = 0
set background = 1
clamp_values()
UpdateDamage()
if(health < 0)
src.dust()
proc/clamp_values()
AdjustStunned(0)
AdjustParalysis(0)
AdjustWeakened(0)
sleeping = 0
if(stat)
stat = CONSCIOUS
return
proc/UpdateDamage()
health = 60 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
return
death(gibbed)
if(key)
var/mob/dead/observer/ghost = new(src)
ghost.name = ghost_name
ghost.real_name = ghost_name
ghost.key = key
if (ghost.client)
ghost.client.eye = ghost
return ..(gibbed)
blob_act()
src << "The blob attempts to reabsorb you."
adjustToxLoss(20)
return
Process_Spacemove()
if(locate(/obj/effect/blob) in oview(1,src))
return 1
return (..())
/mob/living/blob/verb/create_node()
set category = "Blob"
set name = "Create Node"
set desc = "Create a Node."
if(creating_blob) return
var/turf/T = get_turf(src)
creating_blob = 1
if(!T)
creating_blob = 0
return
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
if(!B)//We are on a blob
usr << "There is no blob here!"
creating_blob = 0
return
if(istype(B,/obj/effect/blob/node)||istype(B,/obj/effect/blob/core)||istype(B,/obj/effect/blob/factory))
usr << "Unable to use this blob, find a normal one."
creating_blob = 0
return
for(var/obj/effect/blob/node/blob in orange(5))
usr << "There is another node nearby, move more than 5 tiles away from it!"
creating_blob = 0
return
for(var/obj/effect/blob/factory/blob in orange(2))
usr << "There is a porus blob nearby, move more than 2 tiles away from it!"
creating_blob = 0
B.change_to("Node")
src.dust()
return
/mob/living/blob/verb/create_factory()
set category = "Blob"
set name = "Create Defense"
set desc = "Create a Spore producing blob."
if(creating_blob) return
var/turf/T = get_turf(src)
creating_blob = 1
if(!T)
creating_blob = 0
return
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
if(!B)
usr << "You must be on a blob!"
creating_blob = 0
return
if(istype(B,/obj/effect/blob/node)||istype(B,/obj/effect/blob/core)||istype(B,/obj/effect/blob/factory))
usr << "Unable to use this blob, find a normal one."
creating_blob = 0
return
for(var/obj/effect/blob/blob in orange(2))//Not right next to nodes/cores
if(istype(B,/obj/effect/blob/node))
usr << "There is a node nearby, move away from it!"
creating_blob = 0
return
if(istype(B,/obj/effect/blob/core))
usr << "There is a core nearby, move away from it!"
creating_blob = 0
return
if(istype(B,/obj/effect/blob/factory))
usr << "There is another porous blob nearby, move away from it!"
creating_blob = 0
return
B.change_to("Factory")
src.dust()
return
/mob/living/blob/verb/revert()
set category = "Blob"
set name = "Purge Defense"
set desc = "Removes a porous blob."
if(creating_blob) return
var/turf/T = get_turf(src)
creating_blob = 1
if(!T)
creating_blob = 0
return
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
if(!B)
usr << "You must be on a blob!"
creating_blob = 0
return
if(!istype(B,/obj/effect/blob/factory))
usr << "Unable to use this blob, find another one."
creating_blob = 0
return
B.change_to("Normal")
src.dust()
return
/mob/living/blob/verb/spawn_blob()
set category = "Blob"
set name = "Create new blob"
set desc = "Attempts to create a new blob in this tile."
if(creating_blob) return
var/turf/T = get_turf(src)
creating_blob = 1
if(!T)
creating_blob = 0
return
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
if(B)
usr << "There is a blob here!"
creating_blob = 0
return
new/obj/effect/blob(src.loc)
src.dust()
return
///mob/proc/Blobize()
/client/proc/Blobcount()
set category = "Debug"
set name = "blobreport"
set desc = "blob report."
set hidden = 1
if(!holder)
src << "Only administrators may use this command."
return
if(ticker && ticker.mode)
src << "blobs: [blobs.len]"
src << "cores: [blob_cores.len]"
src << "nodes: [blob_nodes.len]"
return
/client/proc/Blobize()//Mostly stolen from the respawn command
set category = "Debug"
set name = "Ghostblob"
set desc = "Ghost into blobthing."
set hidden = 1
if(!holder)
src << "Only administrators may use this command."
return
var/input = input(src, "Please specify which key will be turned into a bloby.", "Key", "")
var/mob/dead/observer/G_found
if(!input)
var/list/ghosts = list()
for(var/mob/dead/observer/G in player_list)
ghosts += G
if(ghosts.len)
G_found = pick(ghosts)
else
for(var/mob/dead/observer/G in player_list)
if(G.client&&ckey(G.key)==ckey(input))
G_found = G
break
if(!G_found)//If a ghost was not found.
alert("There is no active key like that in the game or the person is not currently a ghost. Aborting command.")
return
if(G_found.client)
G_found.client.screen.len = null
var/mob/living/blob/B = new/mob/living/blob(locate(0,0,1))//temp area also just in case should do this better but tired
if(blob_cores.len > 0)
var/obj/effect/blob/core/core = pick(blob_cores)
if(core)
B.loc = core.loc
B.ghost_name = G_found.real_name
if (G_found.client)
G_found.client.mob = B
B.verbs += /mob/living/blob/verb/create_node
B.verbs += /mob/living/blob/verb/create_factory
B << "<B>You are now a blob fragment.</B>"
B << "You are a weak bit that has temporarily broken off of the blob."
B << "If you stay on the blob for too long you will likely be reabsorbed."
B << "If you stray from the blob you will likely be killed by other organisms."
B << "You have the power to create a new blob node that will help expand the blob."
B << "To create this node you will have to be on a normal blob tile and far enough away from any other node."
B << "Check your Blob verbs and hit Create Node to build a node."
spawn(10)
del(G_found)
@@ -0,0 +1,208 @@
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point
#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point
/mob/living/carbon/alien
name = "alien"
voice_name = "alien"
speak_emote = list("hisses")
icon = 'icons/mob/alien.dmi'
gender = NEUTER
dna = null
var/storedPlasma = 250
var/max_plasma = 500
alien_talk_understand = 1
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = 0
var/move_delay_add = 0 // movement delay to add
status_flags = CANPARALYSE|CANPUSH
var/heal_rate = 1
var/plasma_rate = 5
var/oxygen_alert = 0
var/toxins_alert = 0
var/fire_alert = 0
var/heat_protection = 0.5
/mob/living/carbon/alien/adjustToxLoss(amount)
storedPlasma = min(max(storedPlasma + amount,0),max_plasma) //upper limit of max_plasma, lower limit of 0
return
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
if(amount > 0)
..(amount * 2)
else
..(amount)
return
/mob/living/carbon/alien/proc/getPlasma()
return storedPlasma
/mob/living/carbon/alien/eyecheck()
return 2
/mob/living/carbon/alien/updatehealth()
if(status_flags & GODMODE)
health = maxHealth
stat = CONSCIOUS
else
//oxyloss is only used for suicide
//toxloss isn't used for aliens, its actually used as alien powers!!
health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
/mob/living/carbon/alien/proc/handle_environment(var/datum/gas_mixture/environment)
//If there are alien weeds on the ground then heal if needed or give some toxins
if(locate(/obj/effect/alien/weeds) in loc)
if(health >= maxHealth - getCloneLoss())
adjustToxLoss(plasma_rate)
else
adjustBruteLoss(-heal_rate)
adjustFireLoss(-heal_rate)
adjustOxyLoss(-heal_rate)
if(!environment)
return
var/loc_temp = T0C
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
loc_temp = M.return_temperature()
else if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
loc_temp = heat_turf.temperature
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
loc_temp = loc:air_contents.temperature
else
loc_temp = environment.temperature
//world << "Loc temp: [loc_temp] - Body temp: [bodytemperature] - Fireloss: [getFireLoss()] - Fire protection: [heat_protection] - Location: [loc] - src: [src]"
// Aliens are now weak to fire.
//After then, it reacts to the surrounding atmosphere based on your thermal protection
if(loc_temp > bodytemperature)
//Place is hotter than we are
var/thermal_protection = heat_protection //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(thermal_protection < 1)
bodytemperature += (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
else
bodytemperature += 1 * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
// bodytemperature -= max((loc_temp - bodytemperature / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > 360.15)
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
switch(bodytemperature)
if(360 to 400)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
fire_alert = max(fire_alert, 2)
if(400 to 1000)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
fire_alert = max(fire_alert, 2)
if(1000 to INFINITY)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
fire_alert = max(fire_alert, 2)
return
/mob/living/carbon/alien/proc/handle_mutations_and_radiation()
if(getFireLoss())
if((COLD_RESISTANCE in mutations) || prob(5))
adjustFireLoss(-1)
// Aliens love radiation nom nom nom
if (radiation)
if (radiation > 100)
radiation = 100
if (radiation < 0)
radiation = 0
switch(radiation)
if(1 to 49)
radiation--
if(prob(25))
adjustToxLoss(1)
if(50 to 74)
radiation -= 2
adjustToxLoss(1)
if(prob(5))
radiation -= 5
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
/mob/living/carbon/alien/IsAdvancedToolUser()
return has_fine_manipulation
/mob/living/carbon/alien/Process_Spaceslipping()
return 0 // Don't slip in space.
/mob/living/carbon/alien/Stat()
statpanel("Status")
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
..()
if (client.statpanel == "Status")
stat(null, "Plasma Stored: [getPlasma()]/[max_plasma]")
if(emergency_shuttle)
if(emergency_shuttle.online && emergency_shuttle.location < 2)
var/timeleft = emergency_shuttle.timeleft()
if (timeleft)
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
/mob/living/carbon/alien/Stun(amount)
if(status_flags & CANSTUN)
stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun
else
// add some movement delay
move_delay_add = min(move_delay_add + round(amount / 2), 10) // a maximum delay of 10
return
/mob/living/carbon/alien/getDNA()
return null
/mob/living/carbon/alien/setDNA()
return
/*----------------------------------------
Proc: AddInfectionImages()
Des: Gives the client of the alien an image on each infected mob.
----------------------------------------*/
/mob/living/carbon/alien/proc/AddInfectionImages()
if (client)
for (var/mob/living/C in mob_list)
if(C.status_flags & XENO_HOST)
var/obj/item/alien_embryo/A = locate() in C
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
client.images += I
return
/*----------------------------------------
Proc: RemoveInfectionImages()
Des: Removes all infected images from the alien.
----------------------------------------*/
/mob/living/carbon/alien/proc/RemoveInfectionImages()
if (client)
for(var/image/I in client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
return
#undef HEAT_DAMAGE_LEVEL_1
#undef HEAT_DAMAGE_LEVEL_2
#undef HEAT_DAMAGE_LEVEL_3
@@ -0,0 +1,41 @@
/mob/living/carbon/alien/gib()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("gibbed-a", animation)
xgibs(loc, viruses)
dead_mob_list -= src
spawn(15)
if(animation) del(animation)
if(src) del(src)
/mob/living/carbon/alien/dust()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("dust-a", animation)
new /obj/effect/decal/remains/xeno(loc)
dead_mob_list -= src
spawn(15)
if(animation) del(animation)
if(src) del(src)
@@ -0,0 +1,188 @@
/*NOTES:
These are general powers. Specific powers are stored under the appropriate alien creature type.
*/
/*Alien spit now works like a taser shot. It won't home in on the target but will act the same once it does hit.
Doesn't work on other aliens/AI.*/
/mob/living/carbon/alien/proc/powerc(X, Y)//Y is optional, checks for weed planting. X can be null.
if(stat)
src << "\green You must be conscious to do this."
return 0
else if(X && getPlasma() < X)
src << "\green Not enough plasma stored."
return 0
else if(Y && (!isturf(src.loc) || istype(src.loc, /turf/space)))
src << "\green Bad place for a garden!"
return 0
else return 1
/mob/living/carbon/alien/humanoid/verb/plant()
set name = "Plant Weeds (50)"
set desc = "Plants some alien weeds"
set category = "Alien"
if(powerc(50,1))
adjustToxLoss(-50)
for(var/mob/O in viewers(src, null))
O.show_message(text("\green <B>[src] has planted some alien weeds!</B>"), 1)
new /obj/effect/alien/weeds/node(loc)
return
/*
/mob/living/carbon/alien/humanoid/verb/ActivateHuggers()
set name = "Activate facehuggers (5)"
set desc = "Makes all nearby facehuggers activate"
set category = "Alien"
if(powerc(5))
adjustToxLoss(-5)
for(var/obj/item/clothing/mask/facehugger/F in range(8,src))
F.GoActive()
emote("roar")
return
*/
/mob/living/carbon/alien/humanoid/verb/whisp(mob/M as mob in oview())
set name = "Whisper (10)"
set desc = "Whisper to someone"
set category = "Alien"
if(powerc(10))
adjustToxLoss(-10)
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
log_say("AlienWhisper: [key_name(src)]->[M.key] : [msg]")
M << "\green You hear a strange, alien voice in your head... \italic [msg]"
src << {"\green You said: "[msg]" to [M]"}
return
/mob/living/carbon/alien/humanoid/verb/transfer_plasma(mob/living/carbon/alien/M as mob in oview())
set name = "Transfer Plasma"
set desc = "Transfer Plasma to another alien"
set category = "Alien"
if(isalien(M))
var/amount = input("Amount:", "Transfer Plasma to [M]") as num
if (amount)
amount = abs(round(amount))
if(powerc(amount))
if (get_dist(src,M) <= 1)
M.adjustToxLoss(amount)
adjustToxLoss(-amount)
M << "\green [src] has transfered [amount] plasma to you."
src << {"\green You have trasferred [amount] plasma to [M]"}
else
src << "\green You need to be closer."
return
/mob/living/carbon/alien/humanoid/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N
set name = "Corrossive Acid (200)"
set desc = "Drench an object in acid, destroying it over time."
set category = "Alien"
if(powerc(200))
if(O in oview(1))
// OBJ CHECK
if(isobj(O))
var/obj/I = O
if(I.unacidable) //So the aliens don't destroy energy fields/singularies/other aliens/etc with their acid.
src << "\green You cannot dissolve this object."
return
// TURF CHECK
else if(istype(O, /turf/simulated))
var/turf/T = O
// R WALL
if(istype(T, /turf/simulated/wall/r_wall))
src << "\green You cannot dissolve this object."
return
// R FLOOR
if(istype(T, /turf/simulated/floor/engine))
src << "\green You cannot dissolve this object."
return
else// Not a type we can acid.
return
adjustToxLoss(-200)
new /obj/effect/alien/acid(get_turf(O), O)
visible_message("\green <B>[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!</B>")
else
src << "\green Target is too far away."
return
/mob/living/carbon/alien/humanoid/proc/neurotoxin(mob/target as mob in oview())
set name = "Spit Neurotoxin (50)"
set desc = "Spits neurotoxin at someone, paralyzing them for a short time if they are not wearing protective gear."
set category = "Alien"
if(powerc(50))
if(isalien(target))
src << "\green Your allies are not a valid target."
return
adjustToxLoss(-50)
src << "\green You spit neurotoxin at [target]."
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
O << "\red [src] spits neurotoxin at [target]!"
//I'm not motivated enough to revise this. Prjectile code in general needs update.
var/turf/T = loc
var/turf/U = (istype(target, /atom/movable) ? target.loc : target)
if(!U || !T)
return
while(U && !istype(U,/turf))
U = U.loc
if(!istype(T, /turf))
return
if (U == T)
usr.bullet_act(new /obj/item/projectile/energy/neurotoxin(usr.loc), get_organ_target())
return
if(!istype(U, /turf))
return
var/obj/item/projectile/energy/neurotoxin/A = new /obj/item/projectile/energy/neurotoxin(usr.loc)
A.current = U
A.yo = U.y - T.y
A.xo = U.x - T.x
A.process()
return
/mob/living/carbon/alien/humanoid/proc/resin() // -- TLE
set name = "Secrete Resin (75)"
set desc = "Secrete tough malleable resin."
set category = "Alien"
if(powerc(75))
var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
if(!choice || !powerc(75)) return
adjustToxLoss(-75)
src << "\green You shape a [choice]."
for(var/mob/O in viewers(src, null))
O.show_message(text("\red <B>[src] vomits up a thick purple substance and begins to shape it!</B>"), 1)
switch(choice)
if("resin door")
new /obj/structure/mineral_door/resin(loc)
if("resin wall")
new /obj/effect/alien/resin/wall(loc)
if("resin membrane")
new /obj/effect/alien/resin/membrane(loc)
if("resin nest")
new /obj/structure/stool/bed/nest(loc)
return
/mob/living/carbon/alien/humanoid/verb/regurgitate()
set name = "Regurgitate"
set desc = "Empties the contents of your stomach"
set category = "Alien"
if(powerc())
if(stomach_contents.len)
for(var/mob/M in src)
if(M in stomach_contents)
stomach_contents.Remove(M)
M.loc = loc
//Paralyse(10)
src.visible_message("\green <B>[src] hurls out the contents of their stomach!</B>")
return
@@ -0,0 +1,48 @@
/mob/living/carbon/alien/humanoid/drone
name = "alien drone"
caste = "d"
maxHealth = 100
health = 100
icon_state = "aliend_s"
plasma_rate = 15
/mob/living/carbon/alien/humanoid/drone/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
if(src.name == "alien drone")
src.name = text("alien drone ([rand(1, 1000)])")
src.real_name = src.name
verbs.Add(/mob/living/carbon/alien/humanoid/proc/resin,/mob/living/carbon/alien/humanoid/proc/corrosive_acid)
..()
//Drones use the same base as generic humanoids.
//Drone verbs
/mob/living/carbon/alien/humanoid/drone/verb/evolve() // -- TLE
set name = "Evolve (500)"
set desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
set category = "Alien"
if(powerc(500))
// Queen check
var/no_queen = 1
for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
if(!Q.key && Q.brain_op_stage != 4)
continue
no_queen = 0
if(src.has_brain_worms())
src << "<span class='warning'>We cannot perform this ability at the present time!</span>"
return
if(no_queen)
adjustToxLoss(-500)
src << "\green You begin to evolve!"
for(var/mob/O in viewers(src, null))
O.show_message(text("\green <B>[src] begins to twist and contort!</B>"), 1)
var/mob/living/carbon/alien/humanoid/queen/new_xeno = new (loc)
mind.transfer_to(new_xeno)
del(src)
else
src << "<span class='notice'>We already have an alive queen.</span>"
return
@@ -0,0 +1,76 @@
/mob/living/carbon/alien/humanoid/hunter
name = "alien hunter"
caste = "h"
maxHealth = 150
health = 150
storedPlasma = 100
max_plasma = 150
icon_state = "alienh_s"
plasma_rate = 5
/mob/living/carbon/alien/humanoid/hunter/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
if(name == "alien hunter")
name = text("alien hunter ([rand(1, 1000)])")
real_name = name
..()
/mob/living/carbon/alien/humanoid/hunter
handle_regular_hud_updates()
..() //-Yvarov
if (healths)
if (stat != 2)
switch(health)
if(150 to INFINITY)
healths.icon_state = "health0"
if(100 to 150)
healths.icon_state = "health1"
if(50 to 100)
healths.icon_state = "health2"
if(25 to 50)
healths.icon_state = "health3"
if(0 to 25)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
handle_environment()
if(m_intent == "run" || resting)
..()
else
adjustToxLoss(-heal_rate)
//Hunter verbs
/*
/mob/living/carbon/alien/humanoid/hunter/verb/invis()
set name = "Invisibility (50)"
set desc = "Makes you invisible for 15 seconds"
set category = "Alien"
if(alien_invis)
update_icons()
else
if(powerc(50))
adjustToxLoss(-50)
alien_invis = 1.0
update_icons()
src << "\green You are now invisible."
for(var/mob/O in oviewers(src, null))
O.show_message(text("\red <B>[src] fades into the surroundings!</B>"), 1)
spawn(250)
if(!isnull(src))//Don't want the game to runtime error when the mob no-longer exists.
alien_invis = 0.0
update_icons()
src << "\green You are no longer invisible."
return
*/
@@ -0,0 +1,44 @@
/mob/living/carbon/alien/humanoid/sentinel
name = "alien sentinel"
caste = "s"
maxHealth = 125
health = 125
storedPlasma = 100
max_plasma = 250
icon_state = "aliens_s"
plasma_rate = 10
/mob/living/carbon/alien/humanoid/sentinel/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
if(name == "alien sentinel")
name = text("alien sentinel ([rand(1, 1000)])")
real_name = name
verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin)
..()
/mob/living/carbon/alien/humanoid/sentinel
handle_regular_hud_updates()
..() //-Yvarov
if (healths)
if (stat != 2)
switch(health)
if(125 to INFINITY)
healths.icon_state = "health0"
if(100 to 125)
healths.icon_state = "health1"
if(75 to 100)
healths.icon_state = "health2"
if(25 to 75)
healths.icon_state = "health3"
if(0 to 25)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
@@ -0,0 +1,17 @@
/mob/living/carbon/alien/humanoid/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health6"
stat = DEAD
if(!gibbed)
playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("<B>[src]</B> lets out a waning guttural screech, green blood bubbling from its maw...", 1)
update_canmove()
if(client) blind.layer = 0
update_icons()
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
return ..(gibbed)
@@ -0,0 +1,135 @@
/mob/living/carbon/alien/humanoid/emote(var/act,var/m_type=1,var/message = null)
var/param = null
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
param = copytext(act, t1 + 1, length(act) + 1)
act = copytext(act, 1, t1)
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
switch(act)
if ("me")
if(silent)
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
return custom_emote(m_type, message)
if ("custom")
return custom_emote(m_type, message)
if("sign")
if (!src.restrained())
message = text("<B>The alien</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
m_type = 1
if ("burp")
if (!muzzled)
message = "<B>[src]</B> burps."
m_type = 2
if ("deathgasp")
message = "<B>[src]</B> lets out a waning guttural screech, green blood bubbling from its maw..."
m_type = 2
if("scratch")
if (!src.restrained())
message = "<B>The [src.name]</B> scratches."
m_type = 1
if("whimper")
if (!muzzled)
message = "<B>The [src.name]</B> whimpers."
m_type = 2
if("roar")
if (!muzzled)
message = "<B>The [src.name]</B> roars."
m_type = 2
if("hiss")
if(!muzzled)
message = "<B>The [src.name]</B> hisses."
m_type = 2
if("tail")
message = "<B>The [src.name]</B> waves its tail."
m_type = 1
if("gasp")
message = "<B>The [src.name]</B> gasps."
m_type = 2
if("shiver")
message = "<B>The [src.name]</B> shivers."
m_type = 2
if("drool")
message = "<B>The [src.name]</B> drools."
m_type = 1
if("scretch")
if (!muzzled)
message = "<B>The [src.name]</B> scretches."
m_type = 2
if("choke")
message = "<B>The [src.name]</B> chokes."
m_type = 2
if("moan")
message = "<B>The [src.name]</B> moans!"
m_type = 2
if("nod")
message = "<B>The [src.name]</B> nods its head."
m_type = 1
if("sit")
message = "<B>The [src.name]</B> sits down."
m_type = 1
if("sway")
message = "<B>The [src.name]</B> sways around dizzily."
m_type = 1
if("sulk")
message = "<B>The [src.name]</B> sulks down sadly."
m_type = 1
if("twitch")
message = "<B>The [src.name]</B> twitches violently."
m_type = 1
if("dance")
if (!src.restrained())
message = "<B>The [src.name]</B> dances around happily."
m_type = 1
if("roll")
if (!src.restrained())
message = "<B>The [src.name]</B> rolls."
m_type = 1
if("shake")
message = "<B>The [src.name]</B> shakes its head."
m_type = 1
if("gnarl")
if (!muzzled)
message = "<B>The [src.name]</B> gnarls and shows its teeth.."
m_type = 2
if("jump")
message = "<B>The [src.name]</B> jumps!"
m_type = 1
if("collapse")
Paralyse(2)
message = text("<B>[]</B> collapses!", src)
m_type = 2
if("help")
src << "burp, deathgasp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
else
src << text("Invalid Emote: []", act)
if ((message && src.stat == 0))
log_emote("[name]/[key] : [message]")
if (act == "roar")
playsound(src.loc, 'sound/voice/hiss5.ogg', 40, 1, 1)
if (act == "deathgasp")
playsound(src.loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
if (m_type & 1)
for(var/mob/O in viewers(src, null))
O.show_message(message, m_type)
//Foreach goto(703)
else
for(var/mob/O in hearers(src, null))
O.show_message(message, m_type)
//Foreach goto(746)
return
@@ -0,0 +1,423 @@
/mob/living/carbon/alien/humanoid
name = "alien"
icon_state = "alien_s"
var/obj/item/clothing/suit/wear_suit = null //TODO: necessary? Are they even used? ~Carn
var/obj/item/clothing/head/head = null //
var/obj/item/weapon/r_store = null
var/obj/item/weapon/l_store = null
var/caste = ""
update_icon = 1
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/humanoid/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
if(name == "alien")
name = text("alien ([rand(1, 1000)])")
real_name = name
..()
//This is fine, works the same as a human
/mob/living/carbon/alien/humanoid/Bump(atom/movable/AM as mob|obj, yes)
spawn( 0 )
if ((!( yes ) || now_pushing))
return
now_pushing = 0
..()
if (!istype(AM, /atom/movable))
return
if (ismob(AM))
var/mob/tmob = AM
tmob.LAssailant = src
if (!now_pushing)
now_pushing = 1
if (!AM.anchored)
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = 0
return
step(AM, t)
now_pushing = null
return
return
/mob/living/carbon/alien/humanoid/movement_delay()
var/tally = 0
if (istype(src, /mob/living/carbon/alien/humanoid/queen))
tally += 5
if (istype(src, /mob/living/carbon/alien/humanoid/drone))
tally += 2
if (istype(src, /mob/living/carbon/alien/humanoid/sentinel))
tally += 1
if (istype(src, /mob/living/carbon/alien/humanoid/hunter))
tally = -1 // hunters go supersuperfast
return (tally + move_delay_add + config.alien_delay)
///mob/living/carbon/alien/humanoid/bullet_act(var/obj/item/projectile/Proj) taken care of in living
/mob/living/carbon/alien/humanoid/emp_act(severity)
if(wear_suit) wear_suit.emp_act(severity)
if(head) head.emp_act(severity)
if(r_store) r_store.emp_act(severity)
if(l_store) l_store.emp_act(severity)
..()
/mob/living/carbon/alien/humanoid/ex_act(severity)
if(!blinded)
flick("flash", flash)
var/shielded = 0
var/b_loss = null
var/f_loss = null
switch (severity)
if (1.0)
b_loss += 500
gib()
return
if (2.0)
if (!shielded)
b_loss += 60
f_loss += 60
ear_damage += 30
ear_deaf += 120
if(3.0)
b_loss += 30
if (prob(50) && !shielded)
Paralyse(1)
ear_damage += 15
ear_deaf += 60
adjustBruteLoss(b_loss)
adjustFireLoss(f_loss)
updatehealth()
/mob/living/carbon/alien/humanoid/blob_act()
if (stat == 2)
return
var/shielded = 0
var/damage = null
if (stat != 2)
damage = rand(30,40)
if(shielded)
damage /= 4
show_message("\red The blob attacks!")
adjustFireLoss(damage)
return
/mob/living/carbon/alien/humanoid/meteorhit(O as obj)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message(text("\red [] has been hit by []", src, O), 1)
if (health > 0)
adjustFireLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25))
adjustFireLoss(30)
updatehealth()
return
/mob/living/carbon/alien/humanoid/attack_paw(mob/living/carbon/monkey/M as mob)
if(!ismonkey(M)) return//Fix for aliens receiving double messages when attacking other aliens.
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
switch(M.a_intent)
if ("help")
help_shake_act(M)
else
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
if (health > 0)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[M.name] has bit [src]!</B>"), 1)
adjustBruteLoss(rand(1, 3))
updatehealth()
return
/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(istype(M, /mob/living/carbon/slime/adult))
damage = rand(10, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
if(M.powerlevel > 0)
var/stunprob = 10
var/power = M.powerlevel + rand(0,3)
switch(M.powerlevel)
if(1 to 2) stunprob = 20
if(3 to 4) stunprob = 30
if(5 to 6) stunprob = 40
if(7 to 8) stunprob = 60
if(9) stunprob = 70
if(10) stunprob = 95
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] has shocked []!</B>", src), 1)
Weaken(power)
if (stuttering < power)
stuttering = power
Stun(power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return
/mob/living/carbon/alien/humanoid/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
Weaken(5)
if (stuttering < 5)
stuttering = 5
Stun(5)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>", 1, "\red You hear someone fall.", 2)
return
else
M << "\red Not enough charge! "
return
switch(M.a_intent)
if ("help")
if (health > 0)
help_shake_act(M)
else
if (M.health >= -75.0)
if (((M.head && M.head.flags & 4) || ((M.wear_mask && !( M.wear_mask.flags & 32 )) || ((head && head.flags & 4) || (wear_mask && !( wear_mask.flags & 32 ))))))
M << "\blue <B>Remove that mask!</B>"
return
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
O.source = M
O.target = src
O.s_loc = M.loc
O.t_loc = loc
O.place = "CPR"
requests += O
spawn( 0 )
O.process()
return
if ("grab")
if (M == src || anchored)
return
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
M.put_in_active_hand(G)
grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
if ("hurt")
var/damage = rand(1, 9)
if (prob(90))
if (HULK in M.mutations)//HULK SMASH
damage += 14
spawn(0)
Weaken(damage) // Why can a hulk knock an alien out but not knock out a human? Damage is robust enough.
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
playsound(loc, "punch", 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has punched []!</B>", M, src), 1)
if (damage > 9||prob(5))//Regular humans have a very small chance of weakening an alien.
Weaken(1,5)
for(var/mob/O in viewers(M, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has weakened []!</B>", M, src), 1, "\red You hear someone fall.", 2)
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has attempted to punch []!</B>", M, src), 1)
if ("disarm")
if (!lying)
if (prob(5))//Very small chance to push an alien down.
Weaken(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has pushed down []!</B>", M, src), 1)
else
if (prob(50))
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed []!</B>", M, src), 1)
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has attempted to disarm []!</B>", M, src), 1)
return
/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
In all, this is a lot like the monkey code. /N
*/
/mob/living/carbon/alien/humanoid/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
switch(M.a_intent)
if ("help")
sleeping = max(0,sleeping-5)
resting = 0
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\blue [M.name] nuzzles [] trying to wake it up!", src), 1)
else
if (health > 0)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
var/damage = rand(1, 3)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[M.name] has bit []!</B>", src), 1)
adjustBruteLoss(damage)
updatehealth()
else
M << "\green <B>[name] is too injured for that.</B>"
return
/mob/living/carbon/alien/humanoid/restrained()
if (handcuffed)
return 1
return 0
/mob/living/carbon/alien/humanoid/var/co2overloadtime = null
/mob/living/carbon/alien/humanoid/var/temperature_resistance = T0C+75
/mob/living/carbon/alien/humanoid/show_inv(mob/user as mob)
user.set_machine(src)
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? text("[]", l_hand) : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? text("[]", r_hand) : "Nothing")]</A>
<BR><B>Head:</B> <A href='?src=\ref[src];item=head'>[(head ? text("[]", head) : "Nothing")]</A>
<BR><B>(Exo)Suit:</B> <A href='?src=\ref[src];item=suit'>[(wear_suit ? text("[]", wear_suit) : "Nothing")]</A>
<BR><A href='?src=\ref[src];item=pockets'>Empty Pouches</A>
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
<BR>"}
user << browse(dat, text("window=mob[name];size=340x480"))
onclose(user, "mob[name]")
return
@@ -0,0 +1,54 @@
//unequip
/mob/living/carbon/alien/humanoid/u_equip(obj/item/W as obj)
if (W == wear_suit)
wear_suit = null
update_inv_wear_suit(0)
else if (W == head)
head = null
update_inv_head(0)
else if (W == r_store)
r_store = null
update_inv_pockets(0)
else if (W == l_store)
l_store = null
update_inv_pockets(0)
else if (W == r_hand)
r_hand = null
update_inv_r_hand(0)
else if (W == l_hand)
l_hand = null
update_inv_l_hand(0)
/mob/living/carbon/alien/humanoid/attack_ui(slot_id)
var/obj/item/W = get_active_hand()
if(W)
if(!istype(W)) return
switch(slot_id)
// if("o_clothing")
// if("head")
if(slot_l_store)
if(l_store)
return
if(W.w_class > 3)
return
u_equip(W)
l_store = W
update_inv_pockets()
if(slot_r_store)
if(r_store)
return
if(W.w_class > 3)
return
u_equip(W)
r_store = W
update_inv_pockets()
else
switch(slot_id)
if(slot_wear_suit)
if(wear_suit) wear_suit.attack_alien(src)
if(slot_head)
if(head) head.attack_alien(src)
if(slot_l_store)
if(l_store) l_store.attack_alien(src)
if(slot_r_store)
if(r_store) r_store.attack_alien(src)
@@ -0,0 +1,463 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/alien/humanoid
oxygen_alert = 0
toxins_alert = 0
fire_alert = 0
var/temperature_alert = 0
/mob/living/carbon/alien/humanoid/Life()
set invisibility = 0
set background = 1
if (monkeyizing)
return
..()
var/datum/gas_mixture/environment = loc.return_air()
if (stat != DEAD) //still breathing
//First, resolve location and get a breath
if(air_master.current_cycle%4==2)
//Only try to take a breath every 4 seconds, unless suffocating
spawn(0) breathe()
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
//Mutations and radiation
handle_mutations_and_radiation()
//Chemicals in the body
handle_chemicals_in_body()
//Disabilities
handle_disabilities()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
blinded = null
//Handle temperature/pressure differences between body and environment
handle_environment(environment)
//stuff in the stomach
handle_stomach()
//Status updates, death etc.
handle_regular_status_updates()
update_canmove()
// Grabbing
for(var/obj/item/weapon/grab/G in src)
G.process()
if(client)
handle_regular_hud_updates()
/mob/living/carbon/alien/humanoid
proc/handle_disabilities()
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 10))
src << "\red You have a seizure!"
Paralyse(10)
if (disabilities & COUGHING)
if ((prob(5) && paralysis <= 1))
drop_item()
spawn( 0 )
emote("cough")
return
if (disabilities & TOURETTES)
if ((prob(10) && paralysis <= 1))
Stun(10)
spawn( 0 )
emote("twitch")
return
if (disabilities & NERVOUS)
if (prob(10))
stuttering = max(10, stuttering)
proc/breathe()
if(reagents)
if(reagents.has_reagent("lexorin")) return
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
// HACK NEED CHANGING LATER
if(health < 0)
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(75)) //High chance of gasping for air
spawn emote("gasp")
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
else
//First, check for air from internal atmosphere (using an air tank and mask generally)
breath = get_breath_from_internal(BREATH_VOLUME)
//No breath from internal atmosphere so get breath from location
if(!breath)
if(istype(loc, /obj/))
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = 0
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
else*/
// Not enough air around, take a percentage of what's there to model this properly
breath_moles = environment.total_moles()*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
// Handle chem smoke effect -- Doohl
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
handle_breath(breath)
if(breath)
loc.assume_air(breath)
proc/get_breath_from_internal(volume_needed)
if(internal)
if (!contents.Find(internal))
internal = null
if (!wear_mask || !(wear_mask.flags & MASKINTERNALS) )
internal = null
if(internal)
if (internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed)
else
if (internals)
internals.icon_state = "internal0"
return null
proc/handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return
if(!breath || (breath.total_moles == 0))
//Aliens breathe in vaccuum
return 0
var/toxins_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
if(Toxins_pp) // Detect toxins in air
adjustToxLoss(breath.toxins*250)
toxins_alert = max(toxins_alert, 1)
toxins_used = breath.toxins
else
toxins_alert = 0
//Breathe in toxins and out oxygen
breath.toxins -= toxins_used
breath.oxygen += toxins_used
if(breath.temperature > (T0C+66) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :(
if(prob(20))
src << "\red You feel a searing heat in your lungs!"
fire_alert = max(fire_alert, 1)
else
fire_alert = 0
//Temporary fixes to the alerts.
return 1
proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
var/difference = abs(current-loc_temp) //get difference
var/increments// = difference/10 //find how many increments apart they are
if(difference > 50)
increments = difference/5
else
increments = difference/10
var/change = increments*boost // Get the amount to change by (x per increment)
var/temp_change
if(current < loc_temp)
temperature = min(loc_temp, temperature+change)
else if(current > loc_temp)
temperature = max(loc_temp, temperature-change)
temp_change = (temperature - current)
return temp_change
/*
proc/get_thermal_protection()
var/thermal_protection = 1.0
//Handle normal clothing
if(head && (head.body_parts_covered & HEAD))
thermal_protection += 0.5
if(wear_suit && (wear_suit.body_parts_covered & UPPER_TORSO))
thermal_protection += 0.5
if(wear_suit && (wear_suit.body_parts_covered & LEGS))
thermal_protection += 0.2
if(wear_suit && (wear_suit.body_parts_covered & ARMS))
thermal_protection += 0.2
if(wear_suit && (wear_suit.body_parts_covered & HANDS))
thermal_protection += 0.2
if(wear_suit && (wear_suit.flags & SUITSPACE))
thermal_protection += 3
if(COLD_RESISTANCE in mutations)
thermal_protection += 5
return thermal_protection
proc/add_fire_protection(var/temp)
var/fire_prot = 0
if(head)
if(head.protective_temperature > temp)
fire_prot += (head.protective_temperature/10)
if(wear_mask)
if(wear_mask.protective_temperature > temp)
fire_prot += (wear_mask.protective_temperature/10)
if(wear_suit)
if(wear_suit.protective_temperature > temp)
fire_prot += (wear_suit.protective_temperature/10)
return fire_prot
*/
proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
if(FAT in mutations)
if(nutrition < 100)
if(prob(round((50 - nutrition) / 100)))
src << "\blue You feel fit again!"
mutations.Remove(FAT)
/* else
if(nutrition > 500)
if(prob(5 + round((nutrition - 200) / 2)))
src << "\red You suddenly feel blubbery!"
mutations.Add(FAT)
FUCK YOU FATCODE -Hawk */
if (nutrition > 0)
nutrition -= HUNGER_FACTOR
if (drowsyness)
drowsyness--
eye_blurry = max(2, eye_blurry)
if (prob(5))
sleeping += 1
Paralyse(5)
confused = max(0, confused - 1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 5)
jitteriness = max(0, jitteriness - 5)
else
dizziness = max(0, dizziness - 1)
jitteriness = max(0, jitteriness - 1)
updatehealth()
return //TODO: DEFERRED
proc/handle_regular_status_updates()
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
silent = 0
else //ALIVE. LIGHTS ARE ON
if(health < config.health_threshold_dead || brain_op_stage == 4.0)
death()
blinded = 1
stat = DEAD
silent = 0
return 1
//UNCONSCIOUS. NO-ONE IS HOME
if( (getOxyLoss() > 50) || (config.health_threshold_crit > health) )
if( health <= 20 && prob(1) )
spawn(0)
emote("gasp")
if(!reagents.has_reagent("inaprovaline"))
adjustOxyLoss(1)
Paralyse(3)
if(paralysis)
AdjustParalysis(-1)
blinded = 1
stat = UNCONSCIOUS
else if(sleeping)
sleeping = max(sleeping-1, 0)
blinded = 1
stat = UNCONSCIOUS
if( prob(10) && health )
spawn(0)
emote("hiss")
//CONSCIOUS
else
stat = CONSCIOUS
/* What in the living hell is this?*/
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
//Eyes
if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) //blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
blinded = 1
else if(eye_blurry) //blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
//Ears
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
ear_deaf = max(ear_deaf, 1)
else if(ear_deaf) //deafness, heals slowly over time
ear_deaf = max(ear_deaf-1, 0)
else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
ear_damage = max(ear_damage-0.05, 0)
//Other
if(stunned)
AdjustStunned(-1)
if(!stunned)
update_icons()
if(weakened)
weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
if(stuttering)
stuttering = max(stuttering-1, 0)
if(silent)
silent = max(silent-1, 0)
if(druggy)
druggy = max(druggy-1, 0)
return 1
proc/handle_regular_hud_updates()
if (stat == 2 || (XRAY in mutations))
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight |= SEE_MOBS
sight &= ~SEE_TURFS
sight &= ~SEE_OBJS
see_in_dark = 4
see_invisible = SEE_INVISIBLE_LEVEL_TWO
if (healths)
if (stat != 2)
switch(health)
if(100 to INFINITY)
healths.icon_state = "health0"
if(75 to 100)
healths.icon_state = "health1"
if(50 to 75)
healths.icon_state = "health2"
if(25 to 50)
healths.icon_state = "health3"
if(0 to 25)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
if (toxin) toxin.icon_state = "tox[toxins_alert ? 1 : 0]"
if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]"
if (fire) fire.icon_state = "fire[fire_alert ? 1 : 0]"
//NOTE: the alerts dont reset when youre out of danger. dont blame me,
//blame the person who coded them. Temporary fix added.
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((blind && stat != 2))
if ((blinded))
blind.layer = 18
else
blind.layer = 0
if (disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if (eye_blurry)
client.screen += global_hud.blurry
if (druggy)
client.screen += global_hud.druggy
if (stat != 2)
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
return 1
proc/handle_stomach()
spawn(0)
for(var/mob/living/M in stomach_contents)
if(M.loc != src)
stomach_contents.Remove(M)
continue
if(istype(M, /mob/living/carbon) && stat != 2)
if(M.stat == 2)
M.death(1)
stomach_contents.Remove(M)
del(M)
continue
if(air_master.current_cycle%3==1)
if(!(status_flags & GODMODE))
M.adjustBruteLoss(5)
nutrition += 10
@@ -0,0 +1,7 @@
/mob/living/carbon/alien/humanoid/Login()
..()
update_hud()
if(!isturf(loc))
client.eye = loc
client.perspective = EYE_PERSPECTIVE
return
@@ -0,0 +1,92 @@
/mob/living/carbon/alien/humanoid/queen
name = "alien queen"
caste = "q"
maxHealth = 250
health = 250
icon_state = "alienq_s"
status_flags = CANPARALYSE
heal_rate = 5
plasma_rate = 20
/mob/living/carbon/alien/humanoid/queen/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
//there should only be one queen
for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
if(Q == src) continue
if(Q.stat == DEAD) continue
if(Q.client)
name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
break
real_name = src.name
verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin,/mob/living/carbon/alien/humanoid/proc/resin)
verbs -= /mob/living/carbon/alien/verb/ventcrawl
..()
/mob/living/carbon/alien/humanoid/queen
handle_regular_hud_updates()
..() //-Yvarov
if (src.healths)
if (src.stat != 2)
switch(health)
if(250 to INFINITY)
src.healths.icon_state = "health0"
if(175 to 250)
src.healths.icon_state = "health1"
if(100 to 175)
src.healths.icon_state = "health2"
if(50 to 100)
src.healths.icon_state = "health3"
if(0 to 50)
src.healths.icon_state = "health4"
else
src.healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
//Queen verbs
/mob/living/carbon/alien/humanoid/queen/verb/lay_egg()
set name = "Lay Egg (75)"
set desc = "Lay an egg to produce huggers to impregnate prey with."
set category = "Alien"
if(locate(/obj/effect/alien/egg) in get_turf(src))
src << "There's already an egg here."
return
if(powerc(75,1))//Can't plant eggs on spess tiles. That's silly.
adjustToxLoss(-75)
for(var/mob/O in viewers(src, null))
O.show_message(text("\green <B>[src] has laid an egg!</B>"), 1)
new /obj/effect/alien/egg(loc)
return
/mob/living/carbon/alien/humanoid/queen/large
icon = 'icons/mob/alienqueen.dmi'
icon_state = "queen_s"
pixel_x = -16
/mob/living/carbon/alien/humanoid/queen/large/update_icons()
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
update_hud() //TODO: remove the need for this to be here
overlays.Cut()
if(lying)
if(resting) icon_state = "queen_sleep"
else icon_state = "queen_l"
for(var/image/I in overlays_lying)
overlays += I
else
icon_state = "queen_s"
for(var/image/I in overlays_standing)
overlays += I
@@ -0,0 +1,154 @@
//Xeno Overlays Indexes//////////
#define X_HEAD_LAYER 1
#define X_SUIT_LAYER 2
#define X_L_HAND_LAYER 3
#define X_R_HAND_LAYER 4
#define TARGETED_LAYER 5
#define X_TOTAL_LAYERS 5
/////////////////////////////////
/mob/living/carbon/alien/humanoid
var/list/overlays_lying[X_TOTAL_LAYERS]
var/list/overlays_standing[X_TOTAL_LAYERS]
/mob/living/carbon/alien/humanoid/update_icons()
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
update_hud() //TODO: remove the need for this to be here
overlays.Cut()
if(stat == DEAD)
//If we mostly took damage from fire
if(fireloss > 125)
icon_state = "alien[caste]_husked"
else
icon_state = "alien[caste]_dead"
for(var/image/I in overlays_lying)
overlays += I
else if(lying)
if(resting)
icon_state = "alien[caste]_sleep"
else if(stat == UNCONSCIOUS)
icon_state = "alien[caste]_unconscious"
else
icon_state = "alien[caste]_l"
for(var/image/I in overlays_lying)
overlays += I
else
if(m_intent == "run") icon_state = "alien[caste]_running"
else icon_state = "alien[caste]_s"
for(var/image/I in overlays_standing)
overlays += I
/mob/living/carbon/alien/humanoid/regenerate_icons()
..()
if (monkeyizing) return
update_inv_head(0)
update_inv_wear_suit(0)
update_inv_r_hand(0)
update_inv_l_hand(0)
update_inv_pockets(0)
update_hud()
update_icons()
/mob/living/carbon/alien/humanoid/update_hud()
//TODO
if (client)
// if(other) client.screen |= hud_used.other //Not used
// else client.screen -= hud_used.other //Not used
client.screen |= contents
/mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1)
if(wear_suit)
var/t_state = wear_suit.item_state
if(!t_state) t_state = wear_suit.icon_state
var/image/lying = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]2")
var/image/standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]")
if(wear_suit.blood_DNA)
var/t_suit = "suit"
if( istype(wear_suit, /obj/item/clothing/suit/armor) )
t_suit = "armor"
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood")
//TODO
wear_suit.screen_loc = ui_alien_oclothing
if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
drop_from_inventory(handcuffed)
drop_r_hand()
drop_l_hand()
overlays_lying[X_SUIT_LAYER] = lying
overlays_standing[X_SUIT_LAYER] = standing
else
overlays_lying[X_SUIT_LAYER] = null
overlays_standing[X_SUIT_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/alien/humanoid/update_inv_head(var/update_icons=1)
if (head)
var/t_state = head.item_state
if(!t_state) t_state = head.icon_state
var/image/lying = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]2")
var/image/standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]")
if(head.blood_DNA)
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood2")
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
head.screen_loc = ui_alien_head
overlays_lying[X_HEAD_LAYER] = lying
overlays_standing[X_HEAD_LAYER] = standing
else
overlays_lying[X_HEAD_LAYER] = null
overlays_standing[X_HEAD_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/alien/humanoid/update_inv_pockets(var/update_icons=1)
if(l_store) l_store.screen_loc = ui_storage1
if(r_store) r_store.screen_loc = ui_storage2
if(update_icons) update_icons()
/mob/living/carbon/alien/humanoid/update_inv_r_hand(var/update_icons=1)
if(r_hand)
var/t_state = r_hand.item_state
if(!t_state) t_state = r_hand.icon_state
r_hand.screen_loc = ui_rhand
overlays_standing[X_R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = t_state)
else
overlays_standing[X_R_HAND_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/alien/humanoid/update_inv_l_hand(var/update_icons=1)
if(l_hand)
var/t_state = l_hand.item_state
if(!t_state) t_state = l_hand.icon_state
l_hand.screen_loc = ui_lhand
overlays_standing[X_L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = t_state)
else
overlays_standing[X_L_HAND_LAYER] = null
if(update_icons) update_icons()
//Call when target overlay should be added/removed
/mob/living/carbon/alien/humanoid/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_lying[TARGETED_LAYER] = target_locked
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_lying[TARGETED_LAYER] = null
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
//Xeno Overlays Indexes//////////
#undef X_HEAD_LAYER
#undef X_SUIT_LAYER
#undef X_L_HAND_LAYER
#undef X_R_HAND_LAYER
#undef TARGETED_LAYER
#undef X_TOTAL_LAYERS
@@ -0,0 +1,15 @@
/mob/living/carbon/alien/larva/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health6"
stat = DEAD
icon_state = "larva_dead"
if(!gibbed)
update_canmove()
if(client) blind.layer = 0
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
living_mob_list -= src
return ..(gibbed)
@@ -0,0 +1,127 @@
/mob/living/carbon/alien/larva/emote(var/act,var/m_type=1,var/message = null)
var/param = null
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
param = copytext(act, t1 + 1, length(act) + 1)
act = copytext(act, 1, t1)
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
switch(act)
if ("me")
if(silent)
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
return custom_emote(m_type, message)
if ("custom")
return custom_emote(m_type, message)
if("sign")
if (!src.restrained())
message = text("<B>The alien</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
m_type = 1
if ("burp")
if (!muzzled)
message = "<B>[src]</B> burps."
m_type = 2
if("scratch")
if (!src.restrained())
message = "<B>The [src.name]</B> scratches."
m_type = 1
if("whimper")
if (!muzzled)
message = "<B>The [src.name]</B> whimpers."
m_type = 2
// if("roar")
// if (!muzzled)
// message = "<B>The [src.name]</B> roars." Commenting out since larva shouldn't roar /N
// m_type = 2
if("tail")
message = "<B>The [src.name]</B> waves its tail."
m_type = 1
if("gasp")
message = "<B>The [src.name]</B> gasps."
m_type = 2
if("shiver")
message = "<B>The [src.name]</B> shivers."
m_type = 2
if("drool")
message = "<B>The [src.name]</B> drools."
m_type = 1
if("scretch")
if (!muzzled)
message = "<B>The [src.name]</B> scretches."
m_type = 2
if("choke")
message = "<B>The [src.name]</B> chokes."
m_type = 2
if("moan")
message = "<B>The [src.name]</B> moans!"
m_type = 2
if("nod")
message = "<B>The [src.name]</B> nods its head."
m_type = 1
// if("sit")
// message = "<B>The [src.name]</B> sits down." //Larvan can't sit down, /N
// m_type = 1
if("sway")
message = "<B>The [src.name]</B> sways around dizzily."
m_type = 1
if("sulk")
message = "<B>The [src.name]</B> sulks down sadly."
m_type = 1
if("twitch")
message = "<B>The [src.name]</B> twitches violently."
m_type = 1
if("dance")
if (!src.restrained())
message = "<B>The [src.name]</B> dances around happily."
m_type = 1
if("roll")
if (!src.restrained())
message = "<B>The [src.name]</B> rolls."
m_type = 1
if("shake")
message = "<B>The [src.name]</B> shakes its head."
m_type = 1
if("gnarl")
if (!muzzled)
message = "<B>The [src.name]</B> gnarls and shows its teeth.."
m_type = 2
if("jump")
message = "<B>The [src.name]</B> jumps!"
m_type = 1
if("hiss_")
message = "<B>The [src.name]</B> hisses softly."
m_type = 1
if("collapse")
Paralyse(2)
message = text("<B>[]</B> collapses!", src)
m_type = 2
if("help")
src << "burp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper"
else
src << text("Invalid Emote: []", act)
if ((message && src.stat == 0))
log_emote("[name]/[key] : [message]")
if (m_type & 1)
for(var/mob/O in viewers(src, null))
O.show_message(message, m_type)
//Foreach goto(703)
else
for(var/mob/O in hearers(src, null))
O.show_message(message, m_type)
//Foreach goto(746)
return
@@ -0,0 +1,3 @@
//can't unequip since it can't equip anything
/mob/living/carbon/alien/larva/u_equip(obj/item/W as obj)
return
@@ -0,0 +1,375 @@
/mob/living/carbon/alien/larva
name = "alien larva"
real_name = "alien larva"
icon_state = "larva0"
pass_flags = PASSTABLE
maxHealth = 25
health = 25
storedPlasma = 50
max_plasma = 50
var/amount_grown = 0
var/max_grown = 200
var/time_of_birth
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
if(name == "alien larva")
name = "alien larva ([rand(1, 1000)])"
real_name = name
regenerate_icons()
..()
//This is fine, works the same as a human
/mob/living/carbon/alien/larva/Bump(atom/movable/AM as mob|obj, yes)
spawn( 0 )
if ((!( yes ) || now_pushing))
return
now_pushing = 1
if(ismob(AM))
var/mob/tmob = AM
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(prob(70))
src << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
now_pushing = 0
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
tmob.LAssailant = src
now_pushing = 0
..()
if (!( istype(AM, /atom/movable) ))
return
if (!( now_pushing ))
now_pushing = 1
if (!( AM.anchored ))
var/t = get_dir(src, AM)
step(AM, t)
now_pushing = null
return
return
//This needs to be fixed
/mob/living/carbon/alien/larva/Stat()
..()
stat(null, "Progress: [amount_grown]/[max_grown]")
/mob/living/carbon/alien/larva/adjustToxLoss(amount)
if(stat != DEAD)
amount_grown = min(amount_grown + 1, max_grown)
..(amount)
/mob/living/carbon/alien/larva/ex_act(severity)
if(!blinded)
flick("flash", flash)
var/b_loss = null
var/f_loss = null
switch (severity)
if (1.0)
b_loss += 500
gib()
return
if (2.0)
b_loss += 60
f_loss += 60
ear_damage += 30
ear_deaf += 120
if(3.0)
b_loss += 30
if (prob(50))
Paralyse(1)
ear_damage += 15
ear_deaf += 60
adjustBruteLoss(b_loss)
adjustFireLoss(f_loss)
updatehealth()
/mob/living/carbon/alien/larva/blob_act()
if (stat == 2)
return
var/shielded = 0
var/damage = null
if (stat != 2)
damage = rand(10,30)
if(shielded)
damage /= 4
//paralysis += 1
show_message("\red The blob attacks you!")
adjustFireLoss(damage)
updatehealth()
return
//can't equip anything
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
/mob/living/carbon/alien/larva/meteorhit(O as obj)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message(text("\red [] has been hit by []", src, O), 1)
if (health > 0)
adjustBruteLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25))
adjustFireLoss(30)
updatehealth()
return
/mob/living/carbon/alien/larva/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
updatehealth()
/mob/living/carbon/alien/larva/attack_paw(mob/living/carbon/monkey/M as mob)
if(!(istype(M, /mob/living/carbon/monkey))) return//Fix for aliens receiving double messages when attacking other aliens.
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
switch(M.a_intent)
if ("help")
help_shake_act(M)
else
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
if (health > 0)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[M.name] has bit [src]!</B>"), 1)
adjustBruteLoss(rand(1, 3))
updatehealth()
return
/mob/living/carbon/alien/larva/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(istype(src, /mob/living/carbon/slime/adult))
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
Weaken(5)
if (stuttering < 5)
stuttering = 5
Stun(5)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>", 1, "\red You hear someone fall.", 2)
return
else
M << "\red Not enough charge! "
return
switch(M.a_intent)
if ("help")
if (health > 0)
help_shake_act(M)
else
if (M.health >= -75.0)
if ((M.head && M.head.flags & 4) || (M.wear_mask && !( M.wear_mask.flags & 32 )) )
M << "\blue <B>Remove that mask!</B>"
return
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
O.source = M
O.target = src
O.s_loc = M.loc
O.t_loc = loc
O.place = "CPR"
requests += O
spawn( 0 )
O.process()
return
if ("grab")
if (M == src)
return
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
M.put_in_active_hand(G)
grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
else
var/damage = rand(1, 9)
if (prob(90))
if (HULK in M.mutations)
damage += 5
spawn(0)
Paralyse(1)
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
playsound(loc, "punch", 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has punched []!</B>", M, src), 1)
if (damage > 4.9)
Weaken(rand(10,15))
for(var/mob/O in viewers(M, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has weakened []!</B>", M, src), 1, "\red You hear someone fall.", 2)
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has attempted to punch []!</B>", M, src), 1)
return
/mob/living/carbon/alien/larva/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
..()
switch(M.a_intent)
if ("help")
sleeping = max(0,sleeping-5)
resting = 0
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\blue [M.name] nuzzles [] trying to wake it up!", src), 1)
else
if (health > 0)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
var/damage = rand(1, 3)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[M.name] has bit []!</B>", src), 1)
adjustBruteLoss(damage)
updatehealth()
else
M << "\green <B>[name] is too injured for that.</B>"
return
/mob/living/carbon/alien/larva/restrained()
return 0
/mob/living/carbon/alien/larva/var/co2overloadtime = null
/mob/living/carbon/alien/larva/var/temperature_resistance = T0C+75
// new damage icon system
// now constructs damage icon for each organ from mask * damage field
/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
user.set_machine(src)
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR><BR>
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
<BR>"}
user << browse(dat, text("window=mob[name];size=340x480"))
onclose(user, "mob[name]")
return
/* Commented out because it's duplicated in life.dm
/mob/living/carbon/alien/larva/proc/grow() // Larvae can grow into full fledged Xenos if they survive long enough -- TLE
if(icon_state == "larva_l" && !canmove) // This is a shit death check. It is made of shit and death. Fix later.
return
else
var/mob/living/carbon/alien/humanoid/A = new(loc)
A.key = key
del(src) */
@@ -0,0 +1,382 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/alien/larva
var/temperature_alert = 0
/mob/living/carbon/alien/larva/Life()
set invisibility = 0
set background = 1
if (monkeyizing)
return
..()
var/datum/gas_mixture/enviroment = loc.return_air()
if (stat != DEAD) //still breathing
// GROW!
if(amount_grown < max_grown)
amount_grown++
//First, resolve location and get a breath
if(air_master.current_cycle%4==2)
//Only try to take a breath every 4 seconds, unless suffocating
spawn(0) breathe()
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
//Mutations and radiation
handle_mutations_and_radiation()
//Chemicals in the body
handle_chemicals_in_body()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
blinded = null
//Handle temperature/pressure differences between body and environment
handle_environment(enviroment)
//stuff in the stomach
//handle_stomach()
//Status updates, death etc.
handle_regular_status_updates()
update_canmove()
// Grabbing
for(var/obj/item/weapon/grab/G in src)
G.process()
//some kind of bug in canmove() isn't properly calling update_icons, so this is here as a placeholder
update_icons()
if(client)
handle_regular_hud_updates()
/mob/living/carbon/alien/larva
proc/breathe()
if(reagents.has_reagent("lexorin")) return
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
// HACK NEED CHANGING LATER
if(health < 0)
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(75)) //High chance of gasping for air
spawn emote("gasp")
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
else
//First, check for air from internal atmosphere (using an air tank and mask generally)
breath = get_breath_from_internal(BREATH_VOLUME)
//No breath from internal atmosphere so get breath from location
if(!breath)
if(istype(loc, /obj/))
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = 0
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
else*/
// Not enough air around, take a percentage of what's there to model this properly
breath_moles = environment.total_moles()*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
// Handle chem smoke effect -- Doohl
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
handle_breath(breath)
if(breath)
loc.assume_air(breath)
proc/get_breath_from_internal(volume_needed)
if(internal)
if (!contents.Find(internal))
internal = null
if (!wear_mask || !(wear_mask.flags & MASKINTERNALS) )
internal = null
if(internal)
if (internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed)
else
if (internals)
internals.icon_state = "internal0"
return null
proc/handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return
if(!breath || (breath.total_moles == 0))
//Aliens breathe in vaccuum
return 0
var/toxins_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
if(Toxins_pp) // Detect toxins in air
adjustToxLoss(breath.toxins*250)
toxins_alert = max(toxins_alert, 1)
toxins_used = breath.toxins
else
toxins_alert = 0
//Breathe in toxins and out oxygen
breath.toxins -= toxins_used
breath.oxygen += toxins_used
if(breath.temperature > (T0C+66) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :(
if(prob(20))
src << "\red You feel a searing heat in your lungs!"
fire_alert = max(fire_alert, 1)
else
fire_alert = 0
//Temporary fixes to the alerts.
return 1
proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
if(FAT in mutations)
if(nutrition < 100)
if(prob(round((50 - nutrition) / 100)))
src << "\blue You feel fit again!"
mutations.Add(FAT)
/* else
if(nutrition > 500)
if(prob(5 + round((nutrition - max_grown) / 2)))
src << "\red You suddenly feel blubbery!"
mutations.Add(FAT)
FUCK YOU MORE FAT CODE -Hawk*/
if (nutrition > 0)
nutrition-= HUNGER_FACTOR
if (drowsyness)
drowsyness--
eye_blurry = max(2, eye_blurry)
if (prob(5))
sleeping += 1
Paralyse(5)
confused = max(0, confused - 1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 5)
jitteriness = max(0, jitteriness - 5)
else
dizziness = max(0, dizziness - 1)
jitteriness = max(0, jitteriness - 1)
updatehealth()
return //TODO: DEFERRED
proc/handle_regular_status_updates()
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
silent = 0
else //ALIVE. LIGHTS ARE ON
if(health < -25 || brain_op_stage == 4.0)
death()
blinded = 1
silent = 0
return 1
//UNCONSCIOUS. NO-ONE IS HOME
if( (getOxyLoss() > 25) || (0 > health) )
//if( health <= 20 && prob(1) )
// spawn(0)
// emote("gasp")
if(!reagents.has_reagent("inaprovaline"))
adjustOxyLoss(1)
Paralyse(3)
if(paralysis)
AdjustParalysis(-2)
blinded = 1
stat = UNCONSCIOUS
else if(sleeping)
sleeping = max(sleeping-1, 0)
blinded = 1
stat = UNCONSCIOUS
if( prob(10) && health )
spawn(0)
emote("hiss_")
//CONSCIOUS
else
stat = CONSCIOUS
/* What in the living hell is this?*/
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - rand(1, 2))
//Eyes
if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) //blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
blinded = 1
else if(eye_blurry) //blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
//Ears
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
ear_deaf = max(ear_deaf, 1)
else if(ear_deaf) //deafness, heals slowly over time
ear_deaf = max(ear_deaf-1, 0)
else if(ear_damage < 25) //ear damage heals slowly under this threshold.
ear_damage = max(ear_damage-0.05, 0)
//Other
if(stunned)
AdjustStunned(-1)
if(weakened)
weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
if(stuttering)
stuttering = max(stuttering-1, 0)
if(silent)
silent = max(silent-1, 0)
if(druggy)
druggy = max(druggy-1, 0)
return 1
proc/handle_regular_hud_updates()
if (stat == 2 || (XRAY in mutations))
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight |= SEE_MOBS
sight &= ~SEE_TURFS
sight &= ~SEE_OBJS
see_in_dark = 4
see_invisible = SEE_INVISIBLE_LEVEL_TWO
if (healths)
if (stat != 2)
switch(health)
if(25 to INFINITY)
healths.icon_state = "health0"
if(19 to 25)
healths.icon_state = "health1"
if(13 to 19)
healths.icon_state = "health2"
if(7 to 13)
healths.icon_state = "health3"
if(0 to 7)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
if (toxin) toxin.icon_state = "tox[toxins_alert ? 1 : 0]"
if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]"
if (fire) fire.icon_state = "fire[fire_alert ? 1 : 0]"
//NOTE: the alerts dont reset when youre out of danger. dont blame me,
//blame the person who coded them. Temporary fix added.
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((blind && stat != 2))
if ((blinded))
blind.layer = 18
else
blind.layer = 0
if (disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if (eye_blurry)
client.screen += global_hud.blurry
if (druggy)
client.screen += global_hud.druggy
if (stat != 2)
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
return 1
proc/handle_random_events()
return
proc/handle_stomach()
spawn(0)
for(var/mob/living/M in stomach_contents)
if(M.loc != src)
stomach_contents.Remove(M)
continue
if(istype(M, /mob/living/carbon) && stat != 2)
if(M.stat == 2)
M.death(1)
stomach_contents.Remove(M)
del(M)
continue
if(air_master.current_cycle%3==1)
if(!(M.status_flags & GODMODE))
M.adjustBruteLoss(5)
nutrition += 10
@@ -0,0 +1,3 @@
/mob/living/carbon/alien/larva/Login()
return ..()
@@ -0,0 +1,56 @@
/mob/living/carbon/alien/larva/verb/hide()
set name = "Hide"
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
set category = "Alien"
if(stat != CONSCIOUS)
return
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\green You are now hiding.")
for(var/mob/O in oviewers(src, null))
if ((O.client && !( O.blinded )))
O << text("<B>[] scurries to the ground!</B>", src)
else
layer = MOB_LAYER
src << text("\green You have stopped hiding.")
for(var/mob/O in oviewers(src, null))
if ((O.client && !( O.blinded )))
O << text("[] slowly peaks up from the ground...", src)
/mob/living/carbon/alien/larva/verb/evolve()
set name = "Evolve"
set desc = "Evolve into a fully grown Alien."
set category = "Alien"
if(stat != CONSCIOUS)
return
if(handcuffed || legcuffed)
src << "\red You cannot evolve when you are cuffed."
if(amount_grown >= max_grown) //TODO ~Carn
//green is impossible to read, so i made these blue and changed the formatting slightly
src << "\blue <b>You are growing into a beautiful alien! It is time to choose a caste.</b>"
src << "\blue There are three to choose from:"
src << "<B>Hunters</B> \blue are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves."
src << "<B>Sentinels</B> \blue are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters."
src << "<B>Drones</B> \blue are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen."
var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
var/mob/living/carbon/alien/humanoid/new_xeno
switch(alien_caste)
if("Hunter")
new_xeno = new /mob/living/carbon/alien/humanoid/hunter(loc)
if("Sentinel")
new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(loc)
if("Drone")
new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc)
if(mind) mind.transfer_to(new_xeno)
del(src)
return
else
src << "\red You are not fully grown."
return
@@ -0,0 +1,22 @@
/mob/living/carbon/alien/larva/regenerate_icons()
overlays = list()
update_icons()
/mob/living/carbon/alien/larva/update_icons()
var/state = 0
if(amount_grown > 150)
state = 2
else if(amount_grown > 50)
state = 1
if(stat == DEAD)
icon_state = "larva[state]_dead"
else if (handcuffed || legcuffed)
icon_state = "larva[state]_cuff"
else if (stunned)
icon_state = "larva[state]_stun"
else if(lying || resting)
icon_state = "larva[state]_sleep"
else
icon_state = "larva[state]"
@@ -0,0 +1,4 @@
/mob/living/carbon/alien/humanoid/Login()
..()
AddInfectionImages()
return
@@ -0,0 +1,4 @@
/mob/living/carbon/alien/humanoid/Logout()
..()
RemoveInfectionImages()
return
@@ -0,0 +1,5 @@
/mob/living/carbon/alien/verb/ventcrawl() // -- TLE
set name = "Crawl through vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Alien"
handle_ventcrawl()
@@ -0,0 +1,68 @@
/mob/living/carbon/alien/say(var/message)
if (silent)
return
if (length(message) >= 2)
if (department_radio_keys[copytext(message, 1, 3)] == "alientalk")
message = copytext(message, 3)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if (stat == 2)
return say_dead(message)
else
alien_talk(message)
else
if (copytext(message, 1, 2) != "*" && !stat)
playsound(loc, "hiss", 25, 1, 1)//So aliens can hiss while they hiss yo/N
return ..(message)
else
/mob/living/proc/alien_talk(var/message)
log_say("[key_name(src)] : [message]")
message = trim(message)
if (!message)
return
var/message_a = say_quote(message)
var/rendered = "<i><span class='game say'>Hivemind, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
for (var/mob/living/S in player_list)
if(!S.stat)
if(S.alien_talk_understand)
if(S.alien_talk_understand == alien_talk_understand)
S.show_message(rendered, 2)
else if (S.hivecheck())
S.show_message(rendered, 2)
var/list/listening = hearers(1, src)
listening -= src
listening += src
var/list/heard = list()
for (var/mob/M in listening)
if(!istype(M, /mob/living/carbon/alien) && !M.alien_talk_understand)
heard += M
if (length(heard))
var/message_b
message_b = "hsssss"
message_b = say_quote(message_b)
message_b = "<i>[message_b]</i>"
rendered = "<i><span class='game say'><span class='name'>[voice_name]</span> <span class='message'>[message_b]</span></span></i>"
for (var/mob/M in heard)
M.show_message(rendered, 2)
message = say_quote(message)
rendered = "<i><span class='game say'>Hivemind, <span class='name'>[name]</span> <span class='message'>[message_a]</span></span></i>"
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
if (M.stat > 1)
M.show_message(rendered, 2)
@@ -0,0 +1,71 @@
//XCOM alien code
//By Xerif (Donated by the Foundation project, ss13.org)
/mob/living/carbon/alien/humanoid/special
has_fine_manipulation = 1
var/xcom_state
New()
..()
spawn (1)
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
mind = new()
mind.key = key
mind.special_role = "Special Xeno"
name = "[name] ([rand(1, 1000)])"
real_name = name
src.stand_icon = new /icon('xcomalien.dmi', xcom_state)
src.lying_icon = new /icon('xcomalien.dmi', xcom_state)
src.icon = src.stand_icon
remove_special_verbs()
rebuild_appearance()
death(gibbed)
..()
spawn(5)
gib()
Stat()
statpanel("Status")
if (src.client && src.client.holder)
stat(null, "([x], [y], [z])")
stat(null, "Intent: [src.a_intent]")
stat(null, "Move Mode: [src.m_intent]")
if (src.client.statpanel == "Status")
if (src.internal)
if (!src.internal.air_contents)
del(src.internal)
else
stat("Internal Atmosphere Info", src.internal.name)
stat("Tank Pressure", src.internal.air_contents.return_pressure())
stat("Distribution Pressure", src.internal.distribute_pressure)
return
alien_talk()
if(istype(src, /mob/living/carbon/alien/humanoid/special/etheral))
..()
return
if(istype(src, /mob/living/carbon/alien/humanoid/special/sectoid))
..()
return
return
/mob/living/carbon/alien/humanoid/special/proc/xcom_attack()
return
/mob/living/carbon/alien/humanoid/special/proc/remove_special_verbs()
verbs -= /mob/living/carbon/alien/humanoid/verb/plant
verbs -= /mob/living/carbon/alien/humanoid/verb/ActivateHuggers
verbs -= /mob/living/carbon/alien/humanoid/verb/whisp
verbs -= /mob/living/carbon/alien/humanoid/verb/transfer_plasma
verbs -= /mob/living/carbon/alien/humanoid/verb/corrode
return
@@ -0,0 +1,143 @@
// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability
// It functions almost identically (see code/datums/diseases/alien_embryo.dm)
/obj/item/alien_embryo
name = "alien embryo"
desc = "All slimy and yuck."
icon = 'icons/mob/alien.dmi'
icon_state = "larva0_dead"
var/mob/living/affected_mob
var/stage = 0
/obj/item/alien_embryo/New()
if(istype(loc, /mob/living))
affected_mob = loc
processing_objects.Add(src)
spawn(0)
AddInfectionImages(affected_mob)
else
del(src)
/obj/item/alien_embryo/Del()
if(affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
spawn(0)
RemoveInfectionImages(affected_mob)
..()
/obj/item/alien_embryo/process()
if(!affected_mob) return
if(loc != affected_mob)
affected_mob.status_flags &= ~(XENO_HOST)
processing_objects.Remove(src)
spawn(0)
RemoveInfectionImages(affected_mob)
affected_mob = null
return
if(stage < 5 && prob(3))
stage++
spawn(0)
RefreshInfectionImage(affected_mob)
switch(stage)
if(2, 3)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(1))
affected_mob << "\red Your throat feels sore."
if(prob(1))
affected_mob << "\red Mucous runs down the back of your throat."
if(4)
if(prob(1))
affected_mob.emote("sneeze")
if(prob(1))
affected_mob.emote("cough")
if(prob(2))
affected_mob << "\red Your muscles ache."
if(prob(20))
affected_mob.take_organ_damage(1)
if(prob(2))
affected_mob << "\red Your stomach hurts."
if(prob(20))
affected_mob.adjustToxLoss(1)
affected_mob.updatehealth()
if(5)
affected_mob << "\red You feel something tearing its way out of your stomach..."
affected_mob.adjustToxLoss(10)
affected_mob.updatehealth()
if(prob(50))
AttemptGrow()
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
var/list/candidates = get_alien_candidates()
var/picked = null
// To stop clientless larva, we will check that our host has a client
// if we find no ghosts to become the alien. If the host has a client
// he will become the alien but if he doesn't then we will set the stage
// to 2, so we don't do a process heavy check everytime.
if(candidates.len)
picked = pick(candidates)
else if(affected_mob.client)
picked = affected_mob.key
else
stage = 4 // Let's try again later.
return
if(affected_mob.lying)
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie")
else
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
spawn(6)
var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
new_xeno.key = picked
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
if(gib_on_success)
affected_mob.gib()
del(src)
/*----------------------------------------
Proc: RefreshInfectionImage()
Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens.
----------------------------------------*/
/obj/item/alien_embryo/proc/RefreshInfectionImage()
for(var/mob/living/carbon/alien/alien in player_list)
if(alien.client)
for(var/image/I in alien.client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
for(var/mob/living/L in mob_list)
if(iscorgi(L) || iscarbon(L))
if(L.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: AddInfectionImages(C)
Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
----------------------------------------*/
/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
if(C)
for(var/mob/living/carbon/alien/alien in player_list)
if(alien.client)
if(C.status_flags & XENO_HOST)
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: RemoveInfectionImage(C)
Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
----------------------------------------*/
/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
if(C)
for(var/mob/living/carbon/alien/alien in player_list)
if(alien.client)
for(var/image/I in alien.client.images)
if(I.loc == C)
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
@@ -0,0 +1,239 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
//TODO: Make these simple_animals
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
var/const/MAX_IMPREGNATION_TIME = 150
var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger
name = "alien"
desc = "It has some sort of a tube at the end of its tail."
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
flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | MASKINTERNALS
throw_range = 5
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = 0
var/strength = 5
var/attached = 0
/obj/item/clothing/mask/facehugger/attack_paw(user as mob) //can be picked up by aliens
if(isalien(user))
attack_hand(user)
return
else
..()
return
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile) && !isalien(user))
Attach(user)
return
else
..()
return
/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
..()
user.drop_from_inventory(src)
Attach(M)
/obj/item/clothing/mask/facehugger/New()
if(aliens_allowed)
..()
else
del(src)
/obj/item/clothing/mask/facehugger/examine()
..()
switch(stat)
if(DEAD,UNCONSCIOUS)
usr << "\red \b [src] is not moving."
if(CONSCIOUS)
usr << "\red \b [src] seems to be active."
if (sterile)
usr << "\red \b It looks like the proboscis has been removed."
return
/obj/item/clothing/mask/facehugger/attackby()
Die()
return
/obj/item/clothing/mask/facehugger/bullet_act()
Die()
return
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
Die()
return
/obj/item/clothing/mask/facehugger/equipped(mob/M)
Attach(M)
/obj/item/clothing/mask/facehugger/HasEntered(atom/target)
HasProximity(target)
return
/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
if(stat == CONSCIOUS)
HasProximity(finder)
return 1
return
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
if(CanHug(AM))
Attach(AM)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
spawn(15)
if(icon_state == "[initial(icon_state)]_thrown")
icon_state = "[initial(icon_state)]"
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]"
Attach(hit_atom)
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
if( (!iscorgi(M) && !iscarbon(M)) || isalien(M))
return
if(attached)
return
else
attached++
spawn(MAX_IMPREGNATION_TIME)
attached = 0
var/mob/living/L = M //just so I don't need to use :
if(loc == L) return
if(stat != CONSCIOUS) return
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
L.visible_message("\red \b [src] leaps at [L]'s face!")
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.head && H.head.flags & HEADCOVERSMOUTH)
H.visible_message("\red \b [src] smashes against [H]'s [H.head]!")
Die()
return
if(iscarbon(M))
var/mob/living/carbon/target = L
if(target.wear_mask)
if(prob(20)) return
var/obj/item/clothing/W = target.wear_mask
if(!W.canremove) return
target.drop_from_inventory(W)
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
target.equip_to_slot(src, slot_wear_mask)
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
else if (iscorgi(M))
var/mob/living/simple_animal/corgi/C = M
src.loc = C
C.facehugger = src
C.wear_mask = src
//C.regenerate_icons()
GoIdle() //so it doesn't jump the people that tear it off
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(L)
return
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
return
if(!sterile)
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
new /obj/item/alien_embryo(target)
target.status_flags |= XENO_HOST
target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
Die()
icon_state = "[initial(icon_state)]_impregnated"
if(iscorgi(target))
var/mob/living/simple_animal/corgi/C = target
src.loc = get_turf(C)
C.facehugger = null
else
target.visible_message("\red \b [src] violates [target]'s face!")
return
/obj/item/clothing/mask/facehugger/proc/GoActive()
if(stat == DEAD || stat == CONSCIOUS)
return
stat = CONSCIOUS
icon_state = "[initial(icon_state)]"
/* for(var/mob/living/carbon/alien/alien in world)
var/image/activeIndicator = image('icons/mob/alien.dmi', loc = src, icon_state = "facehugger_active")
activeIndicator.override = 1
if(alien && alien.client)
alien.client.images += activeIndicator */
return
/obj/item/clothing/mask/facehugger/proc/GoIdle()
if(stat == DEAD || stat == UNCONSCIOUS)
return
/* RemoveActiveIndicators() */
stat = UNCONSCIOUS
icon_state = "[initial(icon_state)]_inactive"
spawn(rand(MIN_ACTIVE_TIME,MAX_ACTIVE_TIME))
GoActive()
return
/obj/item/clothing/mask/facehugger/proc/Die()
if(stat == DEAD)
return
/* RemoveActiveIndicators() */
icon_state = "[initial(icon_state)]_dead"
stat = DEAD
src.visible_message("\red \b[src] curls up into a ball!")
return
/proc/CanHug(var/mob/M)
if(iscorgi(M))
return 1
if(!iscarbon(M) || isalien(M))
return 0
var/mob/living/carbon/C = M
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.head && H.head.flags & HEADCOVERSMOUTH)
return 0
return 1
@@ -0,0 +1,59 @@
/mob/living/carbon/alien/humanoid/special/snakeman
name = "Snakeman"
desc = "This race developed in an extremely hostile environment. They are extremely tough and can resist extreme temperature variations. Their mobility depends on a snake-like giant \"foot\" which protects all the vital organs. "
xcom_state = "snake"
movement_delay()
return 4
/mob/living/carbon/alien/humanoid/special/snakeman/verb/lay_egg(mob/living/carbon/human/M as mob)
set name = "Impregnate"
set desc = "Lays an egg on a corpse, allowing the egg to feed."
set category = "Snakeman"
set src = view(0)
if(stat)
return
if(!M)
return
if(!M.client)
src << "This being is missing a brain."
return
visible_message("[src] extends a probiscis and stabs it into [M]")
if (!do_mob(usr, M, 50))
usr << "\red The injection of the egg has been interrupted!"
return
if(M.client)
M.client.mob = new/mob/living/carbon/alien/humanoid/special/snakeman(new/obj/effect/snake_egg(src.loc))
visible_message("[src] injects [M] with an egg.")
visible_message("The egg absorbs [M]")
M.mutations |= NOCLONE
M.update_body()
M.death()
else
src << "This being is missing a brain."
return
/obj/effect/snake_egg
name = "Egg"
icon = 'icons/mob/alien.dmi'
icon_state = "egg"
density = 1
anchored = 1
New()
..()
spawn(300)
for(var/mob/M in src)
M.loc = src.loc
icon_state = "egg_hatched"
density = 0
return
+144
View File
@@ -0,0 +1,144 @@
//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."
icon = 'icons/obj/assemblies.dmi'
icon_state = "mmi_empty"
w_class = 3
origin_tech = "biotech=3"
var/list/construction_cost = list("metal"=1000,"glass"=500)
var/construction_time = 75
//these vars are so the mecha fabricator doesn't shit itself anymore. --NEO
req_access = list(access_robotics)
//Revised. Brainmob is now contained directly within object of transfer. MMI in this case.
var/locked = 0
var/mob/living/carbon/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.
attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O,/obj/item/brain) && !brainmob) //Time to stick a brain in it --NEO
if(!O:brainmob)
user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain."
return
for(var/mob/V in viewers(src, null))
V.show_message(text("\blue [user] sticks \a [O] into \the [src]."))
brainmob = O:brainmob
O:brainmob = null
brainmob.loc = src
brainmob.container = src
brainmob.stat = 0
dead_mob_list -= brainmob//Update dem lists
living_mob_list += brainmob
user.drop_item()
del(O)
name = "Man-Machine Interface: [brainmob.real_name]"
icon_state = "mmi_full"
locked = 1
feedback_inc("cyborg_mmis_filled",1)
return
if((istype(O,/obj/item/weapon/card/id)||istype(O,/obj/item/device/pda)) && brainmob)
if(allowed(user))
locked = !locked
user << "\blue You [locked ? "lock" : "unlock"] the brain holder."
else
user << "\red Access denied."
return
if(brainmob)
O.attack(brainmob, user)//Oh noooeeeee
return
..()
attack_self(mob/user as mob)
if(!brainmob)
user << "\red You upend the MMI, but there's nothing in it."
else if(locked)
user << "\red You upend the MMI, but the brain is clamped into place."
else
user << "\blue You upend the MMI, spilling the brain onto the floor."
var/obj/item/brain/brain = new(user.loc)
brainmob.container = null//Reset brainmob mmi var.
brainmob.loc = brain//Throw mob into brain.
living_mob_list -= brainmob//Get outta here
brain.brainmob = brainmob//Set the brain to use the brainmob
brainmob = null//Set mmi brainmob var to null
icon_state = "mmi_empty"
name = "Man-Machine Interface"
proc
transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people.
brainmob = new(src)
brainmob.name = H.real_name
brainmob.real_name = H.real_name
brainmob.dna = H.dna
brainmob.container = src
name = "Man-Machine Interface: [brainmob.real_name]"
icon_state = "mmi_full"
locked = 1
return
/obj/item/device/mmi/radio_enabled
name = "Radio-enabled Man-Machine Interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio."
origin_tech = "biotech=4"
var/obj/item/device/radio/radio = null//Let's give it a radio.
New()
..()
radio = new(src)//Spawns a radio inside the MMI.
radio.broadcasting = 1//So it's broadcasting from the start.
verb//Allows the brain to toggle the radio functions.
Toggle_Broadcasting()
set name = "Toggle Broadcasting"
set desc = "Toggle broadcasting channel on or off."
set category = "MMI"
set src = usr.loc//In user location, or in MMI in this case.
set popup_menu = 0//Will not appear when right clicking.
if(brainmob.stat)//Only the brainmob will trigger these so no further check is necessary.
brainmob << "Can't do that while incapacitated or dead."
radio.broadcasting = radio.broadcasting==1 ? 0 : 1
brainmob << "\blue Radio is [radio.broadcasting==1 ? "now" : "no longer"] broadcasting."
Toggle_Listening()
set name = "Toggle Listening"
set desc = "Toggle listening channel on or off."
set category = "MMI"
set src = usr.loc
set popup_menu = 0
if(brainmob.stat)
brainmob << "Can't do that while incapacitated or dead."
radio.listening = radio.listening==1 ? 0 : 1
brainmob << "\blue Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast."
/obj/item/device/mmi/emp_act(severity)
if(!brainmob)
return
else
switch(severity)
if(1)
brainmob.emp_damage += rand(20,30)
if(2)
brainmob.emp_damage += rand(10,20)
if(3)
brainmob.emp_damage += rand(0,10)
..()
@@ -0,0 +1,58 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/brain
var/obj/item/container = null
var/timeofhostdeath = 0
var/emp_damage = 0//Handles a type of MMI damage
var/alert = null
use_me = 0 //Can't use the me verb, it's a freaking immobile brain
icon = 'icons/obj/surgery.dmi'
icon_state = "brain1"
New()
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
..()
Del()
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.
..()
say_understands(var/other)//Goddamn is this hackish, but this say code is so odd
if (istype(other, /mob/living/silicon/ai))
if(!(container && istype(container, /obj/item/device/mmi)))
return 0
else
return 1
if (istype(other, /mob/living/silicon/decoy))
if(!(container && istype(container, /obj/item/device/mmi)))
return 0
else
return 1
if (istype(other, /mob/living/silicon/pai))
if(!(container && istype(container, /obj/item/device/mmi)))
return 0
else
return 1
if (istype(other, /mob/living/silicon/robot))
if(!(container && istype(container, /obj/item/device/mmi)))
return 0
else
return 1
if (istype(other, /mob/living/carbon/human))
return 1
if (istype(other, /mob/living/carbon/slime))
return 1
return ..()
/mob/living/carbon/brain/update_canmove()
if(in_contents_of(/obj/mecha))
canmove = 1
use_me = 1 //If it can move, let it emote
else canmove = 0
return canmove
@@ -0,0 +1,98 @@
/obj/item/brain
name = "brain"
desc = "A piece of juicy meat found in a persons head."
icon = 'icons/obj/surgery.dmi'
icon_state = "brain2"
flags = TABLEPASS
force = 1.0
w_class = 1.0
throwforce = 1.0
throw_speed = 3
throw_range = 5
origin_tech = "biotech=3"
attack_verb = list("attacked", "slapped", "whacked")
var/mob/living/carbon/brain/brainmob = null
New()
..()
//Shifting the brain "mob" over to the brain object so it's easier to keep track of. --NEO
//WASSSSSUUUPPPP /N
spawn(5)
if(brainmob && brainmob.client)
brainmob.client.screen.len = null //clear the hud
proc
transfer_identity(var/mob/living/carbon/H)
name = "[H]'s brain"
brainmob = new(src)
brainmob.name = H.real_name
brainmob.real_name = H.real_name
brainmob.dna = H.dna.Clone()
brainmob.timeofhostdeath = H.timeofdeath
if(H.mind)
H.mind.transfer_to(brainmob)
brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain."
return
/obj/item/brain/examine() // -- TLE
set src in oview(12)
if (!( usr ))
return
usr << "This is \icon[src] \an [name]."
if(brainmob && brainmob.client)//if thar be a brain inside... the brain.
usr << "You can feel the small spark of life still left in this one."
else
usr << "This one seems particularly lifeless. Perhaps it will regain some of its luster later.."
/obj/item/brain/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M, /mob))
return
add_fingerprint(user)
if(!(user.zone_sel.selecting == ("head")) || !istype(M, /mob/living/carbon/human))
return ..()
if( !(locate(/obj/machinery/optable, M.loc) && M.resting) && ( !(locate(/obj/structure/table/, M.loc) && M.lying) && prob(50) ) )
return ..()
var/mob/living/carbon/human/H = M
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
// you can't stab someone in the eyes wearing a mask!
user << "\blue You're going to need to remove their head cover first."
return
//since these people will be dead M != usr
if(M:brain_op_stage == 4.0)
for(var/mob/O in viewers(M, null))
if(O == (user || M))
continue
if(M == user)
O.show_message(text("\red [user] inserts [src] into his head!"), 1)
else
O.show_message(text("\red [M] has [src] inserted into his head by [user]."), 1)
if(M != user)
M << "\red [user] inserts [src] into your head!"
user << "\red You insert [src] into [M]'s head!"
else
user << "\red You insert [src] into your head!"
//this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO
if(M.key)//Revised. /N
M.ghostize()
if(brainmob.mind)
brainmob.mind.transfer_to(M)
else
M.key = brainmob.key
M:brain_op_stage = 3.0
del(src)
else
..()
return
@@ -0,0 +1,43 @@
/mob/living/carbon/brain/death(gibbed)
if(stat == DEAD) return
if(!gibbed && container && istype(container, /obj/item/device/mmi))//If not gibbed but in a container.
for(var/mob/O in viewers(container, null))
O.show_message(text("\red <B>[]'s MMI flatlines!</B>", src), 1, "\red You hear something flatline.", 2)
container.icon_state = "mmi_dead"
stat = DEAD
if(blind) blind.layer = 0
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0) //mind. ?
return ..(gibbed)
/mob/living/carbon/brain/gib()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
// flick("gibbed-m", animation)
gibs(loc, viruses, dna)
dead_mob_list -= src
if(container && istype(container, /obj/item/device/mmi))
del(container)//Gets rid of the MMI if there is one
if(loc)
if(istype(loc,/obj/item/brain))
del(loc)//Gets rid of the brain item
spawn(15)
if(animation) del(animation)
if(src) del(src)
@@ -0,0 +1,82 @@
/mob/living/carbon/brain/emote(var/act,var/m_type=1,var/message = null)
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
return
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
act = copytext(act, 1, t1)
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
if(src.stat == DEAD)
return
switch(act)
if ("me")
if(silent)
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
return custom_emote(m_type, message)
if ("custom")
return custom_emote(m_type, message)
if ("alarm")
src << "You sound an alarm."
message = "<B>[src]</B> sounds an alarm."
m_type = 2
if ("alert")
src << "You let out a distressed noise."
message = "<B>[src]</B> lets out a distressed noise."
m_type = 2
if ("notice")
src << "You play a loud tone."
message = "<B>[src]</B> plays a loud tone."
m_type = 2
if ("flash")
message = "The lights on <B>[src]</B> flash quickly."
m_type = 1
if ("blink")
message = "<B>[src]</B> blinks."
m_type = 1
if ("whistle")
src << "You whistle."
message = "<B>[src]</B> whistles."
m_type = 2
if ("beep")
src << "You beep."
message = "<B>[src]</B> beeps."
m_type = 2
if ("boop")
src << "You boop."
message = "<B>[src]</B> boops."
m_type = 2
if ("help")
src << "alarm,alert,notice,flash,blink,whistle,beep,boop"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
if (message)
log_emote("[name]/[key] : [message]")
for(var/mob/M in dead_mob_list)
if (!M.client || istype(M, /mob/new_player))
continue //skip monkeys, leavers, and new_players
if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
if (m_type & 1)
for (var/mob/O in viewers(src, null))
O.show_message(message, m_type)
else if (m_type & 2)
for (var/mob/O in hearers(src.loc, null))
O.show_message(message, m_type)
@@ -0,0 +1,282 @@
/mob/living/carbon/brain/Life()
set invisibility = 0
set background = 1
..()
if(stat != DEAD)
//Mutations and radiation
handle_mutations_and_radiation()
//Chemicals in the body
handle_chemicals_in_body()
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(loc)
environment = loc.return_air()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
blinded = null
//Handle temperature/pressure differences between body and environment
if(environment) // More error checking -- TLE
handle_environment(environment)
//Status updates, death etc.
handle_regular_status_updates()
update_canmove()
if(client)
handle_regular_hud_updates()
/mob/living/carbon/brain/
proc/handle_mutations_and_radiation()
if (radiation)
if (radiation > 100)
radiation = 100
if(!container)//If it's not in an MMI
src << "\red You feel weak."
else//Fluff-wise, since the brain can't detect anything itself, the MMI handles thing like that
src << "\red STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED."
switch(radiation)
if(1 to 49)
radiation--
if(prob(25))
adjustToxLoss(1)
updatehealth()
if(50 to 74)
radiation -= 2
adjustToxLoss(1)
if(prob(5))
radiation -= 5
if(!container)
src << "\red You feel weak."
else
src << "\red STATUS: DANGEROUS LEVELS OF RADIATION DETECTED."
updatehealth()
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
updatehealth()
proc/handle_environment(datum/gas_mixture/environment)
if(!environment)
return
var/environment_heat_capacity = environment.heat_capacity()
if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
environment_heat_capacity = heat_turf.heat_capacity
if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
var/transfer_coefficient = 1
handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient)
if(stat==2)
bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
//Account for massive pressure differences
return //TODO: DEFERRED
proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
if(status_flags & GODMODE) return
if(exposed_temperature > bodytemperature)
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
//adjustFireLoss(2.5*discomfort)
//adjustFireLoss(5.0*discomfort)
adjustFireLoss(20.0*discomfort)
else
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
//adjustFireLoss(2.5*discomfort)
adjustFireLoss(5.0*discomfort)
proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
confused = max(0, confused - 1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 5)
else
dizziness = max(0, dizziness - 1)
updatehealth()
return //TODO: DEFERRED
proc/handle_regular_status_updates() //TODO: comment out the unused bits >_>
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
silent = 0
else //ALIVE. LIGHTS ARE ON
if( !container && (health < config.health_threshold_dead || ((world.time - timeofhostdeath) > config.revival_brain_life)) )
death()
blinded = 1
silent = 0
return 1
//Handling EMP effect in the Life(), it's made VERY simply, and has some additional effects handled elsewhere
if(emp_damage) //This is pretty much a damage type only used by MMIs, dished out by the emp_act
if(!(container && istype(container, /obj/item/device/mmi)))
emp_damage = 0
else
emp_damage = round(emp_damage,1)//Let's have some nice numbers to work with
switch(emp_damage)
if(31 to INFINITY)
emp_damage = 30//Let's not overdo it
if(21 to 30)//High level of EMP damage, unable to see, hear, or speak
eye_blind = 1
blinded = 1
ear_deaf = 1
silent = 1
if(!alert)//Sounds an alarm, but only once per 'level'
emote("alarm")
src << "\red Major electrical distruption detected: System rebooting."
alert = 1
if(prob(75))
emp_damage -= 1
if(20)
alert = 0
blinded = 0
eye_blind = 0
ear_deaf = 0
silent = 0
emp_damage -= 1
if(11 to 19)//Moderate level of EMP damage, resulting in nearsightedness and ear damage
eye_blurry = 1
ear_damage = 1
if(!alert)
emote("alert")
src << "\red Primary systems are now online."
alert = 1
if(prob(50))
emp_damage -= 1
if(10)
alert = 0
eye_blurry = 0
ear_damage = 0
emp_damage -= 1
if(2 to 9)//Low level of EMP damage, has few effects(handled elsewhere)
if(!alert)
emote("notice")
src << "\red System reboot nearly complete."
alert = 1
if(prob(25))
emp_damage -= 1
if(1)
alert = 0
src << "\red All systems restored."
emp_damage -= 1
//Other
if(stunned)
AdjustStunned(-1)
if(weakened)
weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
if(stuttering)
stuttering = max(stuttering-1, 0)
if(silent)
silent = max(silent-1, 0)
if(druggy)
druggy = max(druggy-1, 0)
return 1
proc/handle_regular_hud_updates()
if (stat == 2 || (XRAY in src.mutations))
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight &= ~SEE_TURFS
sight &= ~SEE_MOBS
sight &= ~SEE_OBJS
see_in_dark = 2
see_invisible = SEE_INVISIBLE_LIVING
if (healths)
if (stat != 2)
switch(health)
if(100 to INFINITY)
healths.icon_state = "health0"
if(80 to 100)
healths.icon_state = "health1"
if(60 to 80)
healths.icon_state = "health2"
if(40 to 60)
healths.icon_state = "health3"
if(20 to 40)
healths.icon_state = "health4"
if(0 to 20)
healths.icon_state = "health5"
else
healths.icon_state = "health6"
else
healths.icon_state = "health7"
if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if ((blind && stat != 2))
if ((blinded))
blind.layer = 18
else
blind.layer = 0
if (disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if (eye_blurry)
client.screen += global_hud.blurry
if (druggy)
client.screen += global_hud.druggy
if (stat != 2)
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
return 1
/*/mob/living/carbon/brain/emp_act(severity)
if(!(container && istype(container, /obj/item/device/mmi)))
return
else
switch(severity)
if(1)
emp_damage += rand(20,30)
if(2)
emp_damage += rand(10,20)
if(3)
emp_damage += rand(0,10)
..()*/
@@ -0,0 +1,2 @@
/mob/living/carbon/brain/Login()
return ..()
@@ -0,0 +1,130 @@
/obj/item/device/mmi/posibrain
name = "positronic brain"
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
origin_tech = "engineering=4;materials=4;bluespace=2;programming=4"
construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10)
construction_time = 75
var/searching = 0
var/askDelay = 10 * 60 * 1
mob/living/carbon/brain/brainmob = null
req_access = list(access_robotics)
locked = 0
mecha = null//This does not appear to be used outside of reference in mecha.dm.
attack_self(mob/user as mob)
if(brainmob && !brainmob.key && searching == 0)
//Start the process of searching for a new user.
user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
icon_state = "posibrain-searching"
src.searching = 1
src.request_player()
spawn(600) reset_search()
proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
continue
if(jobban_isbanned(O, "pAI"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_PAI)
question(O.client)
proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round")
if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_PAI
proc/transfer_personality(var/mob/candidate)
src.searching = 0
src.brainmob.mind = candidate.mind
//src.brainmob.key = candidate.key
src.brainmob.ckey = candidate.ckey
src.name = "positronic brain ([src.brainmob.name])"
src.brainmob << "<b>You are a positronic brain, brought into existence on [station_name()].</b>"
src.brainmob << "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>"
src.brainmob << "<b>Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
src.brainmob << "<b>Use say :b to speak to other artificial intelligences.</b>"
src.brainmob.mind.assigned_role = "Positronic Brain"
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain chimes quietly.")
icon_state = "posibrain-occupied"
proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(src.brainmob && src.brainmob.key) return
src.searching = 0
icon_state = "posibrain"
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
/obj/item/device/mmi/posibrain/examine()
set src in oview()
if(!usr || !src) return
if( (usr.sdisabilities & BLIND || usr.blinded || usr.stat) && !istype(usr,/mob/dead/observer) )
usr << "<span class='notice'>Something is there but you can't see it.</span>"
return
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
msg += "<span class='warning'>"
if(src.brainmob && src.brainmob.key)
switch(src.brainmob.stat)
if(CONSCIOUS)
if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responsive.</span>\n"
if(DEAD) msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
else
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
msg += "<span class='info'>*---------*</span>"
usr << msg
return
/obj/item/device/mmi/posibrain/emp_act(severity)
if(!src.brainmob)
return
else
switch(severity)
if(1)
src.brainmob.emp_damage += rand(20,30)
if(2)
src.brainmob.emp_damage += rand(10,20)
if(3)
src.brainmob.emp_damage += rand(0,10)
..()
/obj/item/device/mmi/posibrain/New()
src.brainmob = new(src)
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
src.brainmob.real_name = src.brainmob.name
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.robot_talk_understand = 1
src.brainmob.stat = 0
src.brainmob.silent = 0
src.brainmob.brain_op_stage = 4.0
dead_mob_list -= src.brainmob
..()
@@ -0,0 +1,22 @@
/mob/living/carbon/brain/say(var/message)
if (silent)
return
if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/mmi/posibrain))))
return //No MMI, can't speak, bucko./N
else
if ((department_radio_keys[copytext(message, 1, 3)] == "binary") && (container && istype(container, /obj/item/device/mmi/posibrain)))
message = copytext(message, 3)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
robot_talk(message)
return
if(prob(emp_damage*4))
if(prob(10))//10% chane to drop the message entirely
return
else
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
if(istype(container, /obj/item/device/mmi/radio_enabled))
var/obj/item/device/mmi/radio_enabled/R = container
if(R.radio)
spawn(0) R.radio.hear_talk(src, sanitize(message))
..()
+471
View File
@@ -0,0 +1,471 @@
/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((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
src.bodytemperature += 2
/mob/living/carbon/relaymove(var/mob/user, direction)
if(user in src.stomach_contents)
if(prob(40))
for(var/mob/M in hearers(4, src))
if(M.client)
M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2)
var/obj/item/I = user.get_active_hand()
if(I && I.force)
var/d = rand(round(I.force / 4), I.force)
if(istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
var/organ = H.get_organ("chest")
if (istype(organ, /datum/organ/external))
var/datum/organ/external/temp = organ
if(temp.take_damage(d, 0))
H.UpdateDamageIcon()
H.updatehealth()
else
src.take_organ_damage(d)
for(var/mob/M in viewers(user, null))
if(M.client)
M.show_message(text("\red <B>[user] attacks [src]'s stomach wall with the [I.name]!"), 2)
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
if(prob(src.getBruteLoss() - 50))
for(var/atom/movable/A in stomach_contents)
A.loc = loc
stomach_contents.Remove(A)
src.gib()
/mob/living/carbon/gib()
for(var/mob/M in src)
if(M in src.stomach_contents)
src.stomach_contents.Remove(M)
M.loc = src.loc
for(var/mob/N in viewers(src, null))
if(N.client)
N.show_message(text("\red <B>[M] bursts out of [src]!</B>"), 2)
. = ..()
/mob/living/carbon/attack_hand(mob/M as mob)
if(!istype(M, /mob/living/carbon)) return
if (hasorgans(M))
var/datum/organ/external/temp = M:organs_by_name["r_hand"]
if (M.hand)
temp = M:organs_by_name["l_hand"]
if(temp && !temp.is_usable())
M << "\red You can't use your [temp.display_name]"
return
for(var/datum/disease/D in viruses)
if(D.spread_by_touch())
M.contract_disease(D, 0, 1, CONTACT_HANDS)
for(var/datum/disease/D in M.viruses)
if(D.spread_by_touch())
contract_disease(D, 0, 1, CONTACT_HANDS)
return
/mob/living/carbon/attack_paw(mob/M as mob)
if(!istype(M, /mob/living/carbon)) return
for(var/datum/disease/D in viruses)
if(D.spread_by_touch())
M.contract_disease(D, 0, 1, CONTACT_HANDS)
for(var/datum/disease/D in M.viruses)
if(D.spread_by_touch())
contract_disease(D, 0, 1, CONTACT_HANDS)
return
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0)
if(status_flags & GODMODE) return 0 //godmode
shock_damage *= siemens_coeff
if (shock_damage<1)
return 0
src.take_overall_damage(0,shock_damage,used_weapon="Electrocution")
//src.burn_skin(shock_damage)
//src.adjustFireLoss(shock_damage) //burn_skin will do this for us
//src.updatehealth()
src.visible_message(
"\red [src] was shocked by the [source]!", \
"\red <B>You feel a powerful shock course through your body!</B>", \
"\red You hear a heavy electrical crack." \
)
// if(src.stunned < shock_damage) src.stunned = shock_damage
Stun(10)//This should work for now, more is really silly and makes you lay there forever
// if(src.weakened < 20*siemens_coeff) src.weakened = 20*siemens_coeff
Weaken(10)
return shock_damage
/mob/living/carbon/proc/swap_hand()
var/obj/item/item_in_hand = src.get_active_hand()
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.l_hand_hud_object && hud_used.r_hand_hud_object)
if(hand) //This being 1 means the left hand is in use
hud_used.l_hand_hud_object.icon_state = "hand_active"
hud_used.r_hand_hud_object.icon_state = "hand_inactive"
else
hud_used.l_hand_hud_object.icon_state = "hand_inactive"
hud_used.r_hand_hud_object.icon_state = "hand_active"
/*if (!( src.hand ))
src.hands.dir = NORTH
else
src.hands.dir = SOUTH*/
return
/mob/living/carbon/proc/activate_hand(var/selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
if(istext(selhand))
selhand = lowertext(selhand)
if(selhand == "right" || selhand == "r")
selhand = 0
if(selhand == "left" || selhand == "l")
selhand = 1
if(selhand != src.hand)
swap_hand()
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if (src.health >= config.health_threshold_crit)
if(src == M && istype(src, /mob/living/carbon/human))
var/mob/living/carbon/human/H = src
src.visible_message( \
text("\blue [src] examines [].",src.gender==MALE?"himself":"herself"), \
"\blue You check yourself for injuries." \
)
for(var/datum/organ/external/org in H.organs)
var/status = ""
var/brutedamage = org.brute_dam
var/burndamage = org.burn_dam
if(halloss > 0)
if(prob(30))
brutedamage += halloss
if(prob(30))
burndamage += halloss
if(brutedamage > 0)
status = "bruised"
if(brutedamage > 20)
status = "bleeding"
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(org.status & ORGAN_DESTROYED)
status = "MISSING!"
if(org.status & ORGAN_MUTATED)
status = "weirdly shapen."
if(status == "")
status = "OK"
src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.display_name,status),1)
if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit))
H.play_xylophone()
else
var/t_him = "it"
if (src.gender == MALE)
t_him = "him"
else if (src.gender == FEMALE)
t_him = "her"
if (istype(src,/mob/living/carbon/human) && src:w_uniform)
var/mob/living/carbon/human/H = src
H.w_uniform.add_fingerprint(M)
src.sleeping = max(0,src.sleeping-5)
if(src.sleeping == 0)
src.resting = 0
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
M.visible_message( \
"\blue [M] shakes [src] trying to wake [t_him] up!", \
"\blue You shake [src] trying to wake [t_him] up!", \
)
/mob/living/carbon/proc/eyecheck()
return 0
// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching.
// Stop! ... Hammertime! ~Carn
/mob/living/carbon/proc/getDNA()
return dna
/mob/living/carbon/proc/setDNA(var/datum/dna/newDNA)
dna = newDNA
// ++++ROCKDTBEN++++ MOB PROCS //END
/mob/living/carbon/clean_blood()
. = ..()
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.gloves)
if(H.gloves.clean_blood())
H.update_inv_gloves(0)
H.gloves.germ_level = 0
else
if(H.bloody_hands)
H.bloody_hands = 0
H.update_inv_gloves(0)
H.germ_level = 0
update_icons() //apply the now updated overlays to the mob
//Throwing stuff
/mob/living/carbon/proc/toggle_throw_mode()
if (src.in_throw_mode)
throw_mode_off()
else
throw_mode_on()
/mob/living/carbon/proc/throw_mode_off()
src.in_throw_mode = 0
src.throw_icon.icon_state = "act_throw_off"
/mob/living/carbon/proc/throw_mode_on()
src.in_throw_mode = 1
src.throw_icon.icon_state = "act_throw_on"
/mob/proc/throw_item(atom/target)
return
/mob/living/carbon/throw_item(atom/target)
src.throw_mode_off()
if(usr.stat || !target)
return
if(target.type == /obj/screen) return
var/atom/movable/item = src.get_active_hand()
if(!item) return
if (istype(item, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = item
item = G.throw() //throw the person instead of the grab
if(ismob(item))
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
if(start_T && end_T)
var/mob/M = item
var/start_T_descriptor = "<font color='#6b5d00'>tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]</font>"
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been thrown by [usr.name] ([usr.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]</font>")
usr.attack_log += text("\[[time_stamp()]\] <font color='red'>Has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]</font>")
msg_admin_attack("[usr.name] ([usr.ckey]) has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[usr.x];Y=[usr.y];Z=[usr.z]'>JMP</a>)")
if(!item) return //Grab processing has a chance of returning null
item.layer = initial(item.layer)
u_equip(item)
update_icons()
if (istype(usr, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required.
item.loc = src.loc
if(src.client)
src.client.screen -= item
if(istype(item, /obj/item))
item:dropped(src) // let it know it's been dropped
//actually throw it!
if (item)
src.visible_message("\red [src] has thrown [item].")
if(!src.lastarea)
src.lastarea = get_area(src.loc)
if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
/*
if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
*/
item.throw_at(target, item.throw_range, item.throw_speed)
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
bodytemperature = max(bodytemperature, BODYTEMP_HEAT_DAMAGE_LIMIT+10)
/mob/living/carbon/can_use_hands()
if(handcuffed)
return 0
if(buckled && ! istype(buckled, /obj/structure/stool/bed/chair)) // buckling does not restrict hands
return 0
return 1
/mob/living/carbon/restrained()
if (handcuffed)
return 1
return
/mob/living/carbon/u_equip(obj/item/W as obj)
if(!W) return 0
else if (W == handcuffed)
handcuffed = null
update_inv_handcuffed()
else if (W == legcuffed)
legcuffed = null
update_inv_legcuffed()
else
..()
return
/mob/living/carbon/show_inv(mob/living/carbon/user as mob)
user.set_machine(src)
var/dat = {"
<B><HR><FONT size=3>[name]</FONT></B>
<BR><HR>
<BR><B>Head(Mask):</B> <A href='?src=\ref[src];item=mask'>[(wear_mask ? wear_mask : "Nothing")]</A>
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=l_hand'>[(l_hand ? l_hand : "Nothing")]</A>
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=r_hand'>[(r_hand ? r_hand : "Nothing")]</A>
<BR><B>Back:</B> <A href='?src=\ref[src];item=back'>[(back ? back : "Nothing")]</A> [((istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank) && !( internal )) ? text(" <A href='?src=\ref[];item=internal'>Set Internal</A>", src) : "")]
<BR>[(handcuffed ? text("<A href='?src=\ref[src];item=handcuff'>Handcuffed</A>") : text("<A href='?src=\ref[src];item=handcuff'>Not Handcuffed</A>"))]
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
<BR>"}
user << browse(dat, text("window=mob[];size=325x500", name))
onclose(user, "mob[name]")
return
//generates realistic-ish pulse output based on preset levels
/mob/living/carbon/proc/get_pulse(var/method) //method 0 is for hands, 1 is for machines, more accurate
var/temp = 0 //see setup.dm:694
switch(src.pulse)
if(PULSE_NONE)
return "0"
if(PULSE_SLOW)
temp = rand(40, 60)
return num2text(method ? temp : temp + rand(-10, 10))
if(PULSE_NORM)
temp = rand(60, 90)
return num2text(method ? temp : temp + rand(-10, 10))
if(PULSE_FAST)
temp = rand(90, 120)
return num2text(method ? temp : temp + rand(-10, 10))
if(PULSE_2FAST)
temp = rand(120, 160)
return num2text(method ? temp : temp + rand(-10, 10))
if(PULSE_THREADY)
return method ? ">250" : "extremely weak and fast, patient's artery feels like a thread"
// output for machines^ ^^^^^^^output for people^^^^^^^^^
/mob/living/carbon/verb/mob_sleep()
set name = "Sleep"
set category = "IC"
if(usr.sleeping)
usr << "\red You are already sleeping"
return
if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes")
usr.sleeping = 20 //Short nap
//Brain slug proc for voluntary removal of control.
/mob/living/carbon/proc/release_control()
set category = "Alien"
set name = "Release Control"
set desc = "Release control of your host's body."
var/mob/living/simple_animal/borer/B = has_brain_worms()
if(!B)
return
if(B.controlling)
src << "\red <B>You withdraw your probosci, releasing control of [B.host_brain]</B>"
B.host_brain << "\red <B>Your vision swims as the alien parasite releases control of your body.</B>"
B.ckey = ckey
B.controlling = 0
if(B.host_brain.ckey)
ckey = B.host_brain.ckey
B.host_brain.ckey = null
B.host_brain.name = "host brain"
B.host_brain.real_name = "host brain"
verbs -= /mob/living/carbon/proc/release_control
verbs -= /mob/living/carbon/proc/punish_host
verbs -= /mob/living/carbon/proc/spawn_larvae
//Brain slug proc for tormenting the host.
/mob/living/carbon/proc/punish_host()
set category = "Alien"
set name = "Torment host"
set desc = "Punish your host with agony."
var/mob/living/simple_animal/borer/B = has_brain_worms()
if(!B)
return
if(B.host_brain.ckey)
src << "\red <B>You send a punishing spike of psychic agony lancing into your host's brain.</B>"
B.host_brain << "\red <B><FONT size=3>Horrific, burning agony lances through you, ripping a soundless scream from your trapped mind!</FONT></B>"
//Check for brain worms in head.
/mob/proc/has_brain_worms()
for(var/I in contents)
if(istype(I,/mob/living/simple_animal/borer))
return I
return 0
/mob/living/carbon/proc/spawn_larvae()
set category = "Alien"
set name = "Reproduce"
set desc = "Spawn several young."
var/mob/living/simple_animal/borer/B = has_brain_worms()
if(!B)
return
if(B.chemicals >= 100)
src << "\red <B>Your host twitches and quivers as you rapdly excrete several larvae from your sluglike body.</B>"
visible_message("\red <B>[src] heaves violently, expelling a rush of vomit and a wriggling, sluglike creature!</B>")
B.chemicals -= 100
new /obj/effect/decal/cleanable/vomit(get_turf(src))
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
new /mob/living/simple_animal/borer(get_turf(src))
else
src << "You do not have enough chemicals stored to reproduce."
return
@@ -0,0 +1,21 @@
/mob/living/carbon/
gender = MALE
var/list/stomach_contents = list()
var/brain_op_stage = 0.0
var/list/datum/disease2/disease/virus2 = list()
var/antibodies = 0
var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
var/analgesic = 0 // when this is set, the mob isn't affected by shock or pain
// life should decrease this by 1 every tick
// total amount of wounds on mob, used to spread out healing and the like over all wounds
var/number_wounds = 0
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this.
//Surgery info
var/datum/surgery_status/op_stage = new/datum/surgery_status
//Active emote/pose
var/pose = null
var/pulse = PULSE_NORM //current pulse level
+57
View File
@@ -0,0 +1,57 @@
/mob/living/carbon/verb/give()
set category = "IC"
set name = "Give"
set src in view(1)
if(src.stat == 2 || usr.stat == 2 || src.client == null)
return
if(src == usr)
usr << "\red I feel stupider, suddenly."
return
var/obj/item/I
if(!usr.hand && usr.r_hand == null)
usr << "\red You don't have anything in your right hand to give to [src.name]"
return
if(usr.hand && usr.l_hand == null)
usr << "\red You don't have anything in your left hand to give to [src.name]"
return
if(usr.hand)
I = usr.l_hand
else if(!usr.hand)
I = usr.r_hand
if(!I)
return
if(src.r_hand == null || src.l_hand == null)
switch(alert(src,"[usr] wants to give you \a [I]?",,"Yes","No"))
if("Yes")
if(!I)
return
if(!Adjacent(usr))
usr << "\red You need to stay in reaching distance while giving an object."
src << "\red [usr.name] moved too far away."
return
if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I))
usr << "\red You need to keep the item in your active hand."
src << "\red [usr.name] seem to have given up on giving \the [I.name] to you."
return
if(src.r_hand != null && src.l_hand != null)
src << "\red Your hands are full."
usr << "\red Their hands are full."
return
else
usr.drop_item()
if(src.r_hand == null)
src.r_hand = I
else
src.l_hand = I
I.loc = src
I.layer = 20
I.add_fingerprint(src)
src.update_inv_l_hand()
src.update_inv_r_hand()
usr.update_inv_l_hand()
usr.update_inv_r_hand()
src.visible_message("\blue [usr.name] handed \the [I.name] to [src.name].")
if("No")
src.visible_message("\red [usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.")
else
usr << "\red [src.name]'s hands are full."
@@ -0,0 +1,141 @@
/mob/living/carbon/human/gib()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
for(var/datum/organ/external/E in src.organs)
if(istype(E, /datum/organ/external/chest))
continue
// Only make the limb drop if it's not too damaged
if(prob(100 - E.get_damage()))
// Override the current limb status and don't cause an explosion
E.droplimb(1,1)
flick("gibbed-h", animation)
if(species)
hgibs(loc, viruses, dna, species.flesh_color, species.blood_color)
else
hgibs(loc, viruses, dna)
spawn(15)
if(animation) del(animation)
if(src) del(src)
/mob/living/carbon/human/dust()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("dust-h", animation)
new /obj/effect/decal/remains/human(loc)
spawn(15)
if(animation) del(animation)
if(src) del(src)
/mob/living/carbon/human/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health5"
stat = DEAD
dizziness = 0
jitteriness = 0
//Handle brain slugs.
var/datum/organ/external/head = get_organ("head")
var/mob/living/simple_animal/borer/B
for(var/I in head.implants)
if(istype(I,/mob/living/simple_animal/borer))
B = I
if(B)
if(!B.ckey && ckey && B.controlling)
B.ckey = ckey
B.controlling = 0
if(B.host_brain.ckey)
ckey = B.host_brain.ckey
B.host_brain.ckey = null
B.host_brain.name = "host brain"
B.host_brain.real_name = "host brain"
verbs -= /mob/living/carbon/proc/release_control
//Check for heist mode kill count.
if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist) ) )
//Check for last assailant's mutantrace.
/*if( LAssailant && ( istype( LAssailant,/mob/living/carbon/human ) ) )
var/mob/living/carbon/human/V = LAssailant
if (V.dna && (V.dna.mutantrace == "vox"))*/ //Not currently feasible due to terrible LAssailant tracking.
//world << "Vox kills: [vox_kills]"
vox_kills++ //Bad vox. Shouldn't be killing humans.
if(!gibbed)
emote("deathgasp") //let the world KNOW WE ARE DEAD
//For ninjas exploding when they die.
if( istype(wear_suit, /obj/item/clothing/suit/space/space_ninja) && wear_suit:s_initialized )
src << browse(null, "window=spideros")//Just in case.
var/location = loc
explosion(location, 0, 0, 3, 4)
update_canmove()
if(client) blind.layer = 0
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
if(ticker && ticker.mode)
// world.log << "k"
sql_report_death(src)
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
return ..(gibbed)
/mob/living/carbon/human/proc/makeSkeleton()
if(SKELETON in src.mutations) return
if(f_style)
f_style = "Shaved"
if(h_style)
h_style = "Bald"
update_hair(0)
mutations.Add(SKELETON)
status_flags |= DISFIGURED
update_body(0)
update_mutantrace()
return
/mob/living/carbon/human/proc/ChangeToHusk()
if(HUSK in mutations) return
if(f_style)
f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE
if(h_style)
h_style = "Bald"
update_hair(0)
mutations.Add(HUSK)
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
update_body(0)
update_mutantrace()
return
/mob/living/carbon/human/proc/Drain()
ChangeToHusk()
//mutations |= NOCLONE
return
@@ -0,0 +1,585 @@
/mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null)
var/param = null
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
param = copytext(act, t1 + 1, length(act) + 1)
act = copytext(act, 1, t1)
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
//var/m_type = 1
for (var/obj/item/weapon/implant/I in src)
if (I.implanted)
I.trigger(act, src)
if(src.stat == 2.0 && (act != "deathgasp"))
return
switch(act)
if ("airguitar")
if (!src.restrained())
message = "<B>[src]</B> is strumming the air and headbanging like a safari chimp."
m_type = 1
if ("blink")
message = "<B>[src]</B> blinks."
m_type = 1
if ("blink_r")
message = "<B>[src]</B> blinks rapidly."
m_type = 1
if ("bow")
if (!src.buckled)
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if (!M)
param = null
if (param)
message = "<B>[src]</B> bows to [param]."
else
message = "<B>[src]</B> bows."
m_type = 1
if ("custom")
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
if (!input)
return
var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
if (input2 == "Visible")
m_type = 1
else if (input2 == "Hearable")
if (src.miming)
return
m_type = 2
else
alert("Unable to use this emote, must be either hearable or visible.")
return
return custom_emote(m_type, message)
if ("me")
if(silent)
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
return custom_emote(m_type, message)
if ("salute")
if (!src.buckled)
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if (!M)
param = null
if (param)
message = "<B>[src]</B> salutes to [param]."
else
message = "<B>[src]</b> salutes."
m_type = 1
if ("choke")
if(miming)
message = "<B>[src]</B> clutches his throat desperately!"
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> chokes!"
m_type = 2
else
message = "<B>[src]</B> makes a strong noise."
m_type = 2
if ("clap")
if (!src.restrained())
message = "<B>[src]</B> claps."
m_type = 2
if(miming)
m_type = 1
if ("flap")
if (!src.restrained())
message = "<B>[src]</B> flaps his wings."
m_type = 2
if(miming)
m_type = 1
if ("aflap")
if (!src.restrained())
message = "<B>[src]</B> flaps his wings ANGRILY!"
m_type = 2
if(miming)
m_type = 1
if ("drool")
message = "<B>[src]</B> drools."
m_type = 1
if ("eyebrow")
message = "<B>[src]</B> raises an eyebrow."
m_type = 1
if ("chuckle")
if(miming)
message = "<B>[src]</B> appears to chuckle."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> chuckles."
m_type = 2
else
message = "<B>[src]</B> makes a noise."
m_type = 2
if ("twitch")
message = "<B>[src]</B> twitches violently."
m_type = 1
if ("twitch_s")
message = "<B>[src]</B> twitches."
m_type = 1
if ("faint")
message = "<B>[src]</B> faints."
if(src.sleeping)
return //Can't faint while asleep
src.sleeping += 10 //Short-short nap
m_type = 1
if ("cough")
if(miming)
message = "<B>[src]</B> appears to cough!"
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> coughs!"
m_type = 2
else
message = "<B>[src]</B> makes a strong noise."
m_type = 2
if ("frown")
message = "<B>[src]</B> frowns."
m_type = 1
if ("nod")
message = "<B>[src]</B> nods."
m_type = 1
if ("blush")
message = "<B>[src]</B> blushes."
m_type = 1
if ("wave")
message = "<B>[src]</B> waves."
m_type = 1
if ("gasp")
if(miming)
message = "<B>[src]</B> appears to be gasping!"
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> gasps!"
m_type = 2
else
message = "<B>[src]</B> makes a weak noise."
m_type = 2
if ("deathgasp")
message = "<B>[src]</B> seizes up and falls limp, \his eyes dead and lifeless..."
m_type = 1
if ("giggle")
if(miming)
message = "<B>[src]</B> giggles silently!"
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> giggles."
m_type = 2
else
message = "<B>[src]</B> makes a noise."
m_type = 2
if ("glare")
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if (!M)
param = null
if (param)
message = "<B>[src]</B> glares at [param]."
else
message = "<B>[src]</B> glares."
if ("stare")
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if (!M)
param = null
if (param)
message = "<B>[src]</B> stares at [param]."
else
message = "<B>[src]</B> stares."
if ("look")
var/M = null
if (param)
for (var/mob/A in view(null, null))
if (param == A.name)
M = A
break
if (!M)
param = null
if (param)
message = "<B>[src]</B> looks at [param]."
else
message = "<B>[src]</B> looks."
m_type = 1
if ("grin")
message = "<B>[src]</B> grins."
m_type = 1
if ("cry")
if(miming)
message = "<B>[src]</B> cries."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> cries."
m_type = 2
else
message = "<B>[src]</B> makes a weak noise. \He frowns."
m_type = 2
if ("sigh")
if(miming)
message = "<B>[src]</B> sighs."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> sighs."
m_type = 2
else
message = "<B>[src]</B> makes a weak noise."
m_type = 2
if ("laugh")
if(miming)
message = "<B>[src]</B> acts out a laugh."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> laughs."
m_type = 2
else
message = "<B>[src]</B> makes a noise."
m_type = 2
if ("mumble")
message = "<B>[src]</B> mumbles!"
m_type = 2
if(miming)
m_type = 1
if ("grumble")
if(miming)
message = "<B>[src]</B> grumbles!"
m_type = 1
if (!muzzled)
message = "<B>[src]</B> grumbles!"
m_type = 2
else
message = "<B>[src]</B> makes a noise."
m_type = 2
if ("groan")
if(miming)
message = "<B>[src]</B> appears to groan!"
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> groans!"
m_type = 2
else
message = "<B>[src]</B> makes a loud noise."
m_type = 2
if ("moan")
if(miming)
message = "<B>[src]</B> appears to moan!"
m_type = 1
else
message = "<B>[src]</B> moans!"
m_type = 2
if ("johnny")
var/M
if (param)
M = param
if (!M)
param = null
else
if(miming)
message = "<B>[src]</B> takes a drag from a cigarette and blows \"[M]\" out in smoke."
m_type = 1
else
message = "<B>[src]</B> says, \"[M], please. He had a family.\" [src.name] takes a drag from a cigarette and blows his name out in smoke."
m_type = 2
if ("point")
if (!src.restrained())
var/mob/M = null
if (param)
for (var/atom/A as mob|obj|turf|area in view(null, null))
if (param == A.name)
M = A
break
if (!M)
message = "<B>[src]</B> points."
else
M.point()
if (M)
message = "<B>[src]</B> points to [M]."
else
m_type = 1
if ("raise")
if (!src.restrained())
message = "<B>[src]</B> raises a hand."
m_type = 1
if("shake")
message = "<B>[src]</B> shakes \his head."
m_type = 1
if ("shrug")
message = "<B>[src]</B> shrugs."
m_type = 1
if ("signal")
if (!src.restrained())
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))
message = "<B>[src]</B> raises [t1] finger\s."
m_type = 1
if ("smile")
message = "<B>[src]</B> smiles."
m_type = 1
if ("shiver")
message = "<B>[src]</B> shivers."
m_type = 2
if(miming)
m_type = 1
if ("pale")
message = "<B>[src]</B> goes pale for a second."
m_type = 1
if ("tremble")
message = "<B>[src]</B> trembles in fear!"
m_type = 1
if ("sneeze")
if (miming)
message = "<B>[src]</B> sneezes."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> sneezes."
m_type = 2
else
message = "<B>[src]</B> makes a strange noise."
m_type = 2
if ("sniff")
message = "<B>[src]</B> sniffs."
m_type = 2
if(miming)
m_type = 1
if ("snore")
if (miming)
message = "<B>[src]</B> sleeps soundly."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> snores."
m_type = 2
else
message = "<B>[src]</B> makes a noise."
m_type = 2
if ("whimper")
if (miming)
message = "<B>[src]</B> appears hurt."
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> whimpers."
m_type = 2
else
message = "<B>[src]</B> makes a weak noise."
m_type = 2
if ("wink")
message = "<B>[src]</B> winks."
m_type = 1
if ("yawn")
if (!muzzled)
message = "<B>[src]</B> yawns."
m_type = 2
if(miming)
m_type = 1
if ("collapse")
Paralyse(2)
message = "<B>[src]</B> collapses!"
m_type = 2
if(miming)
m_type = 1
if("hug")
m_type = 1
if (!src.restrained())
var/M = null
if (param)
for (var/mob/A in view(1, null))
if (param == A.name)
M = A
break
if (M == src)
M = null
if (M)
message = "<B>[src]</B> hugs [M]."
else
message = "<B>[src]</B> hugs \himself."
if ("handshake")
m_type = 1
if (!src.restrained() && !src.r_hand)
var/mob/M = null
if (param)
for (var/mob/A in view(1, null))
if (param == A.name)
M = A
break
if (M == src)
M = null
if (M)
if (M.canmove && !M.r_hand && !M.restrained())
message = "<B>[src]</B> shakes hands with [M]."
else
message = "<B>[src]</B> holds out \his hand to [M]."
if("dap")
m_type = 1
if (!src.restrained())
var/M = null
if (param)
for (var/mob/A in view(1, null))
if (param == A.name)
M = A
break
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."
if ("scream")
if (miming)
message = "<B>[src]</B> acts out a scream!"
m_type = 1
else
if (!muzzled)
message = "<B>[src]</B> screams!"
m_type = 2
else
message = "<B>[src]</B> makes a very loud noise."
m_type = 2
if ("help")
src << "blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough,\ncry, custom, deathgasp, drool, eyebrow, frown, gasp, giggle, groan, grumble, handshake, hug-(none)/mob, glare-(none)/mob,\ngrin, laugh, look-(none)/mob, moan, mumble, nod, pale, point-atom, raise, salute, shake, shiver, shrug,\nsigh, signal-#1-10, smile, sneeze, sniff, snore, stare-(none)/mob, tremble, twitch, twitch_s, whimper,\nwink, yawn"
else
src << "\blue Unusable emote '[act]'. Say *help for a list."
if (message)
log_emote("[name]/[key] : [message]")
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
for(var/mob/M in dead_mob_list)
if(!M.client || istype(M, /mob/new_player))
continue //skip monkeys, leavers and new players
if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
if (m_type & 1)
for (var/mob/O in get_mobs_in_view(world.view,src))
O.show_message(message, m_type)
else if (m_type & 2)
for (var/mob/O in (hearers(src.loc, null) | get_mobs_in_view(world.view,src)))
O.show_message(message, m_type)
/mob/living/carbon/human/verb/pose()
set name = "Set Pose"
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
pose = copytext(sanitize(input(usr, "This is [src]. \He is...", "Pose", null) as text), 1, MAX_MESSAGE_LEN)
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavour 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 flavour text.", "Flavour text", null) as text), 1)
@@ -0,0 +1,472 @@
/mob/living/carbon/human/examine()
set src in view()
if(!usr || !src) return
if( usr.sdisabilities & BLIND || usr.blinded || usr.stat==UNCONSCIOUS )
usr << "<span class='notice'>Something is there but you can't see it.</span>"
return
var/skipgloves = 0
var/skipsuitstorage = 0
var/skipjumpsuit = 0
var/skipshoes = 0
var/skipmask = 0
var/skipears = 0
var/skipeyes = 0
var/skipface = 0
//exosuits and helmets obscure our view and stuff.
if(wear_suit)
skipgloves = wear_suit.flags_inv & HIDEGLOVES
skipsuitstorage = wear_suit.flags_inv & HIDESUITSTORAGE
skipjumpsuit = wear_suit.flags_inv & HIDEJUMPSUIT
skipshoes = wear_suit.flags_inv & HIDESHOES
if(head)
skipmask = head.flags_inv & HIDEMASK
skipeyes = head.flags_inv & HIDEEYES
skipears = head.flags_inv & HIDEEARS
skipface = head.flags_inv & HIDEFACE
if(wear_mask)
skipface |= wear_mask.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( skipjumpsuit && 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
if(icon)
msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
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 && !skipjumpsuit)
//Ties
var/tie_msg
if(istype(w_uniform,/obj/item/clothing/under))
var/obj/item/clothing/under/U = w_uniform
if(U.hastie)
tie_msg += " with \icon[U.hastie] \a [U.hastie]"
if(w_uniform.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][tie_msg]!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n"
//head
if(head)
if(head.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[head] \a [head] on [t_his] head.\n"
//suit/armour
if(wear_suit)
if(wear_suit.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[wear_suit] \a [wear_suit].\n"
//suit/armour storage
if(s_store && !skipsuitstorage)
if(s_store.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] carrying \icon[s_store] \a [s_store] on [t_his] [wear_suit.name].\n"
//back
if(back)
if(back.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.</span>\n"
else
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
//left hand
if(l_hand)
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)
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"
//gloves
if(gloves && !skipgloves)
if(gloves.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!</span>\n"
else
msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n"
else if(blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] blood-stained hands!</span>\n"
//handcuffed?
//handcuffed?
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/handcuffs/cable))
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] restrained with cable!</span>\n"
else
msg += "<span class='warning'>[t_He] [t_is] \icon[handcuffed] handcuffed!</span>\n"
//belt
if(belt)
if(belt.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!</span>\n"
else
msg += "[t_He] [t_has] \icon[belt] \a [belt] about [t_his] waist.\n"
//shoes
if(shoes && !skipshoes)
if(shoes.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!</span>\n"
else
msg += "[t_He] [t_is] wearing \icon[shoes] \a [shoes] on [t_his] feet.\n"
else if(feet_blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] blood-stained feet!</span>\n"
//mask
if(wear_mask && !skipmask)
if(wear_mask.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!</span>\n"
else
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
//eyes
if(glasses && !skipeyes)
if(glasses.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!</span>\n"
else
msg += "[t_He] [t_has] \icon[glasses] \a [glasses] covering [t_his] eyes.\n"
//left ear
if(l_ear && !skipears)
msg += "[t_He] [t_has] \icon[l_ear] \a [l_ear] on [t_his] left ear.\n"
//right ear
if(r_ear && !skipears)
msg += "[t_He] [t_has] \icon[r_ear] \a [r_ear] on [t_his] right ear.\n"
//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, usr) <= 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
if(is_jittery)
if(jitteriness >= 300)
msg += "<span class='warning'><B>[t_He] [t_is] convulsing violently!</B></span>\n"
else if(jitteriness >= 200)
msg += "<span class='warning'>[t_He] [t_is] extremely jittery.</span>\n"
else if(jitteriness >= 100)
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
//splints
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
var/datum/organ/external/o = get_organ(organ)
if(o && o.status & ORGAN_SPLINTED)
msg += "<span class='warning'>[t_He] [t_has] a splint on [t_his] [o.display_name]!</span>\n"
if(suiciding)
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
if(mSmallsize in mutations)
msg += "[t_He] [t_is] small halfling!\n"
var/distance = get_dist(usr,src)
if(istype(usr, /mob/dead/observer) || usr.stat == 2) // ghosts can see anything
distance = 1
if (src.stat)
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3)
msg += "<span class='warning'>[t_He] does not appear to be breathing.</span>\n"
if(istype(usr, /mob/living/carbon/human) && !usr.stat && distance <= 1)
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(pulse == PULSE_NONE)
usr << "<span class='deadsay'>[t_He] has no pulse[src.client ? "" : " and [t_his] soul has departed"]...</span>"
else
usr << "<span class='deadsay'>[t_He] has a pulse!</span>"
msg += "<span class='warning'>"
if(nutrition < 100)
msg += "[t_He] [t_is] severely malnourished.\n"
else if(nutrition >= 500)
/*if(usr.nutrition < 100)
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"
msg += "</span>"
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
else if(getBrainLoss() >= 60)
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
if(!key && brain_op_stage != 4 && stat != DEAD)
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 && brain_op_stage != 4 && stat != DEAD)
msg += "[t_He] [t_has] suddenly fallen asleep.\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
var/list/is_bleeding = list()
for(var/datum/organ/external/temp in organs)
if(temp)
if(temp.status & ORGAN_DESTROYED)
is_destroyed["[temp.display_name]"] = 1
wound_flavor_text["[temp.display_name]"] = "<span class='warning'><b>[t_He] is missing [t_his] [temp.display_name].</b></span>\n"
continue
if(temp.status & ORGAN_ROBOT)
if(!(temp.brute_dam + temp.burn_dam))
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]!</span>\n"
continue
else
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name], it has"
if(temp.brute_dam) switch(temp.brute_dam)
if(0 to 20)
wound_flavor_text["[temp.display_name]"] += " some dents"
if(21 to INFINITY)
wound_flavor_text["[temp.display_name]"] += pick(" a lot of dents"," severe denting")
if(temp.brute_dam && temp.burn_dam)
wound_flavor_text["[temp.display_name]"] += " and"
if(temp.burn_dam) switch(temp.burn_dam)
if(0 to 20)
wound_flavor_text["[temp.display_name]"] += " some burns"
if(21 to INFINITY)
wound_flavor_text["[temp.display_name]"] += pick(" a lot of burns"," severe melting")
wound_flavor_text["[temp.display_name]"] += "!</span>\n"
else if(temp.wounds.len > 0)
var/list/wound_descriptors = list()
for(var/datum/wound/W in temp.wounds)
if(W.internal && !temp.open) continue // can't see internal wounds
var/this_wound_desc = W.desc
if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
if(W.germ_level > 1000) this_wound_desc = "badly infected [this_wound_desc]"
else if(W.germ_level > 100) this_wound_desc = "lightly infected [this_wound_desc]"
if(this_wound_desc in wound_descriptors)
wound_descriptors[this_wound_desc] += W.amount
continue
wound_descriptors[this_wound_desc] = W.amount
if(wound_descriptors.len)
var/list/flavor_text = list()
var/list/no_exclude = list("gaping wound", "big gaping wound", "massive wound", "large bruise",\
"huge bruise", "massive bruise", "severe burn", "large burn", "deep burn", "carbonised area")
for(var/wound in wound_descriptors)
switch(wound_descriptors[wound])
if(1)
if(!flavor_text.len)
flavor_text += "<span class='warning'>[t_He] has[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a [wound]"
else
flavor_text += "[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a [wound]"
if(2)
if(!flavor_text.len)
flavor_text += "<span class='warning'>[t_He] has[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a pair of [wound]s"
else
flavor_text += "[prob(10) && !(wound in no_exclude) ? " what might be" : ""] a pair of [wound]s"
if(3 to 5)
if(!flavor_text.len)
flavor_text += "<span class='warning'>[t_He] has several [wound]s"
else
flavor_text += " several [wound]s"
if(6 to INFINITY)
if(!flavor_text.len)
flavor_text += "<span class='warning'>[t_He] has a bunch of [wound]s"
else
flavor_text += " a ton of [wound]\s"
var/flavor_text_string = ""
for(var/text = 1, text <= flavor_text.len, text++)
if(text == flavor_text.len && flavor_text.len > 1)
flavor_text_string += ", and"
else if(flavor_text.len > 1 && text > 1)
flavor_text_string += ","
flavor_text_string += flavor_text[text]
flavor_text_string += " on [t_his] [temp.display_name].</span><br>"
wound_flavor_text["[temp.display_name]"] = flavor_text_string
else
wound_flavor_text["[temp.display_name]"] = ""
if(temp.status & ORGAN_BLEEDING)
is_bleeding["[temp.display_name]"] = 1
else
wound_flavor_text["[temp.display_name]"] = ""
//Handles the text strings being added to the actual description.
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
var/display_chest = 0
var/display_shoes = 0
var/display_gloves = 0
if(wound_flavor_text["head"] && (is_destroyed["head"] || (!skipmask && !(wear_mask && istype(wear_mask, /obj/item/clothing/mask/gas)))))
msg += wound_flavor_text["head"]
else if(is_bleeding["head"])
msg += "<span class='warning'>[src] has blood running down [t_his] face!</span>\n"
if(wound_flavor_text["chest"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
msg += wound_flavor_text["chest"]
else if(is_bleeding["chest"])
display_chest = 1
if(wound_flavor_text["left arm"] && (is_destroyed["left arm"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["left arm"]
else if(is_bleeding["left arm"])
display_chest = 1
if(wound_flavor_text["left hand"] && (is_destroyed["left hand"] || (!gloves && !skipgloves)))
msg += wound_flavor_text["left hand"]
else if(is_bleeding["left hand"])
display_gloves = 1
if(wound_flavor_text["right arm"] && (is_destroyed["right arm"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["right arm"]
else if(is_bleeding["right arm"])
display_chest = 1
if(wound_flavor_text["right hand"] && (is_destroyed["right hand"] || (!gloves && !skipgloves)))
msg += wound_flavor_text["right hand"]
else if(is_bleeding["right hand"])
display_gloves = 1
if(wound_flavor_text["groin"] && (is_destroyed["groin"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["groin"]
else if(is_bleeding["groin"])
display_chest = 1
if(wound_flavor_text["left leg"] && (is_destroyed["left leg"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["left leg"]
else if(is_bleeding["left leg"])
display_chest = 1
if(wound_flavor_text["left foot"]&& (is_destroyed["left foot"] || (!shoes && !skipshoes)))
msg += wound_flavor_text["left foot"]
else if(is_bleeding["left foot"])
display_shoes = 1
if(wound_flavor_text["right leg"] && (is_destroyed["right leg"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["right leg"]
else if(is_bleeding["right leg"])
display_chest = 1
if(wound_flavor_text["right foot"]&& (is_destroyed["right foot"] || (!shoes && !skipshoes)))
msg += wound_flavor_text["right foot"]
else if(is_bleeding["right foot"])
display_shoes = 1
if(display_chest)
msg += "<span class='warning'><b>[src] has blood soaking through from under [t_his] clothing!</b></span>\n"
if(display_shoes)
msg += "<span class='warning'><b>[src] has blood running from [t_his] shoes!</b></span>\n"
if(display_gloves)
msg += "<span class='warning'><b>[src] has blood running from under [t_his] gloves!</b></span>\n"
for(var/implant in get_visible_implants(1))
msg += "<span class='warning'><b>[src] has \a [implant] sticking out of their flesh!</span>\n"
if(digitalcamo)
msg += "[t_He] [t_is] repulsively uncanny!\n"
if(hasHUD(usr,"security"))
var/perpname = "wot"
var/criminal = "None"
if(wear_id)
var/obj/item/weapon/card/id/I = wear_id.GetID()
if(I)
perpname = I.registered_name
else
perpname = name
else
perpname = name
if(perpname)
for (var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.security)
if(R.fields["id"] == E.fields["id"])
criminal = R.fields["criminal"]
msg += "<span class = 'deptradio'>Criminal status:</span> <a href='?src=\ref[src];criminal=1'>\[[criminal]\]</a>\n"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=\ref[src];secrecord=`'>\[View\]</a> <a href='?src=\ref[src];secrecordadd=`'>\[Add comment\]</a>\n"
if(hasHUD(usr,"medical"))
var/perpname = "wot"
var/medical = "None"
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.general)
if (R.fields["id"] == E.fields["id"])
medical = R.fields["p_stat"]
msg += "<span class = 'deptradio'>Physical status:</span> <a href='?src=\ref[src];medical=1'>\[[medical]\]</a>\n"
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=\ref[src];medrecord=`'>\[View\]</a> <a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a>\n"
if(print_flavor_text()) msg += "[print_flavor_text()]\n"
msg += "*---------*</span>"
if (pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\n[t_He] is [pose]"
usr << msg
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
/proc/hasHUD(mob/M as mob, hudtype)
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
switch(hudtype)
if("security")
return istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud)
if("medical")
return istype(H.glasses, /obj/item/clothing/glasses/hud/health)
else
return 0
else if(istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = M
switch(hudtype)
if("security")
return istype(R.module_state_1, /obj/item/borg/sight/hud/sec) || istype(R.module_state_2, /obj/item/borg/sight/hud/sec) || istype(R.module_state_3, /obj/item/borg/sight/hud/sec)
if("medical")
return istype(R.module_state_1, /obj/item/borg/sight/hud/med) || istype(R.module_state_2, /obj/item/borg/sight/hud/med) || istype(R.module_state_3, /obj/item/borg/sight/hud/med)
else
return 0
else
return 0
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,62 @@
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if(check_shields(0, M.name))
visible_message("\red <B>[M] attempted to touch [src]!</B>")
return 0
switch(M.a_intent)
if ("help")
visible_message(text("\blue [M] caresses [src] with its scythe like arm."))
if ("grab")
if(M == src || anchored)
return
if (w_uniform)
w_uniform.add_fingerprint(M)
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
M.put_in_active_hand(G)
grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message(text("\red [] has grabbed [] passively!", M, src))
if("hurt")
if (w_uniform)
w_uniform.add_fingerprint(M)
var/damage = rand(15, 30)
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("\red <B>[M] has lunged at [src]!</B>")
return 0
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("\red <B>[M] has slashed at [src]!</B>")
apply_damage(damage, BRUTE, affecting, armor_block)
if (damage >= 25)
visible_message("\red <B>[M] has wounded [src]!</B>")
apply_effect(rand(0.5,3), WEAKEN, armor_block)
updatehealth()
if("disarm")
if (prob(80))
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
Weaken(rand(0.5,3))
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has tackled down []!</B>", M, src), 1)
if (prob(25))
M.Weaken(rand(2,4))
else
if (prob(80))
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
drop_item()
visible_message(text("\red <B>[] disarmed []!</B>", M, src))
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message(text("\red <B>[] has tried to disarm []!</B>", M, src))
return
@@ -0,0 +1,227 @@
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M as mob)
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
var/datum/organ/external/temp = M:organs_by_name["r_hand"]
if (M.hand)
temp = M:organs_by_name["l_hand"]
if(temp && !temp.is_usable())
M << "\red You can't use your [temp.display_name]."
return
..()
if((M != src) && check_shields(0, M.name))
visible_message("\red <B>[M] attempted to touch [src]!</B>")
return 0
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
visible_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Stungloved [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been stungloved by [M.name] ([M.ckey])</font>")
msg_admin_attack("[M.name] ([M.ckey]) stungloved [src.name] ([src.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[M.x];Y=[M.y];Z=[M.z]'>JMP</a>)")
var/armorblock = run_armor_check(M.zone_sel.selecting, "energy")
apply_effects(5,5,0,0,5,0,0,armorblock)
return 1
else
M << "\red Not enough charge! "
visible_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>")
return
if(istype(M.gloves , /obj/item/clothing/gloves/boxing/hologlove))
var/damage = rand(0, 9)
if(!damage)
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[M] has attempted to punch [src]!</B>")
return 0
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations) damage += 5
playsound(loc, "punch", 25, 1, -1)
visible_message("\red <B>[M] has punched [src]!</B>")
apply_damage(damage, HALLOSS, affecting, armor_block)
if(damage >= 9)
visible_message("\red <B>[M] has weakened [src]!</B>")
apply_effect(4, WEAKEN, armor_block)
return
else
if(istype(M,/mob/living/carbon))
// log_debug("No gloves, [M] is truing to infect [src]")
M.spread_disease_to(src, "Contact")
switch(M.a_intent)
if("help")
if(health >= config.health_threshold_crit)
help_shake_act(M)
return 1
// if(M.health < -75) return 0
if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove your mask!</B>"
return 0
if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH)))
M << "\blue <B>Remove his mask!</B>"
return 0
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human()
O.source = M
O.target = src
O.s_loc = M.loc
O.t_loc = loc
O.place = "CPR"
requests += O
spawn(0)
O.process()
return 1
if("grab")
if(M == src || anchored)
return 0
if(w_uniform)
w_uniform.add_fingerprint(M)
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
if(buckled)
M << "<span class='notice'>You cannot grab [src], \he is buckled in!</span>"
if(!G) //the grab will delete itself in New if affecting is anchored
return
M.put_in_active_hand(G)
grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='warning'>[M] has grabbed [src] passively!</span>")
return 1
if("hurt")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>[M.species.attack_verb]ed [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [M.species.attack_verb]ed by [M.name] ([M.ckey])</font>")
log_attack("[M.name] ([M.ckey]) [M.species.attack_verb]ed [src.name] ([src.ckey])")
var/damage = rand(0, 5)//BS12 EDIT
if(!damage)
if(M.species.attack_verb == "punch")
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("\red <B>[M] has attempted to [M.species.attack_verb] [src]!</B>")
return 0
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations) damage += 5
if(M.species.attack_verb == "punch")
playsound(loc, "punch", 25, 1, -1)
else
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("\red <B>[M] has [M.species.attack_verb]ed [src]!</B>")
//Rearranged, so claws don't increase weaken chance.
if(damage >= 5 && prob(50))
visible_message("\red <B>[M] has weakened [src]!</B>")
apply_effect(2, WEAKEN, armor_block)
if(M.species.punch_damage)
damage += M.species.punch_damage
apply_damage(damage, BRUTE, affecting, armor_block)
if("disarm")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Disarmed [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been disarmed by [M.name] ([M.ckey])</font>")
log_attack("[M.name] ([M.ckey]) disarmed [src.name] ([src.ckey])")
if(w_uniform)
w_uniform.add_fingerprint(M)
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
if (istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
var/obj/item/weapon/gun/W = null
var/chance = 0
if (istype(l_hand,/obj/item/weapon/gun))
W = l_hand
chance = hand ? 40 : 20
if (istype(r_hand,/obj/item/weapon/gun))
W = r_hand
chance = !hand ? 40 : 20
if (prob(chance))
visible_message("<spawn class=danger>[src]'s [W] goes off during struggle!")
var/list/turfs = list()
for(var/turf/T in view())
turfs += T
var/turf/target = pick(turfs)
return W.afterattack(target,src)
var/randn = rand(1, 100)
if (randn <= 25)
apply_effect(4, WEAKEN, run_armor_check(affecting, "melee"))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("\red <B>[M] has pushed [src]!</B>")
return
var/talked = 0 // BubbleWrap
if(randn <= 60)
//BubbleWrap: Disarming breaks a pull
if(pulling)
visible_message("\red <b>[M] has broken [src]'s grip on [pulling]!</B>")
talked = 1
stop_pulling()
//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
if(istype(l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/lgrab = l_hand
if(lgrab.affecting)
visible_message("\red <b>[M] has broken [src]'s grip on [lgrab.affecting]!</B>")
talked = 1
spawn(1)
del(lgrab)
if(istype(r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/rgrab = r_hand
if(rgrab.affecting)
visible_message("\red <b>[M] has broken [src]'s grip on [rgrab.affecting]!</B>")
talked = 1
spawn(1)
del(rgrab)
//End BubbleWrap
if(!talked) //BubbleWrap
drop_item()
visible_message("\red <B>[M] has disarmed [src]!</B>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[M] attempted to disarm [src]!</B>")
return
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
return
@@ -0,0 +1,23 @@
/mob/living/carbon/human/attack_paw(mob/M as mob)
..()
if (M.a_intent == "help")
help_shake_act(M)
else
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
for(var/mob/O in viewers(src, null))
O.show_message(text("\red <B>[M.name] has bit []!</B>", src), 1)
var/damage = rand(1, 3)
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/jungle_fever))
var/mob/living/carbon/human/H = src
src = null
src = H.monkeyize()
contract_disease(D,1,0)
return
@@ -0,0 +1,256 @@
//Updates the mob's health from organs and mob damage variables
/mob/living/carbon/human/updatehealth()
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
return
var/total_burn = 0
var/total_brute = 0
for(var/datum/organ/external/O in organs) //hardcoded to streamline things a bit
total_brute += O.brute_dam
total_burn += O.burn_dam
health = 100 - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
//TODO: fix husking
if( ((100 - total_burn) < config.health_threshold_dead) && stat == DEAD) //100 only being used as the magic human max health number, feel free to change it if you add a var for it -- Urist
ChangeToHusk()
return
/mob/living/carbon/human/getBrainLoss()
var/res = brainloss
var/datum/organ/internal/brain/sponge = internal_organs["brain"]
if (sponge.is_bruised())
res += 20
if (sponge.is_broken())
res += 50
res = min(res,maxHealth*2)
return res
//These procs fetch a cumulative total damage from all organs
/mob/living/carbon/human/getBruteLoss()
var/amount = 0
for(var/datum/organ/external/O in organs)
amount += O.brute_dam
return amount
/mob/living/carbon/human/getFireLoss()
var/amount = 0
for(var/datum/organ/external/O in organs)
amount += O.burn_dam
return amount
/mob/living/carbon/human/adjustBruteLoss(var/amount)
if(amount > 0)
take_overall_damage(amount, 0)
else
heal_overall_damage(-amount, 0)
/mob/living/carbon/human/adjustFireLoss(var/amount)
if(amount > 0)
take_overall_damage(0, amount)
else
heal_overall_damage(0, -amount)
/mob/living/carbon/human/Stun(amount)
if(HULK in mutations) return
..()
/mob/living/carbon/human/Weaken(amount)
if(HULK in mutations) return
..()
/mob/living/carbon/human/Paralyse(amount)
if(HULK in mutations) return
..()
/mob/living/carbon/human/adjustCloneLoss(var/amount)
..()
var/heal_prob = max(0, 80 - getCloneLoss())
var/mut_prob = min(80, getCloneLoss()+10)
if (amount > 0)
if (prob(mut_prob))
var/list/datum/organ/external/candidates = list()
for (var/datum/organ/external/O in organs)
if(!(O.status & ORGAN_MUTATED))
candidates |= O
if (candidates.len)
var/datum/organ/external/O = pick(candidates)
O.mutate()
src << "<span class = 'notice'>Something is not right with your [O.display_name]...</span>"
return
else
if (prob(heal_prob))
for (var/datum/organ/external/O in organs)
if (O.status & ORGAN_MUTATED)
O.unmutate()
src << "<span class = 'notice'>Your [O.display_name] is shaped normally again.</span>"
return
if (getCloneLoss() < 1)
for (var/datum/organ/external/O in organs)
if (O.status & ORGAN_MUTATED)
O.unmutate()
src << "<span class = 'notice'>Your [O.display_name] is shaped normally again.</span>"
////////////////////////////////////////////
//Returns a list of damaged organs
/mob/living/carbon/human/proc/get_damaged_organs(var/brute, var/burn)
var/list/datum/organ/external/parts = list()
for(var/datum/organ/external/O in organs)
if((brute && O.brute_dam) || (burn && O.burn_dam))
parts += O
return parts
//Returns a list of damageable organs
/mob/living/carbon/human/proc/get_damageable_organs()
var/list/datum/organ/external/parts = list()
for(var/datum/organ/external/O in organs)
if(O.brute_dam + O.burn_dam < O.max_damage)
parts += O
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(var/brute, var/burn)
var/list/datum/organ/external/parts = get_damaged_organs(brute,burn)
if(!parts.len) return
var/datum/organ/external/picked = pick(parts)
if(picked.heal_damage(brute,burn))
UpdateDamageIcon()
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(var/brute, var/burn, var/sharp = 0)
var/list/datum/organ/external/parts = get_damageable_organs()
if(!parts.len) return
var/datum/organ/external/picked = pick(parts)
if(picked.take_damage(brute,burn,sharp))
UpdateDamageIcon()
updatehealth()
//Heal MANY external organs, in random order
/mob/living/carbon/human/heal_overall_damage(var/brute, var/burn)
var/list/datum/organ/external/parts = get_damaged_organs(brute,burn)
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/datum/organ/external/picked = pick(parts)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.heal_damage(brute,burn)
brute -= (brute_was-picked.brute_dam)
burn -= (burn_was-picked.burn_dam)
parts -= picked
updatehealth()
if(update) UpdateDamageIcon()
// damage MANY external organs, in random order
/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/used_weapon = null)
if(status_flags & GODMODE) return //godmode
var/list/datum/organ/external/parts = get_damageable_organs()
var/update = 0
while(parts.len && (brute>0 || burn>0) )
var/datum/organ/external/picked = pick(parts)
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
update |= picked.take_damage(brute,burn,sharp,used_weapon)
brute -= (picked.brute_dam - brute_was)
burn -= (picked.burn_dam - burn_was)
parts -= picked
updatehealth()
if(update) UpdateDamageIcon()
////////////////////////////////////////////
/*
This function restores the subjects blood to max.
*/
/mob/living/carbon/human/proc/restore_blood()
var/blood_volume = vessel.get_reagent_amount("blood")
vessel.add_reagent("blood",560.0-blood_volume)
/*
This function restores all organs.
*/
/mob/living/carbon/human/restore_all_organs()
for(var/datum/organ/external/current_organ in organs)
current_organ.rejuvenate()
/mob/living/carbon/human/proc/HealDamage(zone, brute, burn)
var/datum/organ/external/E = get_organ(zone)
if(istype(E, /datum/organ/external))
if (E.heal_damage(brute, burn))
UpdateDamageIcon()
else
return 0
return
/mob/living/carbon/human/proc/get_organ(var/zone)
if(!zone) zone = "chest"
if (zone in list( "eyes", "mouth" ))
zone = "head"
return organs_by_name[zone]
/mob/living/carbon/human/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/obj/used_weapon = null)
//visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]")
if((damagetype != BRUTE) && (damagetype != BURN))
..(damage, damagetype, def_zone, blocked)
return 1
if(blocked >= 2) return 0
var/datum/organ/external/organ = null
if(isorgan(def_zone))
organ = def_zone
else
if(!def_zone) def_zone = ran_zone(def_zone)
organ = get_organ(check_zone(def_zone))
if(!organ) return 0
if(blocked)
damage = (damage/(blocked+1))
switch(damagetype)
if(BRUTE)
damageoverlaytemp = 20
if(organ.take_damage(damage, 0, sharp, used_weapon))
UpdateDamageIcon()
if(BURN)
damageoverlaytemp = 20
if(organ.take_damage(0, damage, sharp, used_weapon))
UpdateDamageIcon()
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
updatehealth()
//Embedded projectile code.
if(!organ) return
if(istype(used_weapon,/obj/item/weapon))
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
organ.implants += W
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
embedded_flag = 1
src.verbs += /mob/proc/yank_out_object
W.add_blood(src)
if(ismob(W.loc))
var/mob/living/H = W.loc
H.drop_item()
W.loc = src
return 1
@@ -0,0 +1,298 @@
/*
Contains most of the procs that are called when a mob is attacked by something
bullet_act
ex_act
meteor_act
emp_act
*/
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
// BEGIN TASER NERF
/* Commenting out new-old taser nerf.
if(C.siemens_coefficient == 0) //If so, is that clothing shock proof?
if(prob(deflectchance))
visible_message("\red <B>The [P.name] gets deflected by [src]'s [C.name]!</B>") //DEFLECT!
visible_message("\red <B> Taser hit for [P.damage] damage!</B>")
del P
*/
/* Commenting out old Taser nerf
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor))
if(istype(P, /obj/item/projectile/energy/electrode))
visible_message("\red <B>The [P.name] gets deflected by [src]'s [wear_suit.name]!</B>")
del P
return -1
*/
// END TASER NERF
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof))
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 40 - round(P.damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
if(prob(reflectchance))
visible_message("\red <B>The [P.name] gets reflected by [src]'s [wear_suit.name]!</B>")
// Find a turf near or on the original location to bounce to
if(P.starting)
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
var/turf/curloc = get_turf(src)
// redirect the projectile
P.original = locate(new_x, new_y, P.z)
P.starting = curloc
P.current = curloc
P.firer = src
P.yo = new_y - curloc.y
P.xo = new_x - curloc.x
return -1 // complete projectile permutation
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2)
return 2
//BEGIN BOOK'S TASER NERF.
if(istype(P, /obj/item/projectile/energy/electrode))
var/datum/organ/external/select_area = get_organ(def_zone) // We're checking the outside, buddy!
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
// var/deflectchance=90 //Is it a CRITICAL HIT with that taser?
for(var/bp in body_parts) //Make an unregulated var to pass around.
if(!bp)
continue //Does this thing we're shooting even exist?
if(bp && istype(bp ,/obj/item/clothing)) // If it exists, and it's clothed
var/obj/item/clothing/C = bp // Then call an argument C to be that clothing!
if(C.body_parts_covered & select_area.body_part) // Is that body part being targeted covered?
P.agony=P.agony*C.siemens_coefficient
apply_effect(P.agony,AGONY,0)
flash_pain()
src <<"\red You have been shot!"
del P
var/obj/item/weapon/cloaking_device/C = locate((/obj/item/weapon/cloaking_device) in src)
if(C && C.active)
C.attack_self(src)//Should shut it off
update_icons()
src << "\blue Your [C.name] was disrupted!"
Stun(2)
if(istype(equipped(),/obj/item/device/assembly/signaler))
var/obj/item/device/assembly/signaler/signaler = equipped()
if(signaler.deadman && prob(80))
src.visible_message("\red [src] triggers their deadman's switch!")
signaler.signal()
return
//END TASER NERF
var/datum/organ/external/organ = get_organ(check_zone(def_zone))
var/armor = checkarmor(organ, "bullet")
if((P.embed && prob(20 + max(P.damage - armor, -10))) && P.damage_type == BRUTE)
var/obj/item/weapon/shard/shrapnel/SP = new()
(SP.name) = "[P.name] shrapnel"
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
(SP.loc) = organ
organ.implants += SP
visible_message("<span class='danger'>The projectile sticks in the wound!</span>")
embedded_flag = 1
src.verbs += /mob/proc/yank_out_object
SP.add_blood(src)
return (..(P , def_zone))
/mob/living/carbon/human/getarmor(var/def_zone, var/type)
var/armorval = 0
var/organnum = 0
if(def_zone)
if(isorgan(def_zone))
return checkarmor(def_zone, type)
var/datum/organ/external/affecting = get_organ(ran_zone(def_zone))
return checkarmor(affecting, type)
//If a specific bodypart is targetted, check how that bodypart is protected and return the value.
//If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values
for(var/datum/organ/external/organ in organs)
armorval += checkarmor(organ, type)
organnum++
return (armorval/max(organnum, 1))
/mob/living/carbon/human/proc/checkarmor(var/datum/organ/external/def_zone, var/type)
if(!type) return 0
var/protection = 0
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
for(var/bp in body_parts)
if(!bp) continue
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]
return protection
/mob/living/carbon/human/proc/check_head_coverage()
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform)
for(var/bp in body_parts)
if(!bp) continue
if(bp && istype(bp ,/obj/item/clothing))
var/obj/item/clothing/C = bp
if(C.body_parts_covered & HEAD)
return 1
return 0
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack")
if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3)
var/obj/item/weapon/I = l_hand
if(I.IsShield() && (prob(50 - round(damage / 3))))
visible_message("\red <B>[src] blocks [attack_text] with the [l_hand.name]!</B>")
return 1
if(r_hand && istype(r_hand, /obj/item/weapon))
var/obj/item/weapon/I = r_hand
if(I.IsShield() && (prob(50 - round(damage / 3))))
visible_message("\red <B>[src] blocks [attack_text] with the [r_hand.name]!</B>")
return 1
if(wear_suit && istype(wear_suit, /obj/item/))
var/obj/item/I = wear_suit
if(I.IsShield() && (prob(35)))
visible_message("\red <B>The reactive teleport system flings [src] clear of [attack_text]!</B>")
var/list/turfs = new/list()
for(var/turf/T in orange(6))
if(istype(T,/turf/space)) continue
if(T.density) continue
if(T.x>world.maxx-6 || T.x<6) continue
if(T.y>world.maxy-6 || T.y<6) continue
turfs += T
if(!turfs.len) turfs += pick(/turf in orange(6))
var/turf/picked = pick(turfs)
if(!isturf(picked)) return
src.loc = picked
return 1
return 0
/mob/living/carbon/human/emp_act(severity)
for(var/obj/O in src)
if(!O) continue
O.emp_act(severity)
for(var/datum/organ/external/O in organs)
if(O.status & ORGAN_DESTROYED) continue
O.emp_act(severity)
for(var/datum/organ/internal/I in O.internal_organs)
if(I.robotic == 0) continue
I.emp_act(severity)
..()
/mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone)
if(!I || !user) return 0
var/target_zone = get_zone_with_miss_chance(user.zone_sel.selecting, src)
if(user == src) // Attacking yourself can't miss
target_zone = user.zone_sel.selecting
if(!target_zone)
visible_message("\red <B>[user] misses [src] with \the [I]!")
return 0
var/datum/organ/external/affecting = get_organ(target_zone)
if (!affecting)
return 0
if(affecting.status & ORGAN_DESTROYED)
user << "What [affecting.display_name]?"
return 0
var/hit_area = affecting.display_name
if((user != src) && check_shields(I.force, "the [I.name]"))
return 0
if(istype(I,/obj/item/weapon/card/emag))
if(!(affecting.status & ORGAN_ROBOT))
user << "\red That limb isn't robotic."
return
if(affecting.sabotaged)
user << "\red [src]'s [affecting.display_name] is already sabotaged!"
else
user << "\red You sneakily slide [I] into the dataport on [src]'s [affecting.display_name] and short out the safeties."
var/obj/item/weapon/card/emag/emag = I
emag.uses--
affecting.sabotaged = 1
return 1
if(I.attack_verb.len)
visible_message("\red <B>[src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!</B>")
else
visible_message("\red <B>[src] has been attacked in the [hit_area] with [I.name] by [user]!</B>")
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].")
if(armor >= 2) return 0
if(!I.force) return 0
apply_damage(I.force, I.damtype, affecting, armor , is_sharp(I), I)
var/bloody = 0
if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (I.force * 2)))
I.add_blood(src) //Make the weapon bloody, not the person.
// if(user.hand) user.update_inv_l_hand() //updates the attacker's overlay for the (now bloodied) weapon
// else user.update_inv_r_hand() //removed because weapons don't have on-mob blood overlays
if(prob(33))
bloody = 1
var/turf/location = loc
if(istype(location, /turf/simulated))
location.add_blood(src)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(get_dist(H, src) <= 1) //people with TK won't get smeared with blood
H.bloody_body(src)
H.bloody_hands(src)
switch(hit_area)
if("head")//Harder to score a stun but if you do it lasts a bit longer
if(prob(I.force))
apply_effect(20, PARALYZE, armor)
visible_message("\red <B>[src] has been knocked unconscious!</B>")
if(src != user && I.damtype == BRUTE)
ticker.mode.remove_revolutionary(mind)
if(bloody)//Apply blood
if(wear_mask)
wear_mask.add_blood(src)
update_inv_wear_mask(0)
if(head)
head.add_blood(src)
update_inv_head(0)
if(glasses && prob(33))
glasses.add_blood(src)
update_inv_glasses(0)
if("chest")//Easier to score a stun but lasts less time
if(prob((I.force + 10)))
apply_effect(5, WEAKEN, armor)
visible_message("\red <B>[src] has been knocked down!</B>")
if(bloody)
bloody_body(src)
return 1
/mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2)
if (gloves)
gloves.add_blood(source)
gloves:transfer_blood = amount
gloves:bloody_hands_mob = source
else
add_blood(source)
bloody_hands = amount
bloody_hands_mob = source
update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
/mob/living/carbon/human/proc/bloody_body(var/mob/living/source)
if(wear_suit)
wear_suit.add_blood(source)
update_inv_wear_suit(0)
if(w_uniform)
w_uniform.add_blood(source)
update_inv_w_uniform(0)
@@ -0,0 +1,59 @@
/mob/living/carbon/human
//Hair colour and style
var/r_hair = 0
var/g_hair = 0
var/b_hair = 0
var/h_style = "Bald"
//Facial hair colour and style
var/r_facial = 0
var/g_facial = 0
var/b_facial = 0
var/f_style = "Shaved"
//Eye colour
var/r_eyes = 0
var/g_eyes = 0
var/b_eyes = 0
var/s_tone = 0 //Skin tone
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
var/age = 30 //Player's age (pure fluff)
var/b_type = "A+" //Player's bloodtype
var/underwear = 1 //Which underwear the player wants
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
//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/glasses = null
var/obj/item/head = null
var/obj/item/l_ear = null
var/obj/item/r_ear = null
var/obj/item/wear_id = null
var/obj/item/r_store = null
var/obj/item/l_store = null
var/obj/item/s_store = null
var/used_skillpoints = 0
var/skill_specialization = null
var/list/skills = null
var/icon/stand_icon = null
var/icon/lying_icon = null
var/miming = null //Toggle for the mime's abilities.
var/special_voice = "" // For changing our voice. Used by a symptom.
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/xylophone = 0 //For the spoooooooky xylophone cooldown
var/mob/remoteview_target = null
var/hand_blood_color
@@ -0,0 +1,83 @@
/mob/living/carbon/human/movement_delay()
var/tally = 0
if(species && species.flags & IS_SLOW)
tally = 7
if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything
if(embedded_flag)
handle_embedded_objects() //Moving with objects stuck in you can cause bad times.
if(reagents.has_reagent("hyperzine")) return -1
if(reagents.has_reagent("nuka_cola")) return -1
var/health_deficiency = (100 - health + halloss)
if(health_deficiency >= 40) tally += (health_deficiency / 25)
var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
if (hungry >= 70) tally += hungry/50
if(wear_suit)
tally += wear_suit.slowdown
if(shoes)
tally += shoes.slowdown
for(var/organ_name in list("l_foot","r_foot","l_leg","r_leg"))
var/datum/organ/external/E = get_organ(organ_name)
if(!E || (E.status & ORGAN_DESTROYED))
tally += 4
if(E.status & ORGAN_SPLINTED)
tally += 0.5
else if(E.status & ORGAN_BROKEN)
tally += 1.5
if(shock_stage >= 10) tally += 3
if(FAT in src.mutations)
tally += 1.5
if (bodytemperature < 283.222)
tally += (283.222 - bodytemperature) / 10 * 1.75
if(mRun in mutations)
tally = 0
return (tally+config.human_delay)
/mob/living/carbon/human/Process_Spacemove(var/check_drift = 0)
//Can we act
if(restrained()) return 0
//Do we have a working jetpack
if(istype(back, /obj/item/weapon/tank/jetpack))
var/obj/item/weapon/tank/jetpack/J = back
if(((!check_drift) || (check_drift && J.stabilization_on)) && (!lying) && (J.allow_thrust(0.01, src)))
inertia_dir = 0
return 1
// if(!check_drift && J.allow_thrust(0.01, src))
// return 1
//If no working jetpack then use the other checks
if(..()) return 1
return 0
/mob/living/carbon/human/Process_Spaceslipping(var/prob_slip = 5)
//If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such.
if(stat)
prob_slip = 0 // Changing this to zero to make it line up with the comment, and also, make more sense.
//Do we have magboots or such on if so no slip
if(istype(shoes, /obj/item/clothing/shoes/magboots) && (shoes.flags & NOSLIP))
prob_slip = 0
//Check hands and mod slip
if(!l_hand) prob_slip -= 2
else if(l_hand.w_class <= 2) prob_slip -= 1
if (!r_hand) prob_slip -= 2
else if(r_hand.w_class <= 2) prob_slip -= 1
prob_slip = round(prob_slip)
return(prob_slip)
@@ -0,0 +1,728 @@
/mob/living/carbon/human/verb/quick_equip()
set name = "quick-equip"
set hidden = 1
if(ishuman(src))
var/mob/living/carbon/human/H = src
var/obj/item/I = H.get_active_hand()
if(!I)
H << "<span class='notice'>You are not holding anything to equip.</span>"
return
if(H.equip_to_appropriate_slot(I))
if(hand)
update_inv_l_hand(0)
else
update_inv_r_hand(0)
else
H << "\red You are unable to equip that."
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1)
for (var/slot in slots)
if (equip_to_slot_if_possible(W, slots[slot], del_on_fail = 0))
return slot
if (del_on_fail)
del(W)
return null
/mob/living/carbon/human/proc/has_organ(name)
var/datum/organ/external/O = organs_by_name[name]
return (O && !(O.status & ORGAN_DESTROYED) )
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
switch(slot)
if(slot_back)
return has_organ("chest")
if(slot_wear_mask)
return has_organ("head")
if(slot_handcuffed)
return has_organ("l_hand") && has_organ("r_hand")
if(slot_legcuffed)
return has_organ("l_leg") && has_organ("r_leg")
if(slot_l_hand)
return has_organ("l_hand")
if(slot_r_hand)
return has_organ("r_hand")
if(slot_belt)
return has_organ("chest")
if(slot_wear_id)
// the only relevant check for this is the uniform check
return 1
if(slot_l_ear)
return has_organ("head")
if(slot_r_ear)
return has_organ("head")
if(slot_glasses)
return has_organ("head")
if(slot_gloves)
return has_organ("l_hand") && has_organ("r_hand")
if(slot_head)
return has_organ("head")
if(slot_shoes)
return has_organ("r_foot") && has_organ("l_foot")
if(slot_wear_suit)
return has_organ("chest")
if(slot_w_uniform)
return has_organ("chest")
if(slot_l_store)
return has_organ("chest")
if(slot_r_store)
return has_organ("chest")
if(slot_s_store)
return has_organ("chest")
if(slot_in_backpack)
return 1
/mob/living/carbon/human/u_equip(obj/item/W as obj)
if(!W) return 0
var/success
if (W == wear_suit)
if(s_store)
drop_from_inventory(s_store)
if(W)
success = 1
wear_suit = null
update_inv_wear_suit()
else if (W == w_uniform)
if (r_store)
drop_from_inventory(r_store)
if (l_store)
drop_from_inventory(l_store)
if (wear_id)
drop_from_inventory(wear_id)
if (belt)
drop_from_inventory(belt)
w_uniform = null
success = 1
update_inv_w_uniform()
else if (W == gloves)
gloves = null
success = 1
update_inv_gloves()
else if (W == glasses)
glasses = null
success = 1
update_inv_glasses()
else if (W == head)
head = null
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
update_hair(0) //rebuild hair
success = 1
update_inv_head()
else if (W == l_ear)
l_ear = null
success = 1
update_inv_ears()
else if (W == r_ear)
r_ear = null
success = 1
update_inv_ears()
else if (W == shoes)
shoes = null
success = 1
update_inv_shoes()
else if (W == belt)
belt = null
success = 1
update_inv_belt()
else if (W == wear_mask)
wear_mask = null
success = 1
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
update_hair(0) //rebuild hair
if(internal)
if(internals)
internals.icon_state = "internal0"
internal = null
update_inv_wear_mask()
else if (W == wear_id)
wear_id = null
success = 1
update_inv_wear_id()
else if (W == r_store)
r_store = null
success = 1
update_inv_pockets()
else if (W == l_store)
l_store = null
success = 1
update_inv_pockets()
else if (W == s_store)
s_store = null
success = 1
update_inv_s_store()
else if (W == back)
back = null
success = 1
update_inv_back()
else if (W == handcuffed)
handcuffed = null
success = 1
update_inv_handcuffed()
else if (W == legcuffed)
legcuffed = null
success = 1
update_inv_legcuffed()
else if (W == r_hand)
r_hand = null
success = 1
update_inv_r_hand()
else if (W == l_hand)
l_hand = null
success = 1
update_inv_l_hand()
else
return 0
if(success)
if (W)
if (client)
client.screen -= W
W.loc = loc
W.dropped(src)
//if(W)
//W.layer = initial(W.layer)
update_action_buttons()
return 1
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc.
/mob/living/carbon/human/equip_to_slot(obj/item/W as obj, slot, redraw_mob = 1)
if(!slot) return
if(!istype(W)) return
if(!has_organ_for_slot(slot)) return
if(W == src.l_hand)
src.l_hand = null
update_inv_l_hand() //So items actually disappear from hands.
else if(W == src.r_hand)
src.r_hand = null
update_inv_r_hand()
W.loc = src
switch(slot)
if(slot_back)
src.back = W
W.equipped(src, slot)
update_inv_back(redraw_mob)
if(slot_wear_mask)
src.wear_mask = W
if((wear_mask.flags & BLOCKHAIR) || (wear_mask.flags & BLOCKHEADHAIR))
update_hair(redraw_mob) //rebuild hair
W.equipped(src, slot)
update_inv_wear_mask(redraw_mob)
if(slot_handcuffed)
src.handcuffed = W
update_inv_handcuffed(redraw_mob)
if(slot_legcuffed)
src.legcuffed = W
W.equipped(src, slot)
update_inv_legcuffed(redraw_mob)
if(slot_l_hand)
src.l_hand = W
W.equipped(src, slot)
update_inv_l_hand(redraw_mob)
if(slot_r_hand)
src.r_hand = W
W.equipped(src, slot)
update_inv_r_hand(redraw_mob)
if(slot_belt)
src.belt = W
W.equipped(src, slot)
update_inv_belt(redraw_mob)
if(slot_wear_id)
src.wear_id = W
W.equipped(src, slot)
update_inv_wear_id(redraw_mob)
if(slot_l_ear)
src.l_ear = W
if(l_ear.slot_flags & SLOT_TWOEARS)
var/obj/item/clothing/ears/offear/O = new(W)
O.loc = src
src.r_ear = O
O.layer = 20
W.equipped(src, slot)
update_inv_ears(redraw_mob)
if(slot_r_ear)
src.r_ear = W
if(r_ear.slot_flags & SLOT_TWOEARS)
var/obj/item/clothing/ears/offear/O = new(W)
O.loc = src
src.l_ear = O
O.layer = 20
W.equipped(src, slot)
update_inv_ears(redraw_mob)
if(slot_glasses)
src.glasses = W
W.equipped(src, slot)
update_inv_glasses(redraw_mob)
if(slot_gloves)
src.gloves = W
W.equipped(src, slot)
update_inv_gloves(redraw_mob)
if(slot_head)
src.head = W
if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR))
update_hair(redraw_mob) //rebuild hair
if(istype(W,/obj/item/clothing/head/kitty))
W.update_icon(src)
W.equipped(src, slot)
update_inv_head(redraw_mob)
if(slot_shoes)
src.shoes = W
W.equipped(src, slot)
update_inv_shoes(redraw_mob)
if(slot_wear_suit)
src.wear_suit = W
W.equipped(src, slot)
update_inv_wear_suit(redraw_mob)
if(slot_w_uniform)
src.w_uniform = W
W.equipped(src, slot)
update_inv_w_uniform(redraw_mob)
if(slot_l_store)
src.l_store = W
W.equipped(src, slot)
update_inv_pockets(redraw_mob)
if(slot_r_store)
src.r_store = W
W.equipped(src, slot)
update_inv_pockets(redraw_mob)
if(slot_s_store)
src.s_store = W
W.equipped(src, slot)
update_inv_s_store(redraw_mob)
if(slot_in_backpack)
if(src.get_active_hand() == W)
src.u_equip(W)
W.loc = src.back
else
src << "\red You are trying to eqip this item to an unsupported inventory slot. How the heck did you manage that? Stop it..."
return
W.layer = 20
return
/obj/effect/equip_e
name = "equip e"
var/mob/source = null
var/s_loc = null //source location
var/t_loc = null //target location
var/obj/item/item = null
var/place = null
/obj/effect/equip_e/human
name = "human"
var/mob/living/carbon/human/target = null
/obj/effect/equip_e/monkey
name = "monkey"
var/mob/living/carbon/monkey/target = null
/obj/effect/equip_e/process()
return
/obj/effect/equip_e/proc/done()
return
/obj/effect/equip_e/New()
if (!ticker)
del(src)
spawn(100)
del(src)
..()
return
/obj/effect/equip_e/human/process()
if (item)
item.add_fingerprint(source)
else
switch(place)
if("mask")
if (!( target.wear_mask ))
del(src)
if("l_hand")
if (!( target.l_hand ))
del(src)
if("r_hand")
if (!( target.r_hand ))
del(src)
if("suit")
if (!( target.wear_suit ))
del(src)
if("uniform")
if (!( target.w_uniform ))
del(src)
if("back")
if (!( target.back ))
del(src)
if("syringe")
return
if("pill")
return
if("fuel")
return
if("drink")
return
if("dnainjector")
return
if("handcuff")
if (!( target.handcuffed ))
del(src)
if("id")
if ((!( target.wear_id ) || !( target.w_uniform )))
del(src)
if("splints")
var/count = 0
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
var/datum/organ/external/o = target.organs_by_name[organ]
if(o.status & ORGAN_SPLINTED)
count = 1
break
if(count == 0)
del(src)
return
if("internal")
if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal )))
del(src)
var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel")
if ((item && !( L.Find(place) )))
if(isrobot(source) && place != "handcuff")
del(src)
for(var/mob/O in viewers(target, null))
O.show_message("\red <B>[source] is trying to put \a [item] on [target]</B>", 1)
else
var/message=null
switch(place)
if("syringe")
message = "\red <B>[source] is trying to inject [target]!</B>"
if("pill")
message = "\red <B>[source] is trying to force [target] to swallow [item]!</B>"
if("drink")
message = "\red <B>[source] is trying to force [target] to swallow a gulp of [item]!</B>"
if("dnainjector")
message = "\red <B>[source] is trying to inject [target] with the [item]!</B>"
if("mask")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had their mask removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) mask</font>")
if(target.wear_mask && !target.wear_mask.canremove)
message = "\red <B>[source] fails to take off \a [target.wear_mask] from [target]'s head!</B>"
return
else
message = "\red <B>[source] is trying to take off \a [target.wear_mask] from [target]'s head!</B>"
if("l_hand")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their left hand item ([target.l_hand]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) left hand item ([target.l_hand])</font>")
message = "\red <B>[source] is trying to take off \a [target.l_hand] from [target]'s left hand!</B>"
if("r_hand")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their right hand item ([target.r_hand]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) right hand item ([target.r_hand])</font>")
message = "\red <B>[source] is trying to take off \a [target.r_hand] from [target]'s right hand!</B>"
if("gloves")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their gloves ([target.gloves]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) gloves ([target.gloves])</font>")
if(target.gloves && !target.gloves.canremove)
message = "\red <B>[source] fails to take off \a [target.gloves] from [target]'s hands!</B>"
return
else
message = "\red <B>[source] is trying to take off the [target.gloves] from [target]'s hands!</B>"
if("eyes")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their eyewear ([target.glasses]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) eyewear ([target.glasses])</font>")
if(target.glasses && !target.glasses.canremove)
message = "\red <B>[source] fails to take off \a [target.glasses] from [target]'s eyes!</B>"
return
else
message = "\red <B>[source] is trying to take off the [target.glasses] from [target]'s eyes!</B>"
if("l_ear")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their left ear item ([target.l_ear]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) left ear item ([target.l_ear])</font>")
if(target.l_ear && !target.l_ear.canremove)
message = "\red <B>[source] fails to take off \a [target.l_ear] from [target]'s left ear!</B>"
return
else
message = "\red <B>[source] is trying to take off the [target.l_ear] from [target]'s left ear!</B>"
if("r_ear")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their right ear item ([target.r_ear]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) right ear item ([target.r_ear])</font>")
if(target.r_ear && !target.r_ear.canremove)
message = "\red <B>[source] fails to take off \a [target.r_ear] from [target]'s right ear!</B>"
return
else
message = "\red <B>[source] is trying to take off the [target.r_ear] from [target]'s right ear!</B>"
if("head")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their hat ([target.head]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) hat ([target.head])</font>")
if(target.head && !target.head.canremove)
message = "\red <B>[source] fails to take off \a [target.head] from [target]'s head!</B>"
return
else
message = "\red <B>[source] is trying to take off the [target.head] from [target]'s head!</B>"
if("shoes")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their shoes ([target.shoes]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) shoes ([target.shoes])</font>")
if(target.shoes && !target.shoes.canremove)
message = "\red <B>[source] fails to take off \a [target.shoes] from [target]'s feet!</B>"
return
else
message = "\red <B>[source] is trying to take off the [target.shoes] from [target]'s feet!</B>"
if("belt")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their belt item ([target.belt]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) belt item ([target.belt])</font>")
message = "\red <B>[source] is trying to take off the [target.belt] from [target]'s belt!</B>"
if("suit")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their suit ([target.wear_suit]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) suit ([target.wear_suit])</font>")
if(target.wear_suit && !target.wear_suit.canremove)
message = "\red <B>[source] fails to take off \a [target.wear_suit] from [target]'s body!</B>"
return
else
message = "\red <B>[source] is trying to take off \a [target.wear_suit] from [target]'s body!</B>"
if("back")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their back item ([target.back]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) back item ([target.back])</font>")
message = "\red <B>[source] is trying to take off \a [target.back] from [target]'s back!</B>"
if("handcuff")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Was unhandcuffed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to unhandcuff [target.name]'s ([target.ckey])</font>")
message = "\red <B>[source] is trying to unhandcuff [target]!</B>"
if("legcuff")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Was unlegcuffed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to unlegcuff [target.name]'s ([target.ckey])</font>")
message = "\red <B>[source] is trying to unlegcuff [target]!</B>"
if("uniform")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their uniform ([target.w_uniform]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) uniform ([target.w_uniform])</font>")
for(var/obj/item/I in list(target.l_store, target.r_store))
if(I.on_found(source))
return
if(target.w_uniform && !target.w_uniform.canremove)
message = "\red <B>[source] fails to take off \a [target.w_uniform] from [target]'s body!</B>"
return
else
message = "\red <B>[source] is trying to take off \a [target.w_uniform] from [target]'s body!</B>"
if("s_store")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their suit storage item ([target.s_store]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) suit storage item ([target.s_store])</font>")
message = "\red <B>[source] is trying to take off \a [target.s_store] from [target]'s suit!</B>"
if("pockets")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their pockets emptied by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to empty [target.name]'s ([target.ckey]) pockets</font>")
for(var/obj/item/I in list(target.l_store, target.r_store))
if(I.on_found(source))
return
message = "\red <B>[source] is trying to empty [target]'s pockets.</B>"
if("CPR")
if (!target.cpr_time)
del(src)
target.cpr_time = 0
message = "\red <B>[source] is trying perform CPR on [target]!</B>"
if("id")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their ID ([target.wear_id]) removed by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) ID ([target.wear_id])</font>")
message = "\red <B>[source] is trying to take off [target.wear_id] from [target]'s uniform!</B>"
if("internal")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their internals toggled by [source.name] ([source.ckey])</font>")
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to toggle [target.name]'s ([target.ckey]) internals</font>")
if (target.internal)
message = "\red <B>[source] is trying to remove [target]'s internals</B>"
else
message = "\red <B>[source] is trying to set on [target]'s internals.</B>"
if("splints")
message = text("\red <B>[] is trying to remove []'s splints!</B>", source, target)
for(var/mob/M in viewers(target, null))
M.show_message(message, 1)
spawn( HUMAN_STRIP_DELAY )
done()
return
return
/*
This proc equips stuff (or does something else) when removing stuff manually from the character window when you click and drag.
It works in conjuction with the process() above.
This proc works for humans only. Aliens stripping humans and the like will all use this proc. Stripping monkeys or somesuch will use their version of this proc.
The first if statement for "mask" and such refers to items that are already equipped and un-equipping them.
The else statement is for equipping stuff to empty slots.
!canremove refers to variable of /obj/item/clothing which either allows or disallows that item to be removed.
It can still be worn/put on as normal.
*/
/obj/effect/equip_e/human/done() //TODO: And rewrite this :< ~Carn
target.cpr_time = 1
if(isanimal(source)) return //animals cannot strip people
if(!source || !target) return //Target or source no longer exist
if(source.loc != s_loc) return //source has moved
if(target.loc != t_loc) return //target has moved
if(LinkBlocked(s_loc,t_loc)) return //Use a proxi!
if(item && source.get_active_hand() != item) return //Swapped hands / removed item from the active one
if ((source.restrained() || source.stat)) return //Source restrained or unconscious / dead
var/slot_to_process
var/strip_item //this will tell us which item we will be stripping - if any.
switch(place) //here we go again...
if("mask")
slot_to_process = slot_wear_mask
if (target.wear_mask && target.wear_mask.canremove)
strip_item = target.wear_mask
if("gloves")
slot_to_process = slot_gloves
if (target.gloves && target.gloves.canremove)
strip_item = target.gloves
if("eyes")
slot_to_process = slot_glasses
if (target.glasses)
strip_item = target.glasses
if("belt")
slot_to_process = slot_belt
if (target.belt)
strip_item = target.belt
if("s_store")
slot_to_process = slot_s_store
if (target.s_store)
strip_item = target.s_store
if("head")
slot_to_process = slot_head
if (target.head && target.head.canremove)
strip_item = target.head
if("l_ear")
slot_to_process = slot_l_ear
if (target.l_ear)
strip_item = target.l_ear
if("r_ear")
slot_to_process = slot_r_ear
if (target.r_ear)
strip_item = target.r_ear
if("shoes")
slot_to_process = slot_shoes
if (target.shoes && target.shoes.canremove)
strip_item = target.shoes
if("l_hand")
if (istype(target, /obj/item/clothing/suit/straight_jacket))
del(src)
slot_to_process = slot_l_hand
if (target.l_hand)
strip_item = target.l_hand
if("r_hand")
if (istype(target, /obj/item/clothing/suit/straight_jacket))
del(src)
slot_to_process = slot_r_hand
if (target.r_hand)
strip_item = target.r_hand
if("uniform")
slot_to_process = slot_w_uniform
if(target.w_uniform && target.w_uniform.canremove)
strip_item = target.w_uniform
if("suit")
slot_to_process = slot_wear_suit
if (target.wear_suit && target.wear_suit.canremove)
strip_item = target.wear_suit
if("id")
slot_to_process = slot_wear_id
if (target.wear_id)
strip_item = target.wear_id
if("back")
slot_to_process = slot_back
if (target.back)
strip_item = target.back
if("handcuff")
slot_to_process = slot_handcuffed
if (target.handcuffed)
strip_item = target.handcuffed
if("legcuff")
slot_to_process = slot_legcuffed
if (target.legcuffed)
strip_item = target.legcuffed
if("splints")
for(var/organ in list("l_leg","r_leg","l_arm","r_arm"))
var/datum/organ/external/o = target.get_organ(organ)
if (o && o.status & ORGAN_SPLINTED)
var/obj/item/W = new /obj/item/stack/medical/splint(amount=1)
o.status &= ~ORGAN_SPLINTED
if (W)
W.loc = target.loc
W.layer = initial(W.layer)
W.add_fingerprint(source)
if("CPR")
if ((target.health > config.health_threshold_dead && target.health < config.health_threshold_crit))
var/suff = min(target.getOxyLoss(), 5) //Pre-merge level, less healing, more prevention of dieing.
target.adjustOxyLoss(-suff)
target.updatehealth()
for(var/mob/O in viewers(source, null))
O.show_message("\red [source] performs CPR on [target]!", 1)
target << "\blue <b>You feel a breath of fresh air enter your lungs. It feels good.</b>"
source << "\red Repeat at least every 7 seconds."
if("dnainjector")
var/obj/item/weapon/dnainjector/S = item
if(S)
S.add_fingerprint(source)
if (!( istype(S, /obj/item/weapon/dnainjector) ))
S.inuse = 0
del(src)
S.inject(target, source)
if (S.s_time >= world.time + 30)
S.inuse = 0
del(src)
S.s_time = world.time
for(var/mob/O in viewers(source, null))
O.show_message("\red [source] injects [target] with the DNA Injector!", 1)
S.inuse = 0
if("pockets")
slot_to_process = slot_l_store
strip_item = target.l_store //We'll do both
if("internal")
if (target.internal)
target.internal.add_fingerprint(source)
target.internal = null
if (target.internals)
target.internals.icon_state = "internal0"
else
if (!( istype(target.wear_mask, /obj/item/clothing/mask) ))
return
else
if (istype(target.back, /obj/item/weapon/tank))
target.internal = target.back
else if (istype(target.s_store, /obj/item/weapon/tank))
target.internal = target.s_store
else if (istype(target.belt, /obj/item/weapon/tank))
target.internal = target.belt
if (target.internal)
for(var/mob/M in viewers(target, 1))
M.show_message("[target] is now running on internals.", 1)
target.internal.add_fingerprint(source)
if (target.internals)
target.internals.icon_state = "internal1"
if(slot_to_process)
if(strip_item) //Stripping an item from the mob
var/obj/item/W = strip_item
target.u_equip(W)
if (target.client)
target.client.screen -= W
if (W)
W.loc = target.loc
W.layer = initial(W.layer)
W.dropped(target)
W.add_fingerprint(source)
if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;)
if(target.r_store)
target.u_equip(target.r_store) //At this stage l_store is already processed by the code above, we only need to process r_store.
else
if(item && target.has_organ_for_slot(slot_to_process)) //Placing an item on the mob
if(item.mob_can_equip(target, slot_to_process, 0))
source.u_equip(item)
target.equip_to_slot_if_possible(item, slot_to_process, 0, 1, 1)
item.dropped(source)
source.update_icons()
target.update_icons()
if(source && target)
if(source.machine == target)
target.show_inv(source)
del(src)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
/mob/living/carbon/human/Login()
..()
update_hud()
ticker.mode.update_all_synd_icons() //This proc only sounds CPU-expensive on paper. It is O(n^2), but the outer for-loop only iterates through syndicates, which are only prsenet in nuke rounds and even when they exist, there's usually 6 of them.
return
@@ -0,0 +1,73 @@
/mob/living/carbon/human/say(var/message)
if(wear_mask)
if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja) && wear_mask:voice == "Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++)
pick_list += i
for(var/i=1, i <= abs(temp_message.len/3), i++)
var/H = pick(pick_list)
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
message = replacetext(message, "o", "¤")
message = replacetext(message, "p", "þ")
message = replacetext(message, "l", "£")
message = replacetext(message, "s", "§")
message = replacetext(message, "u", "µ")
message = replacetext(message, "b", "ß")
else if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
var/obj/item/clothing/mask/horsehead/hoers = wear_mask
if(hoers.voicechange)
if(!(copytext(message, 1, 2) == "*" || (mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling")))
message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
if ((HULK in mutations) && health >= 25 && length(message))
if(copytext(message, 1, 2) != "*")
message = "[uppertext(message)]!!" //because I don't know how to code properly in getting vars from other files -Bro
if (src.slurring)
if(copytext(message, 1, 2) != "*")
message = slur(message)
..(message)
/mob/living/carbon/human/say_understands(var/other,var/datum/language/speaking = null)
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
return 1
if (istype(other, /mob/living/silicon))
return 1
if (istype(other, /mob/living/carbon/brain))
return 1
if (istype(other, /mob/living/carbon/slime))
return 1
return ..()
/mob/living/carbon/human/GetVoice()
if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice))
var/obj/item/clothing/mask/gas/voice/V = src.wear_mask
if(V.vchange)
return V.voice
else
return name
if(mind && mind.changeling && mind.changeling.mimicing)
return mind.changeling.mimicing
if(GetSpecialVoice())
return GetSpecialVoice()
return real_name
/mob/living/carbon/human/proc/SetSpecialVoice(var/new_voice)
if(new_voice)
special_voice = new_voice
return
/mob/living/carbon/human/proc/UnsetSpecialVoice()
special_voice = ""
return
/mob/living/carbon/human/proc/GetSpecialVoice()
return special_voice
@@ -0,0 +1,791 @@
///////////////////////
//UPDATE_ICONS SYSTEM//
///////////////////////
/*
Calling this a system is perhaps a bit trumped up. It is essentially update_clothing dismantled into its
core parts. The key difference is that when we generate overlays we do not generate either lying or standing
versions. Instead, we generate both and store them in two fixed-length lists, both using the same list-index
(The indexes are in update_icons.dm): Each list for humans is (at the time of writing) of length 19.
This will hopefully be reduced as the system is refined.
var/overlays_lying[19] //For the lying down stance
var/overlays_standing[19] //For the standing stance
When we call update_icons, the 'lying' variable is checked and then the appropriate list is assigned to our overlays!
That in itself uses a tiny bit more memory (no more than all the ridiculous lists the game has already mind you).
On the other-hand, it should be very CPU cheap in comparison to the old system.
In the old system, we updated all our overlays every life() call, even if we were standing still inside a crate!
or dead!. 25ish overlays, all generated from scratch every second for every xeno/human/monkey and then applied.
More often than not update_clothing was being called a few times in addition to that! CPU was not the only issue,
all those icons had to be sent to every client. So really the cost was extremely cumulative. To the point where
update_clothing would frequently appear in the top 10 most CPU intensive procs during profiling.
Another feature of this new system is that our lists are indexed. This means we can update specific overlays!
So we only regenerate icons when we need them to be updated! This is the main saving for this system.
In practice this means that:
everytime you fall over, we just switch between precompiled lists. Which is fast and cheap.
Everytime you do something minor like take a pen out of your pocket, we only update the in-hand overlay
etc...
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) )
You will need to call the relevant update_inv_* proc:
update_inv_head()
update_inv_wear_suit()
update_inv_gloves()
update_inv_shoes()
update_inv_w_uniform()
update_inv_glasse()
update_inv_l_hand()
update_inv_r_hand()
update_inv_belt()
update_inv_wear_id()
update_inv_ears()
update_inv_s_store()
update_inv_pockets()
update_inv_back()
update_inv_handcuffed()
update_inv_wear_mask()
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_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows
update_mutantrace() //handles updating your appearance after setting the mutantrace var
UpdateDamageIcon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it)
update_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
...eyes were merged into update_body)
update_targeted() // Updates the target overlay when someone points a gun at you
> All of these procs update our overlays_lying and overlays_standing, and then call update_icons() by default.
If you wish to update several overlays at once, you can set the argument to 0 to disable the update and call
it manually:
e.g.
update_inv_head(0)
update_inv_l_hand(0)
update_inv_r_hand() //<---calls update_icons()
or equivillantly:
update_inv_head(0)
update_inv_l_hand(0)
update_inv_r_hand(0)
update_icons()
> If you need to update all overlays you can use regenerate_icons(). it works exactly like update_clothing used to.
> I reimplimented an old unused variable which was in the code called (coincidentally) var/update_icon
It can be used as another method of triggering regenerate_icons(). It's basically a flag that when set to non-zero
will call regenerate_icons() at the next life() call and then reset itself to 0.
The idea behind it is icons are regenerated only once, even if multiple events requested it.
This system is confusing and is still a WIP. It's primary goal is speeding up the controls of the game whilst
reducing processing costs. So please bear with me while I iron out the kinks. It will be worth it, I promise.
If I can eventually free var/lying stuff from the life() process altogether, stuns/death/status stuff
will become less affected by lag-spikes and will be instantaneous! :3
If you have any questions/constructive-comments/bugs-to-report/or have a massivly devestated butt...
Please contact me on #coderbus IRC. ~Carn x
*/
//Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1 //TODO: make part of body?
#define MUTATIONS_LAYER 2
#define DAMAGE_LAYER 3
#define UNIFORM_LAYER 4
#define ID_LAYER 5
#define SHOES_LAYER 6
#define GLOVES_LAYER 7
#define EARS_LAYER 8
#define SUIT_LAYER 9
#define GLASSES_LAYER 10
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
#define SUIT_STORE_LAYER 12
#define BACK_LAYER 13
#define HAIR_LAYER 14 //TODO: make part of head layer?
#define FACEMASK_LAYER 15
#define HEAD_LAYER 16
#define HANDCUFF_LAYER 17
#define LEGCUFF_LAYER 18
#define L_HAND_LAYER 19
#define R_HAND_LAYER 20
#define TAIL_LAYER 21 //bs12 specific. this hack is probably gonna come back to haunt me
#define TARGETED_LAYER 22 //BS12: Layer for the target overlay from weapon targeting system
#define TOTAL_LAYERS 22
//////////////////////////////////
/mob/living/carbon/human
var/list/overlays_standing[TOTAL_LAYERS]
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
var/icon/race_icon
var/icon/deform_icon
//UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING
//this proc is messy as I was forced to include some old laggy cloaking code to it so that I don't break cloakers
//I'll work on removing that stuff by rewriting some of the cloaking stuff at a later date.
/mob/living/carbon/human/update_icons()
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
update_hud() //TODO: remove the need for this
overlays.Cut()
var/stealth = 0
//cloaking devices. //TODO: get rid of this :<
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
if(S.active)
stealth = 1
break
if(stealth)
icon = 'icons/mob/human.dmi'
icon_state = "body_cloaked"
var/image/I = overlays_standing[L_HAND_LAYER]
if(istype(I)) overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I)) overlays += I
else
icon = stand_icon
for(var/image/I in overlays_standing)
overlays += I
if(lying)
var/matrix/M = matrix()
M.Turn(90)
M.Translate(1,-6)
src.transform = M
else
var/matrix/M = matrix()
src.transform = M
var/global/list/damage_icon_parts = list()
proc/get_damage_icon_part(damage_state, body_part)
if(damage_icon_parts["[damage_state]/[body_part]"] == null)
var/icon/DI = new /icon('icons/mob/dam_human.dmi', damage_state) // the damage icon for whole human
DI.Blend(new /icon('icons/mob/dam_mask.dmi', body_part), ICON_MULTIPLY) // mask with this organ's pixels
damage_icon_parts["[damage_state]/[body_part]"] = DI
return DI
else
return damage_icon_parts["[damage_state]/[body_part]"]
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
/mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1)
// first check whether something actually changed about damage appearance
var/damage_appearance = ""
for(var/datum/organ/external/O in organs)
if(O.status & ORGAN_DESTROYED) damage_appearance += "d"
else
damage_appearance += O.damage_state
if(damage_appearance == previous_damage_appearance)
// nothing to do here
return
previous_damage_appearance = damage_appearance
var/icon/standing = new /icon('icons/mob/dam_human.dmi', "00")
var/image/standing_image = new /image("icon" = standing)
// blend the individual damage states with our icons
for(var/datum/organ/external/O in organs)
if(!(O.status & ORGAN_DESTROYED))
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI = get_damage_icon_part(O.damage_state, O.icon_name)
standing_image.overlays += DI
overlays_standing[DAMAGE_LAYER] = standing_image
if(update_icons) update_icons()
//BASE MOB SPRITE
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
if(stand_icon) del(stand_icon)
var/husk_color_mod = rgb(96,88,80)
var/hulk_color_mod = rgb(48,224,40)
var/necrosis_color_mod = rgb(10,50,0)
var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete
var/fat = (FAT in src.mutations)
var/hulk = (HULK in src.mutations)
var/skeleton = (SKELETON in src.mutations)
var/g = "m"
if(gender == FEMALE) g = "f"
var/datum/organ/external/chest = get_organ("chest")
stand_icon = chest.get_icon(g)
if(!skeleton)
if(husk)
stand_icon.ColorTone(husk_color_mod)
else if(hulk)
var/list/TONE = ReadRGB(hulk_color_mod)
stand_icon.MapColors(rgb(TONE[1],0,0),rgb(0,TONE[2],0),rgb(0,0,TONE[3]))
var/datum/organ/external/head = get_organ("head")
var/has_head = 0
if(head && !(head.status & ORGAN_DESTROYED))
has_head = 1
for(var/datum/organ/external/part in organs)
if(!istype(part, /datum/organ/external/chest) && !(part.status & ORGAN_DESTROYED))
var/icon/temp
if (istype(part, /datum/organ/external/groin) || istype(part, /datum/organ/external/head))
temp = part.get_icon(g)
else
temp = part.get_icon()
if(part.status & ORGAN_DEAD)
temp.ColorTone(necrosis_color_mod)
temp.SetIntensity(0.7)
else if(!skeleton)
if(husk)
temp.ColorTone(husk_color_mod)
else if(hulk)
var/list/TONE = ReadRGB(hulk_color_mod)
temp.MapColors(rgb(TONE[1],0,0),rgb(0,TONE[2],0),rgb(0,0,TONE[3]))
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
//And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
if(part.icon_position&(LEFT|RIGHT))
var/icon/temp2 = new('icons/mob/human.dmi',"blank")
temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH)
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
if(!(part.icon_position & LEFT))
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
if(!(part.icon_position & RIGHT))
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
stand_icon.Blend(temp2, ICON_OVERLAY)
temp2 = new('icons/mob/human.dmi',"blank")
if(part.icon_position & LEFT)
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
if(part.icon_position & RIGHT)
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
stand_icon.Blend(temp2, ICON_UNDERLAY)
else
stand_icon.Blend(temp, ICON_OVERLAY)
//Skin tone
if(!skeleton && !husk && !hulk && (species.flags & HAS_SKIN_TONE))
if(s_tone >= 0)
stand_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
else
stand_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
if(husk)
var/icon/mask = new(stand_icon)
var/icon/husk_over = new(race_icon,"overlay_husk")
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
husk_over.Blend(mask, ICON_ADD)
stand_icon.Blend(husk_over, ICON_OVERLAY)
if(has_head)
//Eyes
if(!skeleton)
var/icon/eyes = new/icon('icons/mob/human_face.dmi', species.eyes)
eyes.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
stand_icon.Blend(eyes, ICON_OVERLAY)
//Mouth (lipstick!)
if(lip_style && (species && species.flags & HAS_LIPS)) //skeletons are allowed to wear lipstick no matter what you think, agouri.
stand_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_s"), ICON_OVERLAY)
//Underwear
if(underwear >0 && underwear < 12 && species.flags & HAS_UNDERWEAR)
if(!fat && !skeleton)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
if(update_icons)
update_icons()
//tail
update_tail_showing(0)
//HAIR OVERLAY
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
//Reset our hair
overlays_standing[HAIR_LAYER] = null
var/datum/organ/external/head/head_organ = get_organ("head")
if( !head_organ || (head_organ.status & ORGAN_DESTROYED) )
if(update_icons) update_icons()
return
//masks and helmets can obscure our hair.
if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)))
if(update_icons) update_icons()
return
//base icons
var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
if(f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
if(facial_hair_style && src.species.name in facial_hair_style.species_allowed)
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
face_standing.Blend(facial_s, ICON_OVERLAY)
if(h_style && !(head && (head.flags & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
if(hair_style && src.species.name in hair_style.species_allowed)
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration)
hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
face_standing.Blend(hair_s, ICON_OVERLAY)
overlays_standing[HAIR_LAYER] = image(face_standing)
if(update_icons) update_icons()
/mob/living/carbon/human/update_mutations(var/update_icons=1)
var/fat
if(FAT in mutations)
fat = "fat"
var/image/standing = image("icon" = 'icons/effects/genetics.dmi')
var/add_image = 0
var/g = "m"
if(gender == FEMALE) g = "f"
// DNA2 - Drawing underlays.
for(var/datum/dna/gene/gene in dna_genes)
if(!gene.block)
continue
if(gene.is_active(src))
var/underlay=gene.OnDrawUnderlays(src,g,fat)
if(underlay)
standing.underlays += underlay
add_image = 1
for(var/mut in mutations)
switch(mut)
/*
if(HULK)
if(fat)
standing.underlays += "hulk_[fat]_s"
else
standing.underlays += "hulk_[g]_s"
add_image = 1
if(COLD_RESISTANCE)
standing.underlays += "fire[fat]_s"
add_image = 1
if(TK)
standing.underlays += "telekinesishead[fat]_s"
add_image = 1
*/
if(LASER)
standing.overlays += "lasereyes_s"
add_image = 1
if(add_image)
overlays_standing[MUTATIONS_LAYER] = standing
else
overlays_standing[MUTATIONS_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1)
var/fat
if( FAT in mutations )
fat = "fat"
// var/g = "m"
// if (gender == FEMALE) g = "f"
//BS12 EDIT
var/skeleton = (SKELETON in src.mutations)
if(skeleton)
race_icon = 'icons/mob/human_races/r_skeleton.dmi'
else
//Icon data is kept in species datums within the mob.
race_icon = species.icobase
deform_icon = species.deform
if(dna)
switch(dna.mutantrace)
if("golem","slime","shadow","adamantine")
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
else
overlays_standing[MUTANTRACE_LAYER] = null
if(!dna || !(dna.mutantrace in list("golem","metroid")))
update_body(0)
update_hair(0)
if(update_icons) update_icons()
//Call when target overlay should be added/removed
/mob/living/carbon/human/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
/* --------------------------------------- */
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
..()
if(monkeyizing) return
update_mutations(0)
update_mutantrace(0)
update_inv_w_uniform(0)
update_inv_wear_id(0)
update_inv_gloves(0)
update_inv_glasses(0)
update_inv_ears(0)
update_inv_shoes(0)
update_inv_s_store(0)
update_inv_wear_mask(0)
update_inv_head(0)
update_inv_belt(0)
update_inv_back(0)
update_inv_wear_suit(0)
update_inv_r_hand(0)
update_inv_l_hand(0)
update_inv_handcuffed(0)
update_inv_legcuffed(0)
update_inv_pockets(0)
UpdateDamageIcon()
update_icons()
//Hud Stuff
update_hud()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1)
if(w_uniform && istype(w_uniform, /obj/item/clothing/under) )
w_uniform.screen_loc = ui_iclothing
var/t_color = w_uniform.item_color
if(!t_color) t_color = icon_state
var/image/standing = image("icon_state" = "[t_color]_s")
standing.icon = ((w_uniform.icon_override) ? w_uniform.icon_override : 'icons/mob/uniform.dmi')
if(w_uniform.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood")
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE.
var/tie_color = w_uniform:hastie.item_color
if(!tie_color) tie_color = w_uniform:hastie.icon_state
standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
overlays_standing[UNIFORM_LAYER] = standing
else
overlays_standing[UNIFORM_LAYER] = null
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
for( var/obj/item/thing in list(r_store, l_store, wear_id, belt) ) //
if(thing) //
u_equip(thing) //
if (client) //
client.screen -= thing //
//
if (thing) //
thing.loc = loc //
thing.dropped(src) //
thing.layer = initial(thing.layer)
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1)
if(wear_id)
wear_id.screen_loc = ui_id //TODO
if(w_uniform && w_uniform:displays_id)
overlays_standing[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
else
overlays_standing[ID_LAYER] = null
else
overlays_standing[ID_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_gloves(var/update_icons=1)
if(gloves)
var/t_state = gloves.item_state
if(!t_state) t_state = gloves.icon_state
var/image/standing = image("icon" = ((gloves.icon_override) ? gloves.icon_override : 'icons/mob/hands.dmi'), "icon_state" = "[t_state]")
if(gloves.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
standing.overlays += bloodsies
gloves.screen_loc = ui_gloves
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
bloodsies.color = hand_blood_color
overlays_standing[GLOVES_LAYER] = bloodsies
else
overlays_standing[GLOVES_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
if(glasses)
overlays_standing[GLASSES_LAYER] = image("icon" = ((glasses.icon_override) ? glasses.icon_override : 'icons/mob/eyes.dmi'), "icon_state" = "[glasses.icon_state]")
else
overlays_standing[GLASSES_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
if(l_ear || r_ear)
if(l_ear)
overlays_standing[EARS_LAYER] = image("icon" = ((l_ear.icon_override) ? l_ear.icon_override : 'icons/mob/ears.dmi'), "icon_state" = "[l_ear.icon_state]")
if(r_ear)
overlays_standing[EARS_LAYER] = image("icon" = ((r_ear.icon_override) ? r_ear.icon_override : 'icons/mob/ears.dmi'), "icon_state" = "[r_ear.icon_state]")
else
overlays_standing[EARS_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
if(shoes)
var/image/standing = image("icon" = ((shoes.icon_override) ? shoes.icon_override : 'icons/mob/feet.dmi'), "icon_state" = "[shoes.icon_state]")
if(shoes.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood")
bloodsies.color = feet_blood_color
overlays_standing[SHOES_LAYER] = bloodsies
else
overlays_standing[SHOES_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_s_store(var/update_icons=1)
if(s_store)
var/t_state = s_store.item_state
if(!t_state) t_state = s_store.icon_state
overlays_standing[SUIT_STORE_LAYER] = image("icon" = 'icons/mob/belt_mirror.dmi', "icon_state" = "[t_state]")
s_store.screen_loc = ui_sstore1 //TODO
else
overlays_standing[SUIT_STORE_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
if(head)
head.screen_loc = ui_head //TODO
var/image/standing
if(istype(head,/obj/item/clothing/head/kitty))
standing = image("icon" = head:mob)
else
standing = image("icon" = ((head.icon_override) ? head.icon_override : 'icons/mob/head.dmi'), "icon_state" = "[head.icon_state]")
if(head.blood_DNA)
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
standing.overlays += bloodsies
overlays_standing[HEAD_LAYER] = standing
else
overlays_standing[HEAD_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_belt(var/update_icons=1)
if(belt)
belt.screen_loc = ui_belt //TODO
var/t_state = belt.item_state
if(!t_state) t_state = belt.icon_state
overlays_standing[BELT_LAYER] = image("icon" = ((belt.icon_override) ? belt.icon_override : 'icons/mob/belt.dmi'), "icon_state" = "[t_state]")
else
overlays_standing[BELT_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
if( wear_suit && istype(wear_suit, /obj/item/clothing/suit) ) //TODO check this
wear_suit.screen_loc = ui_oclothing //TODO
var/image/standing = image("icon" = ((wear_suit.icon_override) ? wear_suit.icon_override : 'icons/mob/suit.dmi'), "icon_state" = "[wear_suit.icon_state]")
if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) )
drop_from_inventory(handcuffed)
drop_l_hand()
drop_r_hand()
if(wear_suit.blood_DNA)
var/obj/item/clothing/suit/S = wear_suit
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood")
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
overlays_standing[SUIT_LAYER] = standing
update_tail_showing(0)
else
overlays_standing[SUIT_LAYER] = null
update_tail_showing(0)
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_pockets(var/update_icons=1)
if(l_store) l_store.screen_loc = ui_storage1 //TODO
if(r_store) r_store.screen_loc = ui_storage2 //TODO
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) )
wear_mask.screen_loc = ui_mask //TODO
var/image/standing = image("icon" = ((wear_mask.icon_override) ? wear_mask.icon_override : 'icons/mob/mask.dmi'), "icon_state" = "[wear_mask.icon_state]")
if( !istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA )
var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
standing.overlays += bloodsies
overlays_standing[FACEMASK_LAYER] = standing
else
overlays_standing[FACEMASK_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
if(back)
back.screen_loc = ui_back //TODO
overlays_standing[BACK_LAYER] = image("icon" = ((back.icon_override) ? back.icon_override : 'icons/mob/back.dmi'), "icon_state" = "[back.icon_state]")
else
overlays_standing[BACK_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_hud() //TODO: do away with this if possible
if(client)
client.screen |= contents
if(hud_used)
hud_used.hidden_inventory_update() //Updates the screenloc of the items on the 'other' inventory bar
/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
if(handcuffed)
drop_r_hand()
drop_l_hand()
stop_pulling() //TODO: should be handled elsewhere
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
else
overlays_standing[HANDCUFF_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
if(legcuffed)
overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
if(src.m_intent != "walk")
src.m_intent = "walk"
if(src.hud_used && src.hud_used.move_intent)
src.hud_used.move_intent.icon_state = "walking"
else
overlays_standing[LEGCUFF_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
if(r_hand)
r_hand.screen_loc = ui_rhand //TODO
var/t_state = r_hand.item_state
if(!t_state) t_state = r_hand.icon_state
overlays_standing[R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = "[t_state]")
if (handcuffed) drop_r_hand()
else
overlays_standing[R_HAND_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
if(l_hand)
l_hand.screen_loc = ui_lhand //TODO
var/t_state = l_hand.item_state
if(!t_state) t_state = l_hand.icon_state
overlays_standing[L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = "[t_state]")
if (handcuffed) drop_l_hand()
else
overlays_standing[L_HAND_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
overlays_standing[TAIL_LAYER] = null
if(species.tail && species.flags & HAS_TAIL)
if(!wear_suit || !(wear_suit.flags_inv & HIDEJUMPSUIT) && !istype(wear_suit, /obj/item/clothing/suit/space))
overlays_standing[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
if(update_icons)
update_icons()
// Used mostly for creating head items
/mob/living/carbon/human/proc/generate_head_icon()
//gender no longer matters for the mouth, although there should probably be seperate base head icons.
// var/g = "m"
// if (gender == FEMALE) g = "f"
//base icons
var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l")
if(f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
if(facial_hair_style)
var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l")
facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
face_lying.Blend(facial_l, ICON_OVERLAY)
if(h_style)
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
if(hair_style)
var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l")
hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
face_lying.Blend(hair_l, ICON_OVERLAY)
//Eyes
// Note: These used to be in update_face(), and the fact they're here will make it difficult to create a disembodied head
var/icon/eyes_l = new/icon('icons/mob/human_face.dmi', "eyes_l")
eyes_l.Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)
face_lying.Blend(eyes_l, ICON_OVERLAY)
if(lip_style)
face_lying.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_l"), ICON_OVERLAY)
var/image/face_lying_image = new /image(icon = face_lying)
return face_lying_image
//Human Overlays Indexes/////////
#undef MUTANTRACE_LAYER
#undef MUTATIONS_LAYER
#undef DAMAGE_LAYER
#undef UNIFORM_LAYER
#undef ID_LAYER
#undef SHOES_LAYER
#undef GLOVES_LAYER
#undef EARS_LAYER
#undef SUIT_LAYER
#undef GLASSES_LAYER
#undef FACEMASK_LAYER
#undef BELT_LAYER
#undef SUIT_STORE_LAYER
#undef BACK_LAYER
#undef HAIR_LAYER
#undef HEAD_LAYER
#undef HANDCUFF_LAYER
#undef LEGCUFF_LAYER
#undef L_HAND_LAYER
#undef R_HAND_LAYER
#undef TAIL_LAYER
#undef TARGETED_LAYER
#undef TOTAL_LAYERS
@@ -0,0 +1,149 @@
//Lallander was here
/mob/living/carbon/human/whisper(message as text)
if(say_disabled) //This is here to try to identify lag problems
usr << "\red Speech is currently admin-disabled."
return
message = trim(copytext(strip_html_simple(message), 1, MAX_MESSAGE_LEN))
if (!message || silent || miming)
return
log_whisper("[src.name]/[src.key] : [message]")
if (src.client)
if (src.client.prefs.muted & MUTE_IC)
src << "\red You cannot whisper (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (src.stat == 2)
return src.say_dead(message)
if (src.stat)
return
var/alt_name = ""
if (istype(src, /mob/living/carbon/human) && src.name != GetVoice())
var/mob/living/carbon/human/H = src
alt_name = " (as [H.get_id_name("Unknown")])"
// Mute disability
if (src.sdisabilities & MUTE)
return
if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
return
var/italics = 1
var/message_range = 1
if(istype(src.wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja)&&src.wear_mask:voice=="Unknown")
if(copytext(message, 1, 2) != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++)
pick_list += i
for(var/i=1, i <= abs(temp_message.len/3), i++)
var/H = pick(pick_list)
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
message = replacetext(message, "o", "¤")
message = replacetext(message, "p", "þ")
message = replacetext(message, "l", "£")
message = replacetext(message, "s", "§")
message = replacetext(message, "u", "µ")
message = replacetext(message, "b", "ß")
if (src.stuttering)
message = stutter(message)
for (var/obj/O in view(message_range, src))
spawn (0)
if (O)
O.hear_talk(src, message)
var/list/listening = hearers(message_range, src)
listening |= src
//Pass whispers on to anything inside the immediate listeners.
for(var/mob/L in listening)
for(var/mob/C in L.contents)
if(istype(C,/mob/living))
listening += C
var/list/eavesdropping = hearers(2, src)
eavesdropping -= src
eavesdropping -= listening
var/list/watching = hearers(5, src)
watching -= src
watching -= listening
watching -= eavesdropping
var/list/heard_a = list() // understood us
var/list/heard_b = list() // didn't understand us
for (var/mob/M in listening)
if (M.say_understands(src))
heard_a += M
else
heard_b += M
var/rendered = null
for (var/mob/M in watching)
if (M.say_understands(src))
rendered = "<span class='game say'><span class='name'>[src.name]</span> whispers something.</span>"
else
rendered = "<span class='game say'><span class='name'>[src.voice_name]</span> whispers something.</span>"
M.show_message(rendered, 2)
if (length(heard_a))
var/message_a = message
if (italics)
message_a = "<i>[message_a]</i>"
//This appears copied from carbon/living say.dm so the istype check for mob is probably not needed. Appending for src is also not needed as the game will check that automatically.
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] whispers, <span class='message'>\"[message_a]\"</span></span>"
for (var/mob/M in heard_a)
M.show_message(rendered, 2)
if (length(heard_b))
var/message_b
message_b = stars(message)
if (italics)
message_b = "<i>[message_b]</i>"
rendered = "<span class='game say'><span class='name'>[src.voice_name]</span> whispers, <span class='message'>\"[message_b]\"</span></span>"
for (var/mob/M in heard_b)
M.show_message(rendered, 2)
for (var/mob/M in eavesdropping)
if (M.say_understands(src))
var/message_c
message_c = stars(message)
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] whispers, <span class='message'>\"[message_c]\"</span></span>"
M.show_message(rendered, 2)
else
rendered = "<span class='game say'><span class='name'>[src.voice_name]</span> whispers something.</span>"
M.show_message(rendered, 2)
if (italics)
message = "<i>[message]</i>"
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] whispers, <span class='message'>\"[message]\"</span></span>"
for (var/mob/M in dead_mob_list)
if (!(M.client))
continue
if (M.stat > 1 && !(M in heard_a) && (M.client.prefs.toggles & CHAT_GHOSTEARS))
M.show_message(rendered, 2)
@@ -0,0 +1,23 @@
/mob/living/carbon/slime/death(gibbed)
if(stat == DEAD) return
stat = DEAD
icon_state = "[colour] baby slime dead"
if(!gibbed)
if(istype(src, /mob/living/carbon/slime/adult))
ghostize()
var/mob/living/carbon/slime/M1 = new primarytype(loc)
M1.rabid = 1
var/mob/living/carbon/slime/M2 = new primarytype(loc)
M2.rabid = 1
if(src) del(src)
else
for(var/mob/O in viewers(src, null))
O.show_message("<b>The [name]</b> seizes up and falls limp...", 1) //ded -- Urist
update_canmove()
if(blind) blind.layer = 0
ticker.mode.check_win()
return ..(gibbed)
@@ -0,0 +1,65 @@
/mob/living/carbon/slime/emote(var/act,var/m_type=1,var/message = null)
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
//param = copytext(act, t1 + 1, length(act) + 1)
act = copytext(act, 1, t1)
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
switch(act)
if ("me")
if(silent)
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
return custom_emote(m_type, message)
if ("custom")
return custom_emote(m_type, message)
if("moan")
message = "<B>The [src.name]</B> moans."
m_type = 2
if("shiver")
message = "<B>The [src.name]</B> shivers."
m_type = 2
if("sway")
message = "<B>The [src.name]</B> sways around dizzily."
m_type = 1
if("twitch")
message = "<B>The [src.name]</B> twitches."
m_type = 1
if("vibrate")
message = "<B>The [src.name]</B> vibrates!"
m_type = 1
if("light")
message = "<B>The [src.name]</B> lights up for a bit, then stops."
m_type = 1
if("jiggle")
message = "<B>The [src.name]</B> jiggles!"
m_type = 1
if("bounce")
message = "<B>The [src.name]</B> bounces in place."
m_type = 1
else
src << text("Invalid Emote: []", act)
if ((message && src.stat == 0))
if (m_type & 1)
for(var/mob/O in viewers(src, null))
O.show_message(message, m_type)
//Foreach goto(703)
else
for(var/mob/O in hearers(src, null))
O.show_message(message, m_type)
//Foreach goto(746)
return
@@ -0,0 +1,37 @@
/mob/living/carbon/slime/examine()
set src in oview()
if(!usr || !src) return
if( (usr.sdisabilities & BLIND || usr.blinded || usr.stat) && !istype(usr,/mob/dead/observer) )
usr << "<span class='notice'>Something is there but you can't see it.</span>"
return
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
if (src.stat == DEAD)
msg += "<span class='deadsay'>It is limp and unresponsive.</span>\n"
else
if (src.getBruteLoss())
msg += "<span class='warning'>"
if (src.getBruteLoss() < 40)
msg += "It has some punctures in its flesh!"
else
msg += "<B>It has severe punctures and tears in its flesh!</B>"
msg += "</span>\n"
switch(powerlevel)
if(2 to 3)
msg += "It is flickering gently with a little electrical activity.\n"
if(4 to 5)
msg += "It is glowing gently with moderate levels of electrical activity.\n"
if(6 to 9)
msg += "<span class='warning'>It is glowing brightly with high levels of electrical activity.</span>\n"
if(10)
msg += "<span class='warning'><B>It is radiating with massive levels of electrical activity!</B></span>\n"
msg += "*---------*</span>"
usr << msg
return
@@ -0,0 +1,4 @@
/mob/living/carbon/slime/proc/regular_hud_updates()
return
@@ -0,0 +1,554 @@
/mob/living/carbon/slime/Life()
set invisibility = 0
set background = 1
if (src.monkeyizing)
return
..()
if(stat != DEAD)
//Chemicals in the body
handle_chemicals_in_body()
handle_nutrition()
handle_targets()
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(src.loc)
environment = loc.return_air()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
src.blinded = null
// Basically just deletes any screen objects :<
regular_hud_updates()
//Handle temperature/pressure differences between body and environment
if(environment)
handle_environment(environment)
//Status updates, death etc.
handle_regular_status_updates()
/mob/living/carbon/slime
var/AIproc = 0 // determines if the AI loop is activated
var/Atkcool = 0 // attack cooldown
var/Tempstun = 0 // temporary temperature stuns
var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
var/SStun = 0 // stun variable
/mob/living/carbon/slime/proc/AIprocess() // the master AI process
//world << "AI proc started."
if(AIproc || stat == DEAD || client) return
var/hungry = 0
var/starving = 0
if(istype(src, /mob/living/carbon/slime/adult))
switch(nutrition)
if(400 to 1100) hungry = 1
if(0 to 399)
starving = 1
else
switch(nutrition)
if(150 to 900) hungry = 1
if(0 to 149) starving = 1
AIproc = 1
//world << "AIproc [AIproc] && stat != 2 [stat] && (attacked > 0 [attacked] || starving [starving] || hungry [hungry] || rabid [rabid] || Victim [Victim] || Target [Target]"
while(AIproc && stat != 2 && (attacked > 0 || starving || hungry || rabid || Victim))
if(Victim) // can't eat AND have this little process at the same time
//world << "break 1"
break
if(!Target || client)
//world << "break 2"
break
if(Target.health <= -70 || Target.stat == 2)
Target = null
AIproc = 0
//world << "break 3"
break
if(Target)
//world << "[Target] Target Found"
for(var/mob/living/carbon/slime/M in view(1,Target))
if(M.Victim == Target)
Target = null
AIproc = 0
//world << "break 4"
break
if(!AIproc)
//world << "break 5"
break
if(Target in view(1,src))
if(istype(Target, /mob/living/silicon))
if(!Atkcool)
spawn()
Atkcool = 1
sleep(15)
Atkcool = 0
if(Target.Adjacent(src))
Target.attack_slime(src)
//world << "retrun 1"
return
if(!Target.lying && prob(80))
if(Target.client && Target.health >= 20)
if(!Atkcool)
spawn()
Atkcool = 1
sleep(25)
Atkcool = 0
if(Target.Adjacent(src))
Target.attack_slime(src)
if(prob(30))
step_to(src, Target)
else
if(!Atkcool && Target.Adjacent(src))
Feedon(Target)
else
if(!Atkcool && Target.Adjacent(src))
Feedon(Target)
else
if(Target in view(7, src))
if(Target.Adjacent(src))
step_to(src, Target)
else
Target = null
AIproc = 0
//world << "break 6"
break
var/sleeptime = movement_delay()
if(sleeptime <= 0) sleeptime = 1
sleep(sleeptime + 2) // this is about as fast as a player slime can go
AIproc = 0
//world << "AI proc ended."
/mob/living/carbon/slime/proc/handle_environment(datum/gas_mixture/environment)
if(!environment)
adjustToxLoss(rand(10,20))
return
//var/environment_heat_capacity = environment.heat_capacity()
var/loc_temp = T0C
if(istype(get_turf(src), /turf/space))
//environment_heat_capacity = loc:heat_capacity
var/turf/heat_turf = get_turf(src)
loc_temp = heat_turf.temperature
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
loc_temp = loc:air_contents.temperature
else
loc_temp = environment.temperature
/*
if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
var/transfer_coefficient
transfer_coefficient = 1
if(wear_mask && (wear_mask.body_parts_covered & HEAD) && (environment.temperature < wear_mask.protective_temperature))
transfer_coefficient *= wear_mask.heat_transfer_coefficient
// handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient)
*/
if(loc_temp < 310.15) // a cold place
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
else // a hot place
bodytemperature += adjust_body_temperature(bodytemperature, loc_temp, 1)
/*
if(stat==2)
bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
*/
//Account for massive pressure differences
if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc
if(bodytemperature <= (T0C - 40)) // stun temperature
Tempstun = 1
if(bodytemperature <= (T0C - 50)) // hurt temperature
if(bodytemperature <= 50) // sqrting negative numbers is bad
adjustToxLoss(200)
else
adjustToxLoss(round(sqrt(bodytemperature)) * 2)
else
Tempstun = 0
updatehealth()
return //TODO: DEFERRED
/mob/living/carbon/slime/proc/adjust_body_temperature(current, loc_temp, boost)
var/temperature = current
var/difference = abs(current-loc_temp) //get difference
var/increments// = difference/10 //find how many increments apart they are
if(difference > 50)
increments = difference/5
else
increments = difference/10
var/change = increments*boost // Get the amount to change by (x per increment)
var/temp_change
if(current < loc_temp)
temperature = min(loc_temp, temperature+change)
else if(current > loc_temp)
temperature = max(loc_temp, temperature-change)
temp_change = (temperature - current)
return temp_change
/mob/living/carbon/slime/proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
src.updatehealth()
return //TODO: DEFERRED
/mob/living/carbon/slime/proc/handle_regular_status_updates()
if(istype(src, /mob/living/carbon/slime/adult))
health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
else
health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
if(health < config.health_threshold_dead && stat != 2)
death()
return
else if(src.health < config.health_threshold_crit)
// if(src.health <= 20 && prob(1)) spawn(0) emote("gasp")
//if(!src.rejuv) src.oxyloss++
if(!src.reagents.has_reagent("inaprovaline")) src.adjustOxyLoss(10)
if(src.stat != DEAD) src.stat = UNCONSCIOUS
if(prob(30))
adjustOxyLoss(-1)
adjustToxLoss(-1)
adjustFireLoss(-1)
adjustCloneLoss(-1)
adjustBruteLoss(-1)
if (src.stat == DEAD)
src.lying = 1
src.blinded = 1
else
if (src.paralysis || src.stunned || src.weakened || (status_flags && FAKEDEATH)) //Stunned etc.
if (src.stunned > 0)
AdjustStunned(-1)
src.stat = 0
if (src.weakened > 0)
AdjustWeakened(-1)
src.lying = 0
src.stat = 0
if (src.paralysis > 0)
AdjustParalysis(-1)
src.blinded = 0
src.lying = 0
src.stat = 0
else
src.lying = 0
src.stat = 0
if (src.stuttering) src.stuttering = 0
if (src.eye_blind)
src.eye_blind = 0
src.blinded = 1
if (src.ear_deaf > 0) src.ear_deaf = 0
if (src.ear_damage < 25)
src.ear_damage = 0
src.density = !( src.lying )
if (src.sdisabilities & BLIND)
src.blinded = 1
if (src.sdisabilities & DEAF)
src.ear_deaf = 1
if (src.eye_blurry > 0)
src.eye_blurry = 0
if (src.druggy > 0)
src.druggy = 0
return 1
/mob/living/carbon/slime/proc/handle_nutrition()
if(prob(20))
if(istype(src, /mob/living/carbon/slime/adult)) nutrition-=rand(4,6)
else nutrition-=rand(2,3)
if(nutrition <= 0)
nutrition = 0
if(prob(75))
adjustToxLoss(rand(0,5))
else
if(istype(src, /mob/living/carbon/slime/adult))
if(nutrition >= 1000)
if(prob(40)) amount_grown++
else
if(nutrition >= 800)
if(prob(40)) amount_grown++
if(amount_grown >= 10 && !Victim && !Target)
if(istype(src, /mob/living/carbon/slime/adult))
if(!client)
for(var/i=1,i<=4,i++)
if(prob(70))
var/mob/living/carbon/slime/M = new primarytype(loc)
M.powerlevel = round(powerlevel/4)
M.Friends = Friends
M.tame = tame
M.rabid = rabid
M.Discipline = Discipline
if(i != 1) step_away(M,src)
else
var/mutations = pick("one","two","three","four")
switch(mutations)
if("one")
var/mob/living/carbon/slime/M = new mutationone(loc)
M.powerlevel = round(powerlevel/4)
M.Friends = Friends
M.tame = tame
M.rabid = rabid
M.Discipline = Discipline
if(i != 1) step_away(M,src)
if("two")
var/mob/living/carbon/slime/M = new mutationtwo(loc)
M.powerlevel = round(powerlevel/4)
M.Friends = Friends
M.tame = tame
M.rabid = rabid
M.Discipline = Discipline
if(i != 1) step_away(M,src)
if("three")
var/mob/living/carbon/slime/M = new mutationthree(loc)
M.powerlevel = round(powerlevel/4)
M.Friends = Friends
M.tame = tame
M.rabid = rabid
M.Discipline = Discipline
if(i != 1) step_away(M,src)
if("four")
var/mob/living/carbon/slime/M = new mutationfour(loc)
M.powerlevel = round(powerlevel/4)
M.Friends = Friends
M.tame = tame
M.rabid = rabid
M.Discipline = Discipline
if(i != 1) step_away(M,src)
del(src)
else
if(!client)
var/mob/living/carbon/slime/adult/A = new adulttype(src.loc)
A.nutrition = nutrition
// A.nutrition += 100
A.powerlevel = max(0, powerlevel-1)
A.Friends = Friends
A.tame = tame
A.rabid = rabid
del(src)
/mob/living/carbon/slime/proc/handle_targets()
if(Tempstun)
if(!Victim) // not while they're eating!
canmove = 0
else
canmove = 1
if(attacked > 50) attacked = 50
if(attacked > 0)
if(prob(85))
attacked--
if(Discipline > 0)
if(Discipline >= 5 && rabid)
if(prob(60)) rabid = 0
if(prob(10))
Discipline--
if(!client)
if(!canmove) return
// DO AI STUFF HERE
if(Target)
if(attacked <= 0)
Target = null
if(Victim) return // if it's eating someone already, continue eating!
if(prob(1))
emote(pick("bounce","sway","light","vibrate","jiggle"))
if(AIproc && SStun) return
var/hungry = 0 // determines if the slime is hungry
var/starving = 0 // determines if the slime is starving-hungry
if(istype(src, /mob/living/carbon/slime/adult)) // 1200 max nutrition
switch(nutrition)
if(601 to 900)
if(prob(25)) hungry = 1//Ensures they continue eating, but aren't as aggressive at the same time
if(301 to 600) hungry = 1
if(0 to 300)
starving = 1
else
switch(nutrition) // 1000 max nutrition
if(501 to 700)
if(prob(25)) hungry = 1
if(201 to 500) hungry = 1
if(0 to 200) starving = 1
if(starving && !client) // if a slime is starving, it starts losing its friends
if(Friends.len > 0 && prob(1))
var/mob/nofriend = pick(Friends)
Friends -= nofriend
if(!Target)
var/list/targets = list()
if(hungry || starving) //Only add to the list if we need to
for(var/mob/living/L in view(7,src))
//Ignore other slimes, dead mobs and simple_animals
if(isslime(L) || L.stat != CONSCIOUS || isanimal(L))
continue
if(issilicon(L))
if(!istype(src, /mob/living/carbon/slime/adult)) //Non-starving diciplined adult slimes wont eat things
if(!starving && Discipline > 0)
continue
if(tame) //Tame slimes ignore electronic life
continue
targets += L //Possible target found!
else if(iscarbon(L))
if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L
if(H.dna)
if(H.dna.mutantrace == "slime")
continue
if(!istype(src, /mob/living/carbon/slime/adult)) //Non-starving diciplined adult slimes wont eat things
if(!starving && Discipline > 0)
continue
if(L in Friends) //No eating friends!
continue
if(tame && ishuman(L)) //Tame slimes dont eat people.
continue
if(!L.canmove) //Only one slime can latch on at a time.
var/notarget = 0
for(var/mob/living/carbon/slime/M in view(1,L))
if(M.Victim == L)
notarget = 1
if(notarget)
continue
targets += L //Possible target found!
if((hungry || starving) && targets.len > 0)
if(!istype(src, /mob/living/carbon/slime/adult))
if(!starving)
for(var/mob/living/carbon/C in targets)
if(!Discipline && prob(5))
if(ishuman(C))
Target = C
break
if(isalienadult(C))
Target = C
break
if(islarva(C))
Target = C
break
if(ismonkey(C))
Target = C
break
else
Target = targets[1]
else
Target = targets[1] // closest target
if(targets.len > 0)
if(attacked > 0 || rabid)
Target = targets[1] //closest mob probably attacked it, so override Target and attack the nearest!
if(!Target)
if(hungry || starving)
if(canmove && isturf(loc) && prob(50))
step(src, pick(cardinal))
else
if(canmove && isturf(loc) && prob(33))
step(src, pick(cardinal))
else
if(!AIproc)
spawn() AIprocess()
@@ -0,0 +1,4 @@
/mob/living/carbon/slime/Login()
..()
update_hud()
return
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,263 @@
/mob/living/carbon/slime/verb/Feed()
set category = "Slime"
set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process."
if(Victim)
Feedstop()
return
if(stat)
src << "<i>I must be conscious to do this...</i>"
return
var/list/choices = list()
for(var/mob/living/C in view(1,src))
if(C!=src && !istype(C,/mob/living/carbon/slime))
choices += C
var/mob/living/carbon/M = input(src,"Who do you wish to feed on?") in null|choices
if(!M) return
if(M in view(1, src))
if(!istype(src, /mob/living/carbon/brain))
if(!istype(M, /mob/living/carbon/slime))
if(stat != 2)
if(health > -70)
for(var/mob/living/carbon/slime/met in view())
if(met.Victim == M && met != src)
src << "<i>The [met.name] is already feeding on this subject...</i>"
return
src << "\blue <i>I have latched onto the subject and begun feeding...</i>"
M << "\red <b>The [src.name] has latched onto your head!</b>"
Feedon(M)
else
src << "<i>This subject does not have a strong enough life energy...</i>"
else
src << "<i>This subject does not have an edible life energy...</i>"
else
src << "<i>I must not feed on my brothers...</i>"
else
src << "<i>This subject does not have an edible life energy...</i>"
/mob/living/carbon/slime/proc/Feedon(var/mob/living/carbon/M)
Victim = M
src.loc = M.loc
canmove = 0
anchored = 1
var/lastnut = nutrition
//if(M.client) M << "\red You legs become paralyzed!"
if(istype(src, /mob/living/carbon/slime/adult))
icon_state = "[colour] adult slime eat"
else
icon_state = "[colour] baby slime eat"
while(Victim && M.health > -70 && stat != 2)
// M.canmove = 0
canmove = 0
if(M in view(1, src))
loc = M.loc
if(prob(15) && M.client && istype(M, /mob/living/carbon))
M << "\red [pick("You can feel your body becoming weak!", \
"You feel like you're about to die!", \
"You feel every part of your body screaming in agony!", \
"A low, rolling pain passes through your body!", \
"Your body feels as if it's falling apart!", \
"You feel extremely weak!", \
"A sharp, deep pain bathes every inch of your body!")]"
if(istype(M, /mob/living/carbon))
Victim.adjustCloneLoss(rand(1,10))
Victim.adjustToxLoss(rand(1,2))
if(Victim.health <= 0)
Victim.adjustToxLoss(rand(2,4))
// Heal yourself
adjustToxLoss(-10)
adjustOxyLoss(-10)
adjustBruteLoss(-10)
adjustFireLoss(-10)
adjustCloneLoss(-10)
if(Victim)
for(var/mob/living/carbon/slime/slime in view(1,M))
if(slime.Victim == M && slime != src)
slime.Feedstop()
nutrition += rand(10,25)
if(nutrition >= lastnut + 50)
if(prob(80))
lastnut = nutrition
powerlevel++
if(powerlevel > 10)
powerlevel = 10
if(istype(src, /mob/living/carbon/slime/adult))
if(nutrition > 1200)
nutrition = 1200
else
if(nutrition > 1000)
nutrition = 1000
Victim.updatehealth()
updatehealth()
else
if(prob(25))
src << "\red <i>[pick("This subject is incompatable", \
"This subject does not have a life energy", "This subject is empty", \
"I am not satisified", "I can not feed from this subject", \
"I do not feel nourished", "This subject is not food")]...</i>"
sleep(rand(15,45))
else
break
if(stat == 2)
if(!istype(src, /mob/living/carbon/slime/adult))
icon_state = "[colour] baby slime dead"
else
if(istype(src, /mob/living/carbon/slime/adult))
icon_state = "[colour] adult slime"
else
icon_state = "[colour] baby slime"
canmove = 1
anchored = 0
if(M)
if(M.health <= -70)
M.canmove = 0
if(!client)
if(Victim && !rabid && !attacked)
if(Victim.LAssailant && Victim.LAssailant != Victim)
if(prob(50))
if(!(Victim.LAssailant in Friends))
Friends.Add(Victim.LAssailant) // no idea why i was using the |= operator
if(M.client && istype(src, /mob/living/carbon/human))
if(prob(85))
rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU
if(client) src << "<i>This subject does not have a strong enough life energy anymore...</i>"
else
M.canmove = 1
if(client) src << "<i>I have stopped feeding...</i>"
else
if(client) src << "<i>I have stopped feeding...</i>"
Victim = null
/mob/living/carbon/slime/proc/Feedstop()
if(Victim)
if(Victim.client) Victim << "[src] has let go of your head!"
Victim = null
/mob/living/carbon/slime/proc/UpdateFeed(var/mob/M)
if(Victim)
if(Victim == M)
loc = M.loc // simple "attach to head" effect!
/mob/living/carbon/slime/verb/Evolve()
set category = "Slime"
set desc = "This will let you evolve from baby to adult slime."
if(stat)
src << "<i>I must be conscious to do this...</i>"
return
if(!istype(src, /mob/living/carbon/slime/adult))
if(amount_grown >= 10)
var/mob/living/carbon/slime/adult/new_slime = new adulttype(loc)
new_slime.nutrition = nutrition
new_slime.powerlevel = max(0, powerlevel-1)
new_slime.a_intent = "hurt"
new_slime.key = key
new_slime.universal_speak = universal_speak
new_slime << "<B>You are now an adult slime.</B>"
del(src)
else
src << "<i>I am not ready to evolve yet...</i>"
else
src << "<i>I have already evolved...</i>"
/mob/living/carbon/slime/verb/Reproduce()
set category = "Slime"
set desc = "This will make you split into four Slimes. NOTE: this will KILL you, but you will be transferred into one of the babies."
if(stat)
src << "<i>I must be conscious to do this...</i>"
return
if(istype(src, /mob/living/carbon/slime/adult))
if(amount_grown >= 10)
//if(input("Are you absolutely sure you want to reproduce? Your current body will cease to be, but your consciousness will be transferred into a produced slime.") in list("Yes","No")=="Yes")
if(stat)
src << "<i>I must be conscious to do this...</i>"
return
var/list/babies = list()
var/new_nutrition = round(nutrition * 0.9)
var/new_powerlevel = round(powerlevel / 4)
for(var/i=1,i<=4,i++)
if(prob(80))
var/mob/living/carbon/slime/M = new primarytype(loc)
M.nutrition = new_nutrition
M.powerlevel = new_powerlevel
if(i != 1) step_away(M,src)
babies += M
else
var/mutations = pick("one","two","three","four")
switch(mutations)
if("one")
var/mob/living/carbon/slime/M = new mutationone(loc)
M.nutrition = new_nutrition
M.powerlevel = new_powerlevel
if(i != 1) step_away(M,src)
babies += M
if("two")
var/mob/living/carbon/slime/M = new mutationtwo(loc)
M.nutrition = new_nutrition
M.powerlevel = new_powerlevel
if(i != 1) step_away(M,src)
babies += M
if("three")
var/mob/living/carbon/slime/M = new mutationthree(loc)
M.nutrition = new_nutrition
M.powerlevel = new_powerlevel
if(i != 1) step_away(M,src)
babies += M
if("four")
var/mob/living/carbon/slime/M = new mutationfour(loc)
M.nutrition = new_nutrition
M.powerlevel = new_powerlevel
if(i != 1) step_away(M,src)
babies += M
var/mob/living/carbon/slime/new_slime = pick(babies)
new_slime.a_intent = "hurt"
new_slime.universal_speak = universal_speak
new_slime.key = key
new_slime << "<B>You are now a slime!</B>"
del(src)
else
src << "<i>I am not ready to reproduce yet...</i>"
else
src << "<i>I am not old enough to reproduce yet...</i>"
/mob/living/carbon/slime/verb/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Slime"
if(Victim) return
handle_ventcrawl()
@@ -0,0 +1,372 @@
////////////////Tier 2
/mob/living/carbon/slime/purple
colour = "purple"
icon_state = "purple baby slime"
primarytype = /mob/living/carbon/slime/purple
mutationone = /mob/living/carbon/slime/darkpurple
mutationtwo = /mob/living/carbon/slime/darkblue
mutationthree = /mob/living/carbon/slime/green
mutationfour = /mob/living/carbon/slime/green
adulttype = /mob/living/carbon/slime/adult/purple
coretype = /obj/item/slime_extract/purple
/mob/living/carbon/slime/adult/purple
icon_state = "purple adult slime"
colour = "purple"
primarytype = /mob/living/carbon/slime/purple
mutationone = /mob/living/carbon/slime/darkpurple
mutationtwo = /mob/living/carbon/slime/darkblue
mutationthree = /mob/living/carbon/slime/green
mutationfour = /mob/living/carbon/slime/green
adulttype = /mob/living/carbon/slime/adult/purple
coretype = /obj/item/slime_extract/purple
/mob/living/carbon/slime/metal
colour = "metal"
icon_state = "metal baby slime"
primarytype = /mob/living/carbon/slime/metal
mutationone = /mob/living/carbon/slime/silver
mutationtwo = /mob/living/carbon/slime/yellow
mutationthree = /mob/living/carbon/slime/gold
mutationfour = /mob/living/carbon/slime/gold
adulttype = /mob/living/carbon/slime/adult/metal
coretype = /obj/item/slime_extract/metal
/mob/living/carbon/slime/adult/metal
icon_state = "metal adult slime"
colour = "metal"
primarytype = /mob/living/carbon/slime/metal
mutationone = /mob/living/carbon/slime/silver
mutationtwo = /mob/living/carbon/slime/yellow
mutationthree = /mob/living/carbon/slime/gold
mutationfour = /mob/living/carbon/slime/gold
adulttype = /mob/living/carbon/slime/adult/metal
coretype = /obj/item/slime_extract/metal
/mob/living/carbon/slime/orange
colour = "orange"
icon_state = "orange baby slime"
primarytype = /mob/living/carbon/slime/orange
mutationone = /mob/living/carbon/slime/red
mutationtwo = /mob/living/carbon/slime/red
mutationthree = /mob/living/carbon/slime/darkpurple
mutationfour = /mob/living/carbon/slime/yellow
adulttype = /mob/living/carbon/slime/adult/orange
coretype = /obj/item/slime_extract/orange
/mob/living/carbon/slime/adult/orange
colour = "orange"
icon_state = "orange adult slime"
primarytype = /mob/living/carbon/slime/orange
mutationone = /mob/living/carbon/slime/red
mutationtwo = /mob/living/carbon/slime/red
mutationthree = /mob/living/carbon/slime/darkpurple
mutationfour = /mob/living/carbon/slime/yellow
adulttype = /mob/living/carbon/slime/adult/orange
coretype = /obj/item/slime_extract/orange
/mob/living/carbon/slime/blue
colour = "blue"
icon_state = "blue baby slime"
primarytype = /mob/living/carbon/slime/blue
mutationone = /mob/living/carbon/slime/darkblue
mutationtwo = /mob/living/carbon/slime/pink
mutationthree = /mob/living/carbon/slime/pink
mutationfour = /mob/living/carbon/slime/silver
adulttype = /mob/living/carbon/slime/adult/blue
coretype = /obj/item/slime_extract/blue
/mob/living/carbon/slime/adult/blue
icon_state = "blue adult slime"
colour = "blue"
primarytype = /mob/living/carbon/slime/blue
mutationone = /mob/living/carbon/slime/darkblue
mutationtwo = /mob/living/carbon/slime/pink
mutationthree = /mob/living/carbon/slime/silver
mutationfour = /mob/living/carbon/slime/pink
adulttype = /mob/living/carbon/slime/adult/blue
coretype = /obj/item/slime_extract/blue
//Tier 3
/mob/living/carbon/slime/darkblue
colour = "dark blue"
icon_state = "dark blue baby slime"
primarytype = /mob/living/carbon/slime/darkblue
mutationone = /mob/living/carbon/slime/purple
mutationtwo = /mob/living/carbon/slime/purple
mutationthree = /mob/living/carbon/slime/blue
mutationfour = /mob/living/carbon/slime/blue
adulttype = /mob/living/carbon/slime/adult/darkblue
coretype = /obj/item/slime_extract/darkblue
/mob/living/carbon/slime/adult/darkblue
icon_state = "dark blue adult slime"
colour = "dark blue"
primarytype = /mob/living/carbon/slime/darkblue
mutationone = /mob/living/carbon/slime/purple
mutationtwo = /mob/living/carbon/slime/purple
mutationthree = /mob/living/carbon/slime/blue
mutationfour = /mob/living/carbon/slime/blue
adulttype = /mob/living/carbon/slime/adult/darkblue
coretype = /obj/item/slime_extract/darkblue
/mob/living/carbon/slime/darkpurple
colour = "dark purple"
icon_state = "dark purple baby slime"
primarytype = /mob/living/carbon/slime/darkpurple
mutationone = /mob/living/carbon/slime/purple
mutationtwo = /mob/living/carbon/slime/purple
mutationthree = /mob/living/carbon/slime/orange
mutationfour = /mob/living/carbon/slime/orange
adulttype = /mob/living/carbon/slime/adult/darkpurple
coretype = /obj/item/slime_extract/darkpurple
/mob/living/carbon/slime/adult/darkpurple
icon_state = "dark purple adult slime"
colour = "dark purple"
primarytype = /mob/living/carbon/slime/darkpurple
mutationone = /mob/living/carbon/slime/purple
mutationtwo = /mob/living/carbon/slime/purple
mutationthree = /mob/living/carbon/slime/orange
mutationfour = /mob/living/carbon/slime/orange
adulttype = /mob/living/carbon/slime/adult/darkpurple
coretype = /obj/item/slime_extract/darkpurple
/mob/living/carbon/slime/yellow
icon_state = "yellow baby slime"
colour = "yellow"
primarytype = /mob/living/carbon/slime/yellow
mutationone = /mob/living/carbon/slime/metal
mutationtwo = /mob/living/carbon/slime/metal
mutationthree = /mob/living/carbon/slime/orange
mutationfour = /mob/living/carbon/slime/orange
adulttype = /mob/living/carbon/slime/adult/yellow
coretype = /obj/item/slime_extract/yellow
/mob/living/carbon/slime/adult/yellow
icon_state = "yellow adult slime"
colour = "yellow"
primarytype = /mob/living/carbon/slime/yellow
mutationone = /mob/living/carbon/slime/metal
mutationtwo = /mob/living/carbon/slime/metal
mutationthree = /mob/living/carbon/slime/orange
mutationfour = /mob/living/carbon/slime/orange
adulttype = /mob/living/carbon/slime/adult/yellow
coretype = /obj/item/slime_extract/yellow
/mob/living/carbon/slime/silver
colour = "silver"
icon_state = "silver baby slime"
primarytype = /mob/living/carbon/slime/silver
mutationone = /mob/living/carbon/slime/metal
mutationtwo = /mob/living/carbon/slime/metal
mutationthree = /mob/living/carbon/slime/blue
mutationfour = /mob/living/carbon/slime/blue
adulttype = /mob/living/carbon/slime/adult/silver
coretype = /obj/item/slime_extract/silver
/mob/living/carbon/slime/adult/silver
icon_state = "silver adult slime"
colour = "silver"
primarytype = /mob/living/carbon/slime/silver
mutationone = /mob/living/carbon/slime/metal
mutationtwo = /mob/living/carbon/slime/metal
mutationthree = /mob/living/carbon/slime/blue
mutationfour = /mob/living/carbon/slime/blue
adulttype = /mob/living/carbon/slime/adult/silver
coretype = /obj/item/slime_extract/silver
/////////////Tier 4
/mob/living/carbon/slime/pink
colour = "pink"
icon_state = "pink baby slime"
primarytype = /mob/living/carbon/slime/pink
mutationone = /mob/living/carbon/slime/pink
mutationtwo = /mob/living/carbon/slime/pink
mutationthree = /mob/living/carbon/slime/lightpink
mutationfour = /mob/living/carbon/slime/lightpink
adulttype = /mob/living/carbon/slime/adult/pink
coretype = /obj/item/slime_extract/pink
/mob/living/carbon/slime/adult/pink
icon_state = "pink adult slime"
colour = "pink"
primarytype = /mob/living/carbon/slime/pink
mutationone = /mob/living/carbon/slime/pink
mutationtwo = /mob/living/carbon/slime/pink
mutationthree = /mob/living/carbon/slime/lightpink
mutationfour = /mob/living/carbon/slime/lightpink
adulttype = /mob/living/carbon/slime/adult/pink
coretype = /obj/item/slime_extract/pink
/mob/living/carbon/slime/red
colour = "red"
icon_state = "red baby slime"
primarytype = /mob/living/carbon/slime/red
mutationone = /mob/living/carbon/slime/red
mutationtwo = /mob/living/carbon/slime/red
mutationthree = /mob/living/carbon/slime/oil
mutationfour = /mob/living/carbon/slime/oil
adulttype = /mob/living/carbon/slime/adult/red
coretype = /obj/item/slime_extract/red
/mob/living/carbon/slime/adult/red
icon_state = "red adult slime"
colour = "red"
primarytype = /mob/living/carbon/slime/red
mutationone = /mob/living/carbon/slime/red
mutationtwo = /mob/living/carbon/slime/red
mutationthree = /mob/living/carbon/slime/oil
mutationfour = /mob/living/carbon/slime/oil
adulttype = /mob/living/carbon/slime/adult/red
coretype = /obj/item/slime_extract/red
/mob/living/carbon/slime/gold
colour = "gold"
icon_state = "gold baby slime"
primarytype = /mob/living/carbon/slime/gold
mutationone = /mob/living/carbon/slime/gold
mutationtwo = /mob/living/carbon/slime/gold
mutationthree = /mob/living/carbon/slime/adamantine
mutationfour = /mob/living/carbon/slime/adamantine
adulttype = /mob/living/carbon/slime/adult/gold
coretype = /obj/item/slime_extract/gold
/mob/living/carbon/slime/adult/gold
icon_state = "gold adult slime"
colour = "gold"
primarytype = /mob/living/carbon/slime/gold
mutationone = /mob/living/carbon/slime/gold
mutationtwo = /mob/living/carbon/slime/gold
mutationthree = /mob/living/carbon/slime/adamantine
mutationfour = /mob/living/carbon/slime/adamantine
adulttype = /mob/living/carbon/slime/adult/gold
coretype = /obj/item/slime_extract/gold
/mob/living/carbon/slime/green
colour = "green"
icon_state = "green baby slime"
primarytype = /mob/living/carbon/slime/green
mutationone = /mob/living/carbon/slime/green
mutationtwo = /mob/living/carbon/slime/green
mutationthree = /mob/living/carbon/slime/black
mutationfour = /mob/living/carbon/slime/black
adulttype = /mob/living/carbon/slime/adult/green
coretype = /obj/item/slime_extract/green
/mob/living/carbon/slime/adult/green
icon_state = "green adult slime"
colour = "green"
primarytype = /mob/living/carbon/slime/green
mutationone = /mob/living/carbon/slime/green
mutationtwo = /mob/living/carbon/slime/green
mutationthree = /mob/living/carbon/slime/black
mutationfour = /mob/living/carbon/slime/black
adulttype = /mob/living/carbon/slime/adult/green
coretype = /obj/item/slime_extract/green
// Tier 5
/mob/living/carbon/slime/lightpink
colour = "light pink"
icon_state = "light pink baby slime"
primarytype = /mob/living/carbon/slime/lightpink
mutationone = /mob/living/carbon/slime/lightpink
mutationtwo = /mob/living/carbon/slime/lightpink
mutationthree = /mob/living/carbon/slime/lightpink
mutationfour = /mob/living/carbon/slime/lightpink
adulttype = /mob/living/carbon/slime/adult/lightpink
coretype = /obj/item/slime_extract/lightpink
/mob/living/carbon/slime/adult/lightpink
icon_state = "light pink adult slime"
colour = "light pink"
primarytype = /mob/living/carbon/slime/lightpink
mutationone = /mob/living/carbon/slime/lightpink
mutationtwo = /mob/living/carbon/slime/lightpink
mutationthree = /mob/living/carbon/slime/lightpink
mutationfour = /mob/living/carbon/slime/lightpink
adulttype = /mob/living/carbon/slime/adult/lightpink
coretype = /obj/item/slime_extract/lightpink
/mob/living/carbon/slime/oil
icon_state = "oil baby slime"
colour = "oil"
primarytype = /mob/living/carbon/slime/oil
mutationone = /mob/living/carbon/slime/oil
mutationtwo = /mob/living/carbon/slime/oil
mutationthree = /mob/living/carbon/slime/oil
mutationfour = /mob/living/carbon/slime/oil
adulttype = /mob/living/carbon/slime/adult/oil
coretype = /obj/item/slime_extract/oil
/mob/living/carbon/slime/adult/oil
icon_state = "oil adult slime"
colour = "oil"
primarytype = /mob/living/carbon/slime/oil
mutationone = /mob/living/carbon/slime/oil
mutationtwo = /mob/living/carbon/slime/oil
mutationthree = /mob/living/carbon/slime/oil
mutationfour = /mob/living/carbon/slime/oil
adulttype = /mob/living/carbon/slime/adult/oil
coretype = /obj/item/slime_extract/oil
/mob/living/carbon/slime/black
icon_state = "black baby slime"
colour = "black"
primarytype = /mob/living/carbon/slime/black
mutationone = /mob/living/carbon/slime/black
mutationtwo = /mob/living/carbon/slime/black
mutationthree = /mob/living/carbon/slime/black
mutationfour = /mob/living/carbon/slime/black
adulttype = /mob/living/carbon/slime/adult/black
coretype = /obj/item/slime_extract/black
/mob/living/carbon/slime/adult/black
icon_state = "black adult slime"
colour = "black"
primarytype = /mob/living/carbon/slime/black
mutationone = /mob/living/carbon/slime/black
mutationtwo = /mob/living/carbon/slime/black
mutationthree = /mob/living/carbon/slime/black
mutationfour = /mob/living/carbon/slime/black
adulttype = /mob/living/carbon/slime/adult/black
coretype = /obj/item/slime_extract/black
/mob/living/carbon/slime/adamantine
icon_state = "adamantine baby slime"
colour = "adamantine"
primarytype = /mob/living/carbon/slime/adamantine
mutationone = /mob/living/carbon/slime/adamantine
mutationtwo = /mob/living/carbon/slime/adamantine
mutationthree = /mob/living/carbon/slime/adamantine
mutationfour = /mob/living/carbon/slime/adamantine
adulttype = /mob/living/carbon/slime/adult/adamantine
coretype = /obj/item/slime_extract/adamantine
/mob/living/carbon/slime/adult/adamantine
icon_state = "adamantine adult slime"
colour = "adamantine"
primarytype = /mob/living/carbon/slime/adamantine
mutationone = /mob/living/carbon/slime/adamantine
mutationtwo = /mob/living/carbon/slime/adamantine
mutationthree = /mob/living/carbon/slime/adamantine
mutationfour = /mob/living/carbon/slime/adamantine
adulttype = /mob/living/carbon/slime/adult/adamantine
coretype = /obj/item/slime_extract/adamantine
@@ -0,0 +1 @@
//no special icon processing
@@ -0,0 +1,56 @@
/mob/living/carbon/monkey/gib()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("gibbed-m", animation)
gibs(loc, viruses, dna)
spawn(15)
if(animation) del(animation)
if(src) del(src)
/mob/living/carbon/monkey/dust()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("dust-m", animation)
new /obj/effect/decal/cleanable/ash(loc)
spawn(15)
if(animation) del(animation)
if(src) del(src)
/mob/living/carbon/monkey/death(gibbed)
if(stat == DEAD) return
if(healths) healths.icon_state = "health5"
stat = DEAD
if(!gibbed)
for(var/mob/O in viewers(src, null))
O.show_message("<b>The [name]</b> lets out a faint chimper as it collapses and stops moving...", 1) //ded -- Urist
update_canmove()
if(blind) blind.layer = 0
ticker.mode.check_win()
return ..(gibbed)
@@ -0,0 +1,193 @@
/*
Tiny babby plant critter plus procs.
*/
//Helper object for picking dionaea (and other creatures) up.
/obj/item/weapon/holder
name = "holder"
desc = "You shouldn't ever see this."
/obj/item/weapon/holder/diona
name = "diona nymph"
desc = "It's a tiny plant critter."
icon = 'icons/obj/objects.dmi'
icon_state = "nymph"
slot_flags = SLOT_HEAD
origin_tech = "magnets=3;biotech=5"
/obj/item/weapon/holder/New()
..()
processing_objects.Add(src)
/obj/item/weapon/holder/Del()
//Hopefully this will stop the icon from remaining on human mobs.
if(istype(loc,/mob/living))
var/mob/living/A = src.loc
src.loc = null
A.update_icons()
processing_objects.Remove(src)
..()
/obj/item/weapon/holder/process()
if(!loc) return
if(istype(loc,/turf) || !(contents.len))
for(var/mob/M in contents)
M.loc = get_turf(src)
del(src)
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob)
for(var/mob/M in src.contents)
M.attackby(W,user)
//Mob defines.
/mob/living/carbon/monkey/diona
name = "diona nymph"
voice_name = "diona nymph"
speak_emote = list("chirrups")
icon_state = "nymph1"
var/list/donors = list()
var/ready_evolve = 0
/mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob)
//Let people pick the little buggers up.
if(M.a_intent == "help")
var/obj/item/weapon/holder/diona/D = new(loc)
src.loc = D
D.name = loc.name
D.attack_hand(M)
M << "You scoop up [src]."
src << "[M] scoops you up."
return
..()
/mob/living/carbon/monkey/diona/New()
..()
gender = NEUTER
dna.mutantrace = "plant"
greaterform = "Diona"
add_language("Rootspeak")
//Verbs after this point.
/mob/living/carbon/monkey/diona/verb/fertilize_plant()
set category = "Diona"
set name = "Fertilize plant"
set desc = "Turn your food into nutrients for plants."
var/list/trays = list()
for(var/obj/machinery/hydroponics/tray in range(1))
if(tray.nutrilevel < 10)
trays += tray
var/obj/machinery/hydroponics/target = input("Select a tray:") as null|anything in trays
if(!src || !target || target.nutrilevel == 10) return //Sanity check.
src.nutrition -= ((10-target.nutrilevel)*5)
target.nutrilevel = 10
src.visible_message("\red [src] secretes a trickle of green liquid from its tail, refilling [target]'s nutrient tray.","\red You secrete a trickle of green liquid from your tail, refilling [target]'s nutrient tray.")
/mob/living/carbon/monkey/diona/verb/eat_weeds()
set category = "Diona"
set name = "Eat Weeds"
set desc = "Clean the weeds out of soil or a hydroponics tray."
var/list/trays = list()
for(var/obj/machinery/hydroponics/tray in range(1))
if(tray.weedlevel > 0)
trays += tray
var/obj/machinery/hydroponics/target = input("Select a tray:") as null|anything in trays
if(!src || !target || target.weedlevel == 0) return //Sanity check.
src.reagents.add_reagent("nutriment", target.weedlevel)
target.weedlevel = 0
src.visible_message("\red [src] begins rooting through [target], ripping out weeds and eating them noisily.","\red You begin rooting through [target], ripping out weeds and eating them noisily.")
/mob/living/carbon/monkey/diona/verb/evolve()
set category = "Diona"
set name = "Evolve"
set desc = "Grow to a more complex form."
if(!is_alien_whitelisted(src, "Diona") && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play as a full diona.")
return 0
if(donors.len < 5)
src << "You are not yet ready for your growth..."
return
if(nutrition < 400)
src << "You have not yet consumed enough to grow..."
return
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark and twigs!","\red You begin to shift and quiver, then erupt in a shower of shed bark and twigs, attaining your adult form!")
var/mob/living/carbon/human/adult = new(get_turf(src.loc))
adult.set_species("Diona")
if(istype(loc,/obj/item/weapon/holder/diona))
var/obj/item/weapon/holder/diona/L = loc
src.loc = L.loc
del(L)
for(var/datum/language/L in languages)
adult.add_language(L.name)
adult.regenerate_icons()
adult.name = src.name
adult.real_name = src.real_name
adult.ckey = src.ckey
for (var/obj/item/W in src.contents)
src.drop_from_inventory(W)
del(src)
/mob/living/carbon/monkey/diona/verb/steal_blood()
set category = "Diona"
set name = "Steal Blood"
set desc = "Take a blood sample from a suitable donor."
var/list/choices = list()
for(var/mob/living/carbon/C in view(1,src))
if(C.real_name != real_name)
choices += C
var/mob/living/M = input(src,"Who do you wish to take a sample from?") in null|choices
if(!M || !src) return
if(donors.Find(M.real_name))
src << "\red That donor offers you nothing new."
return
src.visible_message("\red [src] flicks out a feeler and neatly steals a sample of [M]'s blood.","\red You flick out a feeler and neatly steal a sample of [M]'s blood.")
donors += M.real_name
spawn(25)
update_progression()
/mob/living/carbon/monkey/diona/proc/update_progression()
if(!donors.len)
return
if(donors.len == 5)
ready_evolve = 1
src << "\green You feel ready to move on to your next stage of growth."
else if(donors.len == 2)
universal_understand = 1
src << "\green You feel your awareness expand, and realize you know how to understand the creatures around you."
else if(donors.len == 4)
universal_speak = 1
src << "\green You feel your awareness expand, and realize you know how to speak with the creatures around you."
else
src << "\green The blood seeps into your small form, and you draw out the echoes of memories and personality from it, working them into your budding mind."
@@ -0,0 +1,131 @@
/mob/living/carbon/monkey/emote(var/act,var/m_type=1,var/message = null)
var/param = null
if (findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
param = copytext(act, t1 + 1, length(act) + 1)
act = copytext(act, 1, t1)
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
act = copytext(act,1,length(act))
var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
switch(act)
if ("me")
if(silent)
return
if (src.client)
if (client.prefs.muted & MUTE_IC)
src << "\red You cannot send IC messages (muted)."
return
if (src.client.handle_spam_prevention(message,MUTE_IC))
return
if (stat)
return
if(!(message))
return
return custom_emote(m_type, message)
if ("custom")
return custom_emote(m_type, message)
if("sign")
if (!src.restrained())
message = text("<B>The monkey</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
m_type = 1
if("scratch")
if (!src.restrained())
message = "<B>The [src.name]</B> scratches."
m_type = 1
if("whimper")
if (!muzzled)
message = "<B>The [src.name]</B> whimpers."
m_type = 2
if("roar")
if (!muzzled)
message = "<B>The [src.name]</B> roars."
m_type = 2
if("tail")
message = "<B>The [src.name]</B> waves his tail."
m_type = 1
if("gasp")
message = "<B>The [src.name]</B> gasps."
m_type = 2
if("shiver")
message = "<B>The [src.name]</B> shivers."
m_type = 2
if("drool")
message = "<B>The [src.name]</B> drools."
m_type = 1
if("paw")
if (!src.restrained())
message = "<B>The [src.name]</B> flails his paw."
m_type = 1
if("scretch")
if (!muzzled)
message = "<B>The [src.name]</B> scretches."
m_type = 2
if("choke")
message = "<B>The [src.name]</B> chokes."
m_type = 2
if("moan")
message = "<B>The [src.name]</B> moans!"
m_type = 2
if("nod")
message = "<B>The [src.name]</B> nods his head."
m_type = 1
if("sit")
message = "<B>The [src.name]</B> sits down."
m_type = 1
if("sway")
message = "<B>The [src.name]</B> sways around dizzily."
m_type = 1
if("sulk")
message = "<B>The [src.name]</B> sulks down sadly."
m_type = 1
if("twitch")
message = "<B>The [src.name]</B> twitches violently."
m_type = 1
if("dance")
if (!src.restrained())
message = "<B>The [src.name]</B> dances around happily."
m_type = 1
if("roll")
if (!src.restrained())
message = "<B>The [src.name]</B> rolls."
m_type = 1
if("shake")
message = "<B>The [src.name]</B> shakes his head."
m_type = 1
if("gnarl")
if (!muzzled)
message = "<B>The [src.name]</B> gnarls and shows his teeth.."
m_type = 2
if("jump")
message = "<B>The [src.name]</B> jumps!"
m_type = 1
if("collapse")
Paralyse(2)
message = text("<B>[]</B> collapses!", src)
m_type = 2
if("deathgasp")
message = "<b>The [src.name]</b> lets out a faint chimper as it collapses and stops moving..."
m_type = 1
if("help")
src << "choke, collapse, dance, deathgasp, drool, gasp, shiver, gnarl, jump, paw, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
else
src << text("Invalid Emote: []", act)
if ((message && src.stat == 0))
if(src.client)
log_emote("[name]/[key] : [message]")
if (m_type & 1)
for(var/mob/O in viewers(src, null))
O.show_message(message, m_type)
//Foreach goto(703)
else
for(var/mob/O in hearers(src, null))
O.show_message(message, m_type)
//Foreach goto(746)
return
@@ -0,0 +1,45 @@
/mob/living/carbon/monkey/examine()
set src in oview()
if(!usr || !src) return
if( (usr.sdisabilities & BLIND || usr.blinded || usr.stat) && !istype(usr,/mob/dead/observer) )
usr << "<span class='notice'>Something is there but you can't see it.</span>"
return
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
if (src.handcuffed)
msg += "It is \icon[src.handcuffed] handcuffed!\n"
if (src.wear_mask)
msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its head.\n"
if (src.l_hand)
msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n"
if (src.r_hand)
msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n"
if (src.back)
msg += "It has \icon[src.back] \a [src.back] on its back.\n"
if (src.stat == DEAD)
msg += "<span class='deadsay'>It is limp and unresponsive, with no signs of life.</span>\n"
else
msg += "<span class='warning'>"
if (src.getBruteLoss())
if (src.getBruteLoss() < 30)
msg += "It has minor bruising.\n"
else
msg += "<B>It has severe bruising!</B>\n"
if (src.getFireLoss())
if (src.getFireLoss() < 30)
msg += "It has minor burns.\n"
else
msg += "<B>It has severe burns!</B>\n"
if (src.stat == UNCONSCIOUS)
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
msg += "</span>"
if (src.digitalcamo)
msg += "It is repulsively uncanny!\n"
msg += "*---------*</span>"
usr << msg
return
@@ -0,0 +1,236 @@
/obj/effect/equip_e/monkey/process()
if (item)
item.add_fingerprint(source)
if (!( item ))
switch(place)
if("head")
if (!( target.wear_mask ))
del(src)
return
if("l_hand")
if (!( target.l_hand ))
del(src)
return
if("r_hand")
if (!( target.r_hand ))
del(src)
return
if("back")
if (!( target.back ))
del(src)
return
if("handcuff")
if (!( target.handcuffed ))
del(src)
return
if("internal")
if ((!( (istype(target.wear_mask, /obj/item/clothing/mask) && istype(target.back, /obj/item/weapon/tank) && !( target.internal )) ) && !( target.internal )))
del(src)
return
if (item)
if(isrobot(source) && place != "handcuff")
var/list/L = list( "syringe", "pill", "drink", "dnainjector", "fuel")
if(!(L.Find(place)))
del(src)
return
for(var/mob/O in viewers(target, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] is trying to put a [] on []</B>", source, item, target), 1)
else
var/message = null
switch(place)
if("mask")
if(istype(target.wear_mask, /obj/item/clothing)&&!target.wear_mask:canremove)
message = text("\red <B>[] fails to take off \a [] from []'s body!</B>", source, target.wear_mask, target)
else
message = text("\red <B>[] is trying to take off \a [] from []'s head!</B>", source, target.wear_mask, target)
if("l_hand")
message = text("\red <B>[] is trying to take off a [] from []'s left hand!</B>", source, target.l_hand, target)
if("r_hand")
message = text("\red <B>[] is trying to take off a [] from []'s right hand!</B>", source, target.r_hand, target)
if("back")
message = text("\red <B>[] is trying to take off a [] from []'s back!</B>", source, target.back, target)
if("handcuff")
message = text("\red <B>[] is trying to unhandcuff []!</B>", source, target)
if("internal")
if (target.internal)
message = text("\red <B>[] is trying to remove []'s internals</B>", source, target)
else
message = text("\red <B>[] is trying to set on []'s internals.</B>", source, target)
else
for(var/mob/M in viewers(target, null))
M.show_message(message, 1)
spawn( 30 )
done()
return
return
/obj/effect/equip_e/monkey/done()
if(!source || !target) return
if(source.loc != s_loc) return
if(target.loc != t_loc) return
if(LinkBlocked(s_loc,t_loc)) return
if(item && source.get_active_hand() != item) return
if ((source.restrained() || source.stat)) return
switch(place)
if("mask")
if (target.wear_mask)
if(istype(target.wear_mask, /obj/item/clothing)&& !target.wear_mask:canremove)
return
var/obj/item/W = target.wear_mask
target.u_equip(W)
if (target.client)
target.client.screen -= W
if (W)
W.loc = target.loc
W.dropped(target)
W.layer = initial(W.layer)
W.add_fingerprint(source)
else
if (istype(item, /obj/item/clothing/mask))
source.drop_item()
loc = target
item.layer = 20
target.wear_mask = item
item.loc = target
if("l_hand")
if (target.l_hand)
var/obj/item/W = target.l_hand
target.u_equip(W)
if (target.client)
target.client.screen -= W
if (W)
W.loc = target.loc
W.layer = initial(W.layer)
W.dropped(target)
W.add_fingerprint(source)
else
if (istype(item, /obj/item))
source.drop_item()
loc = target
item.layer = 20
target.l_hand = item
item.loc = target
item.dropped(source)
item.equipped(target,target.l_hand)
if("r_hand")
if (target.r_hand)
var/obj/item/W = target.r_hand
target.u_equip(W)
if (target.client)
target.client.screen -= W
if (W)
W.loc = target.loc
W.layer = initial(W.layer)
W.dropped(target)
W.add_fingerprint(source)
else
if (istype(item, /obj/item))
source.drop_item()
loc = target
item.layer = 20
target.r_hand = item
item.loc = target
item.dropped(source)
item.equipped(target,target.r_hand)
if("back")
if (target.back)
var/obj/item/W = target.back
target.u_equip(W)
if (target.client)
target.client.screen -= W
if (W)
W.loc = target.loc
W.dropped(target)
W.layer = initial(W.layer)
W.add_fingerprint(source)
else
if ((istype(item, /obj/item) && item.slot_flags & SLOT_BACK ))
source.drop_item()
loc = target
item.layer = 20
target.back = item
item.loc = target
if("handcuff")
if (target.handcuffed)
var/obj/item/W = target.handcuffed
target.u_equip(W)
if (target.client)
target.client.screen -= W
if (W)
W.loc = target.loc
W.dropped(target)
W.layer = initial(W.layer)
W.add_fingerprint(source)
else
if (istype(item, /obj/item/weapon/handcuffs))
source.drop_item()
target.handcuffed = item
item.loc = target
if("internal")
if (target.internal)
target.internal.add_fingerprint(source)
target.internal = null
else
if (target.internal)
target.internal = null
if (!( istype(target.wear_mask, /obj/item/clothing/mask) ))
return
else
if (istype(target.back, /obj/item/weapon/tank))
target.internal = target.back
target.internal.add_fingerprint(source)
for(var/mob/M in viewers(target, 1))
if ((M.client && !( M.blinded )))
M.show_message(text("[] is now running on internals.", target), 1)
else
source.regenerate_icons()
target.regenerate_icons()
del(src)
return
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc.
/mob/living/carbon/monkey/equip_to_slot(obj/item/W as obj, slot, redraw_mob = 1)
if(!slot) return
if(!istype(W)) return
if(W == get_active_hand())
u_equip(W)
switch(slot)
if(slot_back)
src.back = W
W.equipped(src, slot)
update_inv_back(redraw_mob)
if(slot_wear_mask)
src.wear_mask = W
W.equipped(src, slot)
update_inv_wear_mask(redraw_mob)
if(slot_handcuffed)
src.handcuffed = W
update_inv_handcuffed(redraw_mob)
if(slot_legcuffed)
src.legcuffed = W
W.equipped(src, slot)
update_inv_legcuffed(redraw_mob)
if(slot_l_hand)
src.l_hand = W
W.equipped(src, slot)
update_inv_l_hand(redraw_mob)
if(slot_r_hand)
src.r_hand = W
W.equipped(src, slot)
update_inv_r_hand(redraw_mob)
if(slot_in_backpack)
W.loc = src.back
else
usr << "\red You are trying to eqip this item to an unsupported inventory slot. How the heck did you manage that? Stop it..."
return
W.layer = 20
return
@@ -0,0 +1,675 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/mob/living/carbon/monkey
var/oxygen_alert = 0
var/toxins_alert = 0
var/fire_alert = 0
var/pressure_alert = 0
var/temperature_alert = 0
/mob/living/carbon/monkey/Life()
set invisibility = 0
set background = 1
if (monkeyizing) return
if (update_muts)
update_muts=0
domutcheck(src,null,MUTCHK_FORCED)
..()
var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
if(loc)
environment = loc.return_air()
if (stat != DEAD && !istype(src,/mob/living/carbon/monkey/diona)) //still breathing
//First, resolve location and get a breath
if(air_master.current_cycle%4==2)
//Only try to take a breath every 4 seconds, unless suffocating
breathe()
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
//Updates the number of stored chemicals for powers
handle_changeling()
//Mutations and radiation
handle_mutations_and_radiation()
//Chemicals in the body
handle_chemicals_in_body()
//Disabilities
handle_disabilities()
//Virus updates, duh
handle_virus_updates()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
//to find it.
blinded = null
//Handle temperature/pressure differences between body and environment
if(environment) // More error checking -- TLE
handle_environment(environment)
//Status updates, death etc.
handle_regular_status_updates()
update_canmove()
if(client)
handle_regular_hud_updates()
// Grabbing
for(var/obj/item/weapon/grab/G in src)
G.process()
if(!client && stat == CONSCIOUS)
if(prob(33) && canmove && isturf(loc) && !pulledby) //won't move if being pulled
step(src, pick(cardinal))
if(prob(1))
emote(pick("scratch","jump","roll","tail"))
/mob/living/carbon/monkey/calculate_affecting_pressure(var/pressure)
..()
return pressure
/mob/living/carbon/monkey
proc/handle_disabilities()
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 10))
src << "\red You have a seizure!"
Paralyse(10)
if (disabilities & COUGHING)
if ((prob(5) && paralysis <= 1))
drop_item()
spawn( 0 )
emote("cough")
return
if (disabilities & TOURETTES)
if ((prob(10) && paralysis <= 1))
Stun(10)
spawn( 0 )
emote("twitch")
return
if (disabilities & NERVOUS)
if (prob(10))
stuttering = max(10, stuttering)
proc/handle_mutations_and_radiation()
if(getFireLoss())
if((COLD_RESISTANCE in mutations) || prob(50))
switch(getFireLoss())
if(1 to 50)
adjustFireLoss(-1)
if(51 to 100)
adjustFireLoss(-5)
if ((HULK in mutations) && health <= 25)
mutations.Remove(HULK)
src << "\red You suddenly feel very weak."
Weaken(3)
emote("collapse")
if (radiation)
if(istype(src,/mob/living/carbon/monkey/diona)) //Filthy check. Dionaea don't take rad damage.
var/rads = radiation/25
radiation -= rads
nutrition += rads
heal_overall_damage(rads,rads)
adjustOxyLoss(-(rads))
adjustToxLoss(-(rads))
updatehealth()
return
if (radiation > 100)
radiation = 100
Weaken(10)
src << "\red You feel weak."
emote("collapse")
switch(radiation)
if(1 to 49)
radiation--
if(prob(25))
adjustToxLoss(1)
updatehealth()
if(50 to 74)
radiation -= 2
adjustToxLoss(1)
if(prob(5))
radiation -= 5
Weaken(3)
src << "\red You feel weak."
emote("collapse")
updatehealth()
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
if(prob(1))
src << "\red You mutate!"
randmutb(src)
domutcheck(src,null)
emote("gasp")
updatehealth()
proc/handle_virus_updates()
if(status_flags & GODMODE) return 0 //godmode
if(bodytemperature > 406)
for(var/datum/disease/D in viruses)
D.cure()
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
V.cure(src)
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
if(B.virus2.len)
for (var/ID in B.virus2)
var/datum/disease2/disease/V = B.virus2[ID]
infect_virus2(src,V)
for(var/obj/effect/decal/cleanable/mucus/M in view(1,src))
if(M.virus2.len)
for (var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID]
infect_virus2(src,V)
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
if(isnull(V)) // Trying to figure out a runtime error that keeps repeating
CRASH("virus2 nulled before calling activate()")
else
V.activate(src)
// activate may have deleted the virus
if(!V) continue
// check if we're immune
if(V.antigen & src.antibodies)
V.dead = 1
return
proc/breathe()
if(reagents)
if(reagents.has_reagent("lexorin")) return
if(!loc) return //probably ought to make a proper fix for this, but :effort: --NeoFite
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
if(health < 0)
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(75)) //High chance of gasping for air
spawn emote("gasp")
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
else
//First, check for air from internal atmosphere (using an air tank and mask generally)
breath = get_breath_from_internal(BREATH_VOLUME)
//No breath from internal atmosphere so get breath from location
if(!breath)
if(istype(loc, /obj/))
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = environment.total_moles()*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
if(istype(wear_mask, /obj/item/clothing/mask/gas))
var/obj/item/clothing/mask/gas/G = wear_mask
var/datum/gas_mixture/filtered = new
filtered.copy_from(breath)
filtered.toxins *= G.gas_filter_strength
for(var/datum/gas/gas in filtered.trace_gases)
gas.moles *= G.gas_filter_strength
filtered.update_values()
loc.assume_air(filtered)
breath.toxins *= 1 - G.gas_filter_strength
for(var/datum/gas/gas in breath.trace_gases)
gas.moles *= 1 - G.gas_filter_strength
breath.update_values()
// Handle chem smoke effect -- Doohl
var/block = 0
if(wear_mask)
if(istype(wear_mask, /obj/item/clothing/mask/gas))
block = 1
if(!block)
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
if(smoke.reagents.total_volume)
smoke.reagents.reaction(src, INGEST)
spawn(5)
if(smoke)
smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
break // If they breathe in the nasty stuff once, no need to continue checking
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
var/obj/location_as_object = loc
location_as_object.handle_internal_lifeform(src, 0)
handle_breath(breath)
if(breath)
loc.assume_air(breath)
proc/get_breath_from_internal(volume_needed)
if(internal)
if (!contents.Find(internal))
internal = null
if (!wear_mask || !(wear_mask.flags|MASKINTERNALS) )
internal = null
if(internal)
if (internals)
internals.icon_state = "internal1"
return internal.remove_air_volume(volume_needed)
else
if (internals)
internals.icon_state = "internal0"
return null
proc/handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return
if(!breath || (breath.total_moles == 0))
adjustOxyLoss(7)
oxygen_alert = max(oxygen_alert, 1)
return 0
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
//var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now)
var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
var/safe_toxins_max = 0.5
var/SA_para_min = 0.5
var/SA_sleep_min = 5
var/oxygen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
//Partial pressure of the O2 in our breath
var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure
// Same, but for the toxins
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
// And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun)
var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure
if(O2_pp < safe_oxygen_min) // Too little oxygen
if(prob(20))
spawn(0) emote("gasp")
if (O2_pp == 0)
O2_pp = 0.01
var/ratio = safe_oxygen_min/O2_pp
adjustOxyLoss(min(5*ratio, 7)) // Don't fuck them up too fast (space only does 7 after all!)
oxygen_used = breath.oxygen*ratio/6
oxygen_alert = max(oxygen_alert, 1)
/*else if (O2_pp > safe_oxygen_max) // Too much oxygen (commented this out for now, I'll deal with pressure damage elsewhere I suppose)
spawn(0) emote("cough")
var/ratio = O2_pp/safe_oxygen_max
oxyloss += 5*ratio
oxygen_used = breath.oxygen*ratio/6
oxygen_alert = max(oxygen_alert, 1)*/
else // We're in safe limits
adjustOxyLoss(-5)
oxygen_used = breath.oxygen/6
oxygen_alert = 0
breath.oxygen -= oxygen_used
breath.carbon_dioxide += oxygen_used
if(CO2_pp > safe_co2_max)
if(!co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
co2overloadtime = world.time
else if(world.time - co2overloadtime > 120)
Paralyse(3)
adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business
if(world.time - co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
adjustOxyLoss(8)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
spawn(0) emote("cough")
else
co2overloadtime = 0
if(Toxins_pp > safe_toxins_max) // Too much toxins
var/ratio = (breath.toxins/safe_toxins_max) * 10
//adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) //Limit amount of damage toxin exposure can do per second
if(reagents)
reagents.add_reagent("plasma", Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE))
toxins_alert = max(toxins_alert, 1)
else
toxins_alert = 0
if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure
if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
Paralyse(3) // 3 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
sleeping = max(sleeping+2, 10)
else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
if(prob(20))
spawn(0) emote(pick("giggle", "laugh"))
if(breath.temperature > (T0C+66)) // Hot air hurts :(
if(prob(20))
src << "\red You feel a searing heat in your lungs!"
fire_alert = max(fire_alert, 2)
else
fire_alert = 0
//Temporary fixes to the alerts.
return 1
proc/handle_environment(datum/gas_mixture/environment)
if(!environment)
return
var/environment_heat_capacity = environment.heat_capacity()
if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
environment_heat_capacity = heat_turf.heat_capacity
if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
var/transfer_coefficient = 1
handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient)
if(stat==2)
bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000)
//Account for massive pressure differences
var/pressure = environment.return_pressure()
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
switch(adjusted_pressure)
if(HAZARD_HIGH_PRESSURE to INFINITY)
adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
pressure_alert = 2
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
pressure_alert = 1
if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
pressure_alert = 0
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
pressure_alert = -1
else
if( !(COLD_RESISTANCE in mutations) )
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
pressure_alert = -2
else
pressure_alert = -1
return
proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
if(status_flags & GODMODE) return
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
//adjustFireLoss(2.5*discomfort)
if(exposed_temperature > bodytemperature)
adjustFireLoss(20.0*discomfort)
else
adjustFireLoss(5.0*discomfort)
proc/handle_chemicals_in_body()
if(alien) //Diona nymphs are the only alien monkey currently.
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
else light_amount = 5
nutrition += light_amount
traumatic_shock -= light_amount
if(nutrition > 500)
nutrition = 500
if(light_amount > 2) //if there's enough light, heal
adjustBruteLoss(-1)
adjustToxLoss(-1)
adjustOxyLoss(-1)
if(reagents) reagents.metabolize(src,alien)
if (drowsyness)
drowsyness--
eye_blurry = max(2, eye_blurry)
if (prob(5))
sleeping += 1
Paralyse(5)
confused = max(0, confused - 1)
// decrement dizziness counter, clamped to 0
if(resting)
dizziness = max(0, dizziness - 5)
else
dizziness = max(0, dizziness - 1)
updatehealth()
return //TODO: DEFERRED
proc/handle_regular_status_updates()
updatehealth()
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
blinded = 1
silent = 0
else //ALIVE. LIGHTS ARE ON
if(health < config.health_threshold_dead || brain_op_stage == 4.0)
death()
blinded = 1
stat = DEAD
silent = 0
return 1
//UNCONSCIOUS. NO-ONE IS HOME
if( (getOxyLoss() > 25) || (config.health_threshold_crit > health) )
if( health <= 20 && prob(1) )
spawn(0)
emote("gasp")
if(!reagents.has_reagent("inaprovaline"))
adjustOxyLoss(1)
Paralyse(3)
if(halloss > 100)
src << "<span class='notice'>You're in too much pain to keep going...</span>"
for(var/mob/O in oviewers(src, null))
O.show_message("<B>[src]</B> slumps to the ground, too weak to continue fighting.", 1)
Paralyse(10)
setHalLoss(99)
if(paralysis)
AdjustParalysis(-1)
blinded = 1
stat = UNCONSCIOUS
if(halloss > 0)
adjustHalLoss(-3)
else if(sleeping)
handle_dreams()
adjustHalLoss(-3)
sleeping = max(sleeping-1, 0)
blinded = 1
stat = UNCONSCIOUS
if( prob(10) && health && !hal_crit )
spawn(0)
emote("snore")
else if(resting)
if(halloss > 0)
adjustHalLoss(-3)
//CONSCIOUS
else
stat = CONSCIOUS
if(halloss > 0)
adjustHalLoss(-1)
//Eyes
if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own
blinded = 1
else if(eye_blind) //blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
blinded = 1
else if(eye_blurry) //blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
//Ears
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
ear_deaf = max(ear_deaf, 1)
else if(ear_deaf) //deafness, heals slowly over time
ear_deaf = max(ear_deaf-1, 0)
else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
ear_damage = max(ear_damage-0.05, 0)
//Other
if(stunned)
AdjustStunned(-1)
if(weakened)
weakened = max(weakened-1,0) //before you get mad Rockdtben: I done this so update_canmove isn't called multiple times
if(stuttering)
stuttering = max(stuttering-1, 0)
if(silent)
silent = max(silent-1, 0)
if(druggy)
druggy = max(druggy-1, 0)
return 1
proc/handle_regular_hud_updates()
if (stat == 2 || (XRAY in mutations))
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
else if (stat != 2)
sight &= ~SEE_TURFS
sight &= ~SEE_MOBS
sight &= ~SEE_OBJS
see_in_dark = 2
see_invisible = SEE_INVISIBLE_LIVING
if (healths)
if (stat != 2)
switch(health)
if(100 to INFINITY)
healths.icon_state = "health0"
if(80 to 100)
healths.icon_state = "health1"
if(60 to 80)
healths.icon_state = "health2"
if(40 to 60)
healths.icon_state = "health3"
if(20 to 40)
healths.icon_state = "health4"
if(0 to 20)
healths.icon_state = "health5"
else
healths.icon_state = "health6"
else
healths.icon_state = "health7"
if(pressure)
pressure.icon_state = "pressure[pressure_alert]"
if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
if (toxin) toxin.icon_state = "tox[toxins_alert ? 1 : 0]"
if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]"
if (fire) fire.icon_state = "fire[fire_alert ? 2 : 0]"
//NOTE: the alerts dont reset when youre out of danger. dont blame me,
//blame the person who coded them. Temporary fix added.
if(bodytemp)
switch(bodytemperature) //310.055 optimal body temp
if(345 to INFINITY)
bodytemp.icon_state = "temp4"
if(335 to 345)
bodytemp.icon_state = "temp3"
if(327 to 335)
bodytemp.icon_state = "temp2"
if(316 to 327)
bodytemp.icon_state = "temp1"
if(300 to 316)
bodytemp.icon_state = "temp0"
if(295 to 300)
bodytemp.icon_state = "temp-1"
if(280 to 295)
bodytemp.icon_state = "temp-2"
if(260 to 280)
bodytemp.icon_state = "temp-3"
else
bodytemp.icon_state = "temp-4"
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
if(blind && stat != DEAD)
if(blinded)
blind.layer = 18
else
blind.layer = 0
if(disabilities & NEARSIGHTED)
client.screen += global_hud.vimpaired
if(eye_blurry)
client.screen += global_hud.blurry
if(druggy)
client.screen += global_hud.druggy
if (stat != 2)
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
else
if(client && !client.adminobs)
reset_view(null)
return 1
proc/handle_random_events()
if (prob(1) && prob(2))
spawn(0)
emote("scratch")
return
proc/handle_changeling()
if(mind && mind.changeling)
mind.changeling.regenerate()
@@ -0,0 +1,4 @@
/mob/living/carbon/monkey/Login()
..()
update_hud()
return
@@ -0,0 +1,519 @@
/mob/living/carbon/monkey
name = "monkey"
voice_name = "monkey"
speak_emote = list("chimpers")
icon_state = "monkey1"
icon = 'icons/mob/monkey.dmi'
gender = NEUTER
pass_flags = PASSTABLE
update_icon = 0 ///no need to call regenerate_icon
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/greaterform = "Human" // Used when humanizing a monkey.
icon_state = "monkey1"
//var/uni_append = "12C4E2" // Small appearance modifier for different species.
var/list/uni_append = list(0x12C,0x4E2) // Same as above for DNA2.
var/update_muts = 1 // Monkey gene must be set at start.
var/alien = 0 //Used for reagent metabolism.
/mob/living/carbon/monkey/tajara
name = "farwa"
voice_name = "farwa"
speak_emote = list("mews")
icon_state = "tajkey1"
uni_append = list(0x0A0,0xE00) // 0A0E00
/mob/living/carbon/monkey/skrell
name = "neaera"
voice_name = "neaera"
speak_emote = list("squicks")
icon_state = "skrellkey1"
uni_append = list(0x01C,0xC92) // 01CC92
/mob/living/carbon/monkey/unathi
name = "stok"
voice_name = "stok"
speak_emote = list("hisses")
icon_state = "stokkey1"
uni_append = list(0x044,0xC5D) // 044C5D
/mob/living/carbon/monkey/New()
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
if(name == initial(name)) //To stop Pun-Pun becoming generic.
name = "[name] ([rand(1, 1000)])"
real_name = name
if (!(dna))
if(gender == NEUTER)
gender = pick(MALE, FEMALE)
dna = new /datum/dna( null )
dna.real_name = real_name
dna.ResetSE()
dna.ResetUI()
//dna.uni_identity = "00600200A00E0110148FC01300B009"
//dna.SetUI(list(0x006,0x002,0x00A,0x00E,0x011,0x014,0x8FC,0x013,0x00B,0x009))
//dna.struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6"
//dna.SetSE(list(0x433,0x591,0x567,0x561,0x31E,0x137,0x633,0x34D,0x1C3,0x690,0x120,0x321,0x64D,0x4FE,0x4CD,0x615,0x44B,0x6C0,0x3F2,0x51B,0x6C6,0x0A4,0x282,0x1D2,0x6BA,0x3B0,0xFD6))
dna.unique_enzymes = md5(name)
// We're a monkey
dna.SetSEState(MONKEYBLOCK, 1)
dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF)
// Fix gender
dna.SetUIState(DNA_UI_GENDER, gender != MALE, 1)
// Set the blocks to uni_append, if needed.
if(uni_append.len>0)
for(var/b=1;b<=uni_append.len;b++)
dna.SetUIValue(DNA_UI_LENGTH-(uni_append.len-b),uni_append[b], 1)
dna.UpdateUI()
update_muts=1
..()
update_icons()
return
/mob/living/carbon/monkey/unathi/New()
..()
dna.mutantrace = "lizard"
greaterform = "Unathi"
add_language("Sinta'unathi")
/mob/living/carbon/monkey/skrell/New()
..()
dna.mutantrace = "skrell"
greaterform = "Skrell"
add_language("Skrellian")
/mob/living/carbon/monkey/tajara/New()
..()
dna.mutantrace = "tajaran"
greaterform = "Tajaran"
add_language("Siik'tajr")
/mob/living/carbon/monkey/diona/New()
..()
alien = 1
gender = NEUTER
dna.mutantrace = "plant"
greaterform = "Diona"
add_language("Rootspeak")
/mob/living/carbon/monkey/movement_delay()
var/tally = 0
if(reagents)
if(reagents.has_reagent("hyperzine")) return -1
if(reagents.has_reagent("nuka_cola")) return -1
var/health_deficiency = (100 - health)
if(health_deficiency >= 45) tally += (health_deficiency / 25)
if (bodytemperature < 283.222)
tally += (283.222 - bodytemperature) / 10 * 1.75
return tally+config.monkey_delay
/mob/living/carbon/monkey/Bump(atom/movable/AM as mob|obj, yes)
spawn( 0 )
if ((!( yes ) || now_pushing))
return
now_pushing = 1
if(ismob(AM))
var/mob/tmob = AM
if(istype(tmob, /mob/living/carbon/human) && (HULK in tmob.mutations))
if(prob(70))
usr << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
now_pushing = 0
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
tmob.LAssailant = src
now_pushing = 0
..()
if (!( istype(AM, /atom/movable) ))
return
if (!( now_pushing ))
now_pushing = 1
if (!( AM.anchored ))
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = 0
return
step(AM, t)
now_pushing = null
return
return
/mob/living/carbon/monkey/Topic(href, href_list)
..()
if (href_list["mach_close"])
var/t1 = text("window=[]", href_list["mach_close"])
unset_machine()
src << browse(null, t1)
if ((href_list["item"] && !( usr.stat ) && !( usr.restrained() ) && in_range(src, usr) ))
var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey( )
O.source = usr
O.target = src
O.item = usr.get_active_hand()
O.s_loc = usr.loc
O.t_loc = loc
O.place = href_list["item"]
requests += O
spawn( 0 )
O.process()
return
..()
return
/mob/living/carbon/monkey/meteorhit(obj/O as obj)
for(var/mob/M in viewers(src, null))
M.show_message(text("\red [] has been hit by []", src, O), 1)
if (health > 0)
var/shielded = 0
adjustBruteLoss(30)
if ((O.icon_state == "flaming" && !( shielded )))
adjustFireLoss(40)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
return
//mob/living/carbon/monkey/bullet_act(var/obj/item/projectile/Proj)taken care of in living
/mob/living/carbon/monkey/attack_paw(mob/M as mob)
..()
if (M.a_intent == "help")
help_shake_act(M)
else
if ((M.a_intent == "hurt" && !( istype(wear_mask, /obj/item/clothing/mask/muzzle) )))
if ((prob(75) && health > 0))
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M.name] has bit [name]!</B>", 1)
var/damage = rand(1, 5)
adjustBruteLoss(damage)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/jungle_fever))
contract_disease(D,1,0)
else
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M.name] has attempted to bite [name]!</B>", 1)
return
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
Weaken(5)
if (stuttering < 5)
stuttering = 5
Stun(5)
for(var/mob/O in viewers(src, null))
if (O.client)
O.show_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>", 1, "\red You hear someone fall", 2)
return
else
M << "\red Not enough charge! "
return
if (M.a_intent == "help")
help_shake_act(M)
else
if (M.a_intent == "hurt")
if ((prob(75) && health > 0))
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has punched [name]!</B>", M), 1)
playsound(loc, "punch", 25, 1, -1)
var/damage = rand(5, 10)
if (prob(40))
damage = rand(10, 15)
if (paralysis < 5)
Paralyse(rand(10, 15))
spawn( 0 )
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has knocked out [name]!</B>", M), 1)
return
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has attempted to punch [name]!</B>", M), 1)
else
if (M.a_intent == "grab")
if (M == src || anchored)
return
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src )
M.put_in_active_hand(G)
grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
else
if (!( paralysis ))
if (prob(25))
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has pushed down [name]!</B>", M), 1)
else
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
return
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if (istype(loc, /turf) && istype(loc.loc, /area/start))
M << "No attacking people at spawn, you jackass."
return
switch(M.a_intent)
if ("help")
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
if ("hurt")
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))
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has wounded [name]!</B>", M), 1)
else
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has slashed [name]!</B>", M), 1)
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has attempted to lunge at [name]!</B>", M), 1)
if ("grab")
if (M == src)
return
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
M.put_in_active_hand(G)
grabbed_by += G
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
if ("disarm")
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
var/damage = 5
if(prob(95))
Weaken(15)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has tackled down [name]!</B>", M), 1)
else
drop_item()
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/monkey/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
return
if(M.Victim) return // can't attack while eating!
if (health > -100)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] glomps []!</B>", src), 1)
var/damage = rand(1, 3)
if(istype(src, /mob/living/carbon/slime/adult))
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
if(M.powerlevel > 0)
var/stunprob = 10
var/power = M.powerlevel + rand(0,3)
switch(M.powerlevel)
if(1 to 2) stunprob = 20
if(3 to 4) stunprob = 30
if(5 to 6) stunprob = 40
if(7 to 8) stunprob = 60
if(9) stunprob = 70
if(10) stunprob = 95
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>The [M.name] has shocked []!</B>", src), 1)
Weaken(power)
if (stuttering < power)
stuttering = power
Stun(power)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
if (prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return
/mob/living/carbon/monkey/Stat()
..()
statpanel("Status")
stat(null, text("Intent: []", a_intent))
stat(null, text("Move Mode: []", m_intent))
if(client && mind)
if (client.statpanel == "Status")
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
stat("Genetic Damage Time", mind.changeling.geneticdamage)
return
/mob/living/carbon/monkey/verb/removeinternal()
set name = "Remove Internals"
set category = "IC"
internal = null
return
/mob/living/carbon/monkey/var/co2overloadtime = null
/mob/living/carbon/monkey/var/temperature_resistance = T0C+75
/mob/living/carbon/monkey/emp_act(severity)
if(wear_id) wear_id.emp_act(severity)
..()
/mob/living/carbon/monkey/ex_act(severity)
if(!blinded)
flick("flash", flash)
switch(severity)
if(1.0)
if (stat != 2)
adjustBruteLoss(200)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
if(2.0)
if (stat != 2)
adjustBruteLoss(60)
adjustFireLoss(60)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
if(3.0)
if (stat != 2)
adjustBruteLoss(30)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
if (prob(50))
Paralyse(10)
else
return
/mob/living/carbon/monkey/blob_act()
if (stat != 2)
adjustFireLoss(60)
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
if (prob(50))
Paralyse(10)
if (stat == DEAD && client)
gib()
return
if (stat == DEAD && !client)
gibs(loc, viruses)
del(src)
return
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
if(!ticker) return 0
if(!ticker.mode.name == "monkey") return 0
return 1
@@ -0,0 +1,99 @@
mob/living/carbon/monkey/var
mob/npc_target = null // the NPC this monkey is attacking
mob/npc_fleeing = null // the monkey is scared of this mob
mob/hiding_behind = null
hid_behind = 0
var/list/hostiles = list()
fleeing_duration = 0
mob/living/carbon/monkey/proc/npc_act()
if(!client && !stat)
if(npc_fleeing && canmove)
var/prevloc = loc
if(!hiding_behind)
for(var/mob/living/carbon/human/H in view(7, src))
if(!hostiles.Find(H))
hiding_behind = H
if(hiding_behind)
if(get_dist(src, hiding_behind) == 1)
if(!hid_behind)
emote("me", 1, "hides behind [hiding_behind]!")
hid_behind = 1
step_to(src, get_step(hiding_behind, get_dir(npc_fleeing, hiding_behind)))
else
if(!step_to(src, hiding_behind, 1))
hiding_behind = null
else
step_away(src, npc_fleeing, 7)
if(prob(7))
if(prob(50) && (npc_fleeing in view(8,src)))
switch(rand(1,3))
if(1)
emote("me", 1, "shows [npc_fleeing] its fangs!")
if(2)
emote("me", 2, "gnarls at [npc_fleeing].")
if(3)
emote("me", 2, "eyes [npc_fleeing] fearfully.")
else
switch(rand(1,3))
if(1)
emote("whimper")
if(2)
emote("me", 1, "trembles heavily.")
if(3)
emote("me", 2, "chimpers nervously.")
fleeing_duration--
if(fleeing_duration <= 0)
npc_fleeing = null
hiding_behind = null
hid_behind = 0
if(loc == prevloc) dir = get_dir(src, npc_fleeing)
else
if(prob(33) && canmove && isturf(loc))
step(src, pick(cardinal))
if(prob(1))
if(health < 70)
switch(rand(1,3))
if(1)
emote("me", 1, "cowers on the floor, writhing in pain.")
if(2)
emote("me", 1, "trembles visibly, it seems to be in pain.")
if(3)
emote("me", 1, "wraps its arms around its knees, breathing heavily.")
else
emote(pick("scratch","jump","roll","tail"))
mob/living/carbon/monkey/react_to_attack(mob/M)
if(npc_fleeing == M)
fleeing_duration += 30
return
if(!hostiles.Find(M)) hostiles += M
spawn(5)
switch(rand(1,3))
if(1)
emote("me", 1, "flails about wildly!")
if(2)
emote("me", 2, "screams loudly at [M]!")
if(3)
emote("me", 2, "whimpers fearfully!")
npc_fleeing = M
fleeing_duration = 30
/*/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/slash = 0, var/used_weapon = null)
if(!client && !stat)
if(damage > 10)
if(prob(40) || health == 100)
emote("me", 2, pick("screams loudly!", "whimpers in pain!"))
else if(health == 100 || (damage > 0 && prob(10)))
emote("me", 1, pick("flails about wildly!", "cringes visibly!", "chimpers nervously."))
return ..()*/
@@ -0,0 +1,5 @@
/mob/living/carbon/monkey/verb/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Monkey"
handle_ventcrawl()
@@ -0,0 +1,120 @@
//Monkey Overlays Indexes////////
#define M_MASK_LAYER 1
#define M_BACK_LAYER 2
#define M_HANDCUFF_LAYER 3
#define M_L_HAND_LAYER 4
#define M_R_HAND_LAYER 5
#define TARGETED_LAYER 6
#define M_TOTAL_LAYERS 6
/////////////////////////////////
/mob/living/carbon/monkey
var/list/overlays_lying[M_TOTAL_LAYERS]
var/list/overlays_standing[M_TOTAL_LAYERS]
/mob/living/carbon/monkey/regenerate_icons()
..()
update_inv_wear_mask(0)
update_inv_back(0)
update_inv_r_hand(0)
update_inv_l_hand(0)
update_inv_handcuffed(0)
update_icons()
//Hud Stuff
update_hud()
return
/mob/living/carbon/monkey/update_icons()
update_hud()
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
overlays.Cut()
for(var/image/I in overlays_standing)
overlays += I
if(lying)
var/matrix/M = matrix()
M.Turn(90)
M.Translate(1,-6)
src.transform = M
else
var/matrix/M = matrix()
src.transform = M
////////
/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1)
if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) )
overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]")
wear_mask.screen_loc = ui_monkey_mask
else
overlays_standing[M_MASK_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1)
if(r_hand)
var/t_state = r_hand.item_state
if(!t_state) t_state = r_hand.icon_state
overlays_standing[M_R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = t_state)
r_hand.screen_loc = ui_rhand
if (handcuffed) drop_r_hand()
else
overlays_standing[M_R_HAND_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/monkey/update_inv_l_hand(var/update_icons=1)
if(l_hand)
var/t_state = l_hand.item_state
if(!t_state) t_state = l_hand.icon_state
overlays_standing[M_L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = t_state)
l_hand.screen_loc = ui_lhand
if (handcuffed) drop_l_hand()
else
overlays_standing[M_L_HAND_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/monkey/update_inv_back(var/update_icons=1)
if(back)
overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
back.screen_loc = ui_monkey_back
else
overlays_standing[M_BACK_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/monkey/update_inv_handcuffed(var/update_icons=1)
if(handcuffed)
drop_r_hand()
drop_l_hand()
stop_pulling()
overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1")
else
overlays_standing[M_HANDCUFF_LAYER] = null
if(update_icons) update_icons()
/mob/living/carbon/monkey/update_hud()
if (client)
client.screen |= contents
//Call when target overlay should be added/removed
/mob/living/carbon/monkey/update_targeted(var/update_icons=1)
if (targeted_by && target_locked)
overlays_standing[TARGETED_LAYER] = target_locked
else if (!targeted_by && target_locked)
del(target_locked)
if (!targeted_by)
overlays_standing[TARGETED_LAYER] = null
if(update_icons) update_icons()
//Monkey Overlays Indexes////////
#undef M_MASK_LAYER
#undef M_BACK_LAYER
#undef M_HANDCUFF_LAYER
#undef M_L_HAND_LAYER
#undef M_R_HAND_LAYER
#undef TARGETED_LAYER
#undef M_TOTAL_LAYERS
+51
View File
@@ -0,0 +1,51 @@
/mob/living/var/traumatic_shock = 0
/mob/living/carbon/var/shock_stage = 0
// proc to find out in how much pain the mob is at the moment
/mob/living/carbon/proc/updateshock()
src.traumatic_shock = \
1 * src.getOxyLoss() + \
0.7 * src.getToxLoss() + \
1.5 * src.getFireLoss() + \
1.2 * src.getBruteLoss() + \
1.7 * src.getCloneLoss() + \
2 * src.halloss
if(reagents.has_reagent("alkysine"))
src.traumatic_shock -= 10
if(reagents.has_reagent("inaprovaline"))
src.traumatic_shock -= 25
if(reagents.has_reagent("synaptizine"))
src.traumatic_shock -= 40
if(reagents.has_reagent("paracetamol"))
src.traumatic_shock -= 50
if(reagents.has_reagent("tramadol"))
src.traumatic_shock -= 80
if(reagents.has_reagent("oxycodone"))
src.traumatic_shock -= 200
if(src.slurring)
src.traumatic_shock -= 20
if(src.analgesic)
src.traumatic_shock = 0
// broken or ripped off organs will add quite a bit of pain
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/M = src
for(var/datum/organ/external/organ in M.organs)
if (!organ)
continue
if((organ.status & ORGAN_DESTROYED) && !organ.amputated)
src.traumatic_shock += 60
else if(organ.status & ORGAN_BROKEN || organ.open)
src.traumatic_shock += 30
if(organ.status & ORGAN_SPLINTED)
src.traumatic_shock -= 25
if(src.traumatic_shock < 0)
src.traumatic_shock = 0
return src.traumatic_shock
/mob/living/carbon/proc/handle_shock()
updateshock()
+158
View File
@@ -0,0 +1,158 @@
/*
Datum-based species. Should make for much cleaner and easier to maintain mutantrace code.
*/
/datum/species
var/name // Species name.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/eyes = "eyes_s" // Icon for eyes.
var/primitive // Lesser form, if any (ie. monkey for humans)
var/tail // Name of tail image in species effects icon file.
var/language // Default racial language, if any.
var/attack_verb = "punch" // Empty hand hurt intent verb.
var/punch_damage = 0 // Extra empty hand attack damage.
var/mutantrace // Safeguard due to old code.
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/cold_level_1 = 260 // Cold damage level 1 below this point.
var/cold_level_2 = 200 // Cold damage level 2 below this point.
var/cold_level_3 = 120 // Cold damage level 3 below this point.
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 2 above this point.
var/darksight = 2
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure.
var/brute_resist // Physical damage reduction.
var/burn_resist // Burn damage reduction.
var/flags = 0 // Various specific features.
var/list/abilities = list() // For species-derived or admin-given powers
var/blood_color = "#A10808" //Red.
var/flesh_color = "#FFC896" //Pink.
/datum/species/human
name = "Human"
language = "Sol Common"
primitive = /mob/living/carbon/monkey
flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR
//If you wanted to add a species-level ability:
/*abilities = list(/client/proc/test_ability)*/
/datum/species/unathi
name = "Unathi"
icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi'
language = "Sinta'unathi"
tail = "sogtail"
attack_verb = "scratch"
punch_damage = 5
primitive = /mob/living/carbon/monkey/unathi
darksight = 3
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
cold_level_3 = 130 //Default 120
heat_level_1 = 420 //Default 360 - Higher is better
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flesh_color = "#34AF10"
/datum/species/tajaran
name = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
language = "Siik'tajr"
tail = "tajtail"
attack_verb = "scratch"
punch_damage = 5
darksight = 8
cold_level_1 = 200 //Default 260
cold_level_2 = 140 //Default 200
cold_level_3 = 80 //Default 120
heat_level_1 = 330 //Default 360
heat_level_2 = 380 //Default 400
heat_level_3 = 800 //Default 1000
primitive = /mob/living/carbon/monkey/tajara
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL
flesh_color = "#AFA59E"
/datum/species/skrell
name = "Skrell"
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR
flesh_color = "#8CD7A3"
/datum/species/vox
name = "Vox"
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
language = "Vox-pidgin"
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
eyes = "vox_eyes_s"
breath_type = "nitrogen"
flags = NO_SCAN | NO_BLOOD
blood_color = "#2299FC"
flesh_color = "#808D11"
/datum/species/diona
name = "Diona"
icobase = 'icons/mob/human_races/r_plant.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
attack_verb = "slash"
punch_damage = 5
primitive = /mob/living/carbon/monkey/diona
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
blood_color = "#004400"
flesh_color = "#907E4A"
+77
View File
@@ -0,0 +1,77 @@
/*
apply_damage(a,b,c)
args
a:damage - How much damage to take
b:damage_type - What type of damage to take, brute, burn
c:def_zone - Where to take the damage if its brute or burn
Returns
standard 0 if fail
*/
/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/used_weapon = null)
if(!damage || (blocked >= 2)) return 0
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage/(blocked+1))
if(BURN)
if(COLD_RESISTANCE in mutations) damage = 0
adjustFireLoss(damage/(blocked+1))
if(TOX)
adjustToxLoss(damage/(blocked+1))
if(OXY)
adjustOxyLoss(damage/(blocked+1))
if(CLONE)
adjustCloneLoss(damage/(blocked+1))
if(HALLOSS)
adjustHalLoss(damage/(blocked+1))
updatehealth()
return 1
/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/halloss = 0, var/def_zone = null, var/blocked = 0)
if(blocked >= 2) return 0
if(brute) apply_damage(brute, BRUTE, def_zone, blocked)
if(burn) apply_damage(burn, BURN, def_zone, blocked)
if(tox) apply_damage(tox, TOX, def_zone, blocked)
if(oxy) apply_damage(oxy, OXY, def_zone, blocked)
if(clone) apply_damage(clone, CLONE, def_zone, blocked)
if(halloss) apply_damage(halloss, HALLOSS, def_zone, blocked)
return 1
/mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0)
if(!effect || (blocked >= 2)) return 0
switch(effecttype)
if(STUN)
Stun(effect/(blocked+1))
if(WEAKEN)
Weaken(effect/(blocked+1))
if(PARALYZE)
Paralyse(effect/(blocked+1))
if(AGONY)
halloss += effect // Useful for objects that cause "subdual" damage. PAIN!
if(IRRADIATE)
radiation += max((((effect - (effect*(getarmor(null, "rad")/100))))/(blocked+1)),0)//Rads auto check armor
if(STUTTER)
if(status_flags & CANSTUN) // stun is usually associated with stutter
stuttering = max(stuttering,(effect/(blocked+1)))
if(EYE_BLUR)
eye_blurry = max(eye_blurry,(effect/(blocked+1)))
if(DROWSY)
drowsyness = max(drowsyness,(effect/(blocked+1)))
updatehealth()
return 1
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0)
if(blocked >= 2) return 0
if(stun) apply_effect(stun, STUN, blocked)
if(weaken) apply_effect(weaken, WEAKEN, blocked)
if(paralyze) apply_effect(paralyze, PARALYZE, blocked)
if(irradiate) apply_effect(irradiate, IRRADIATE, blocked)
if(stutter) apply_effect(stutter, STUTTER, blocked)
if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked)
if(drowsy) apply_effect(drowsy, DROWSY, blocked)
if(agony) apply_effect(agony, AGONY, blocked)
return 1
+769
View File
@@ -0,0 +1,769 @@
/mob/living/verb/succumb()
set hidden = 1
if ((src.health < 0 && src.health > -95.0))
src.adjustOxyLoss(src.health + 200)
src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
src << "\blue You have given up life and succumbed to death."
/mob/living/proc/updatehealth()
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
else
health = maxHealth - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - getCloneLoss() - halloss
//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(var/pressure)
return 0
//sort of a legacy burn method for /electrocute, /shock, and the e_chair
/mob/living/proc/burn_skin(burn_amount)
if(istype(src, /mob/living/carbon/human))
//world << "DEBUG: burn_skin(), mutations=[mutations]"
if(mShock in src.mutations) //shockproof
return 0
if (COLD_RESISTANCE in src.mutations) //fireproof
return 0
var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part
var/divided_damage = (burn_amount)/(H.organs.len)
var/extradam = 0 //added to when organ is at max dam
for(var/datum/organ/external/affecting in H.organs)
if(!affecting) continue
if(affecting.take_damage(0, divided_damage+extradam)) //TODO: fix the extradam stuff. Or, ebtter yet...rewrite this entire proc ~Carn
H.UpdateDamageIcon()
H.updatehealth()
return 1
else if(istype(src, /mob/living/carbon/monkey))
if (COLD_RESISTANCE in src.mutations) //fireproof
return 0
var/mob/living/carbon/monkey/M = src
M.adjustFireLoss(burn_amount)
M.updatehealth()
return 1
else if(istype(src, /mob/living/silicon/ai))
return 0
/mob/living/proc/adjustBodyTemp(actual, desired, incrementboost)
var/temperature = actual
var/difference = abs(actual-desired) //get difference
var/increments = difference/10 //find how many increments apart they are
var/change = increments*incrementboost // Get the amount to change by (x per increment)
// Too cold
if(actual < desired)
temperature += change
if(actual > desired)
temperature = desired
// Too hot
if(actual > desired)
temperature -= change
if(actual < desired)
temperature = desired
// if(istype(src, /mob/living/carbon/human))
// world << "[src] ~ [src.bodytemperature] ~ [temperature]"
return temperature
// ++++ROCKDTBEN++++ MOB PROCS -- Ask me before touching.
// Stop! ... Hammertime! ~Carn
// I touched them without asking... I'm soooo edgy ~Erro (added nodamage checks)
/mob/living/proc/getBruteLoss()
return bruteloss
/mob/living/proc/adjustBruteLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
bruteloss = min(max(bruteloss + amount, 0),(maxHealth*2))
/mob/living/proc/getOxyLoss()
return oxyloss
/mob/living/proc/adjustOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
oxyloss = min(max(oxyloss + amount, 0),(maxHealth*2))
/mob/living/proc/setOxyLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
oxyloss = amount
/mob/living/proc/getToxLoss()
return toxloss
/mob/living/proc/adjustToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
toxloss = min(max(toxloss + amount, 0),(maxHealth*2))
/mob/living/proc/setToxLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
toxloss = amount
/mob/living/proc/getFireLoss()
return fireloss
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
fireloss = min(max(fireloss + amount, 0),(maxHealth*2))
/mob/living/proc/getCloneLoss()
return cloneloss
/mob/living/proc/adjustCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
cloneloss = min(max(cloneloss + amount, 0),(maxHealth*2))
/mob/living/proc/setCloneLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
cloneloss = amount
/mob/living/proc/getBrainLoss()
return brainloss
/mob/living/proc/adjustBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
brainloss = min(max(brainloss + amount, 0),(maxHealth*2))
/mob/living/proc/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
brainloss = amount
/mob/living/proc/getHalLoss()
return halloss
/mob/living/proc/adjustHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
halloss = min(max(halloss + amount, 0),(maxHealth*2))
/mob/living/proc/setHalLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
halloss = amount
/mob/living/proc/getMaxHealth()
return maxHealth
/mob/living/proc/setMaxHealth(var/newMaxHealth)
maxHealth = newMaxHealth
// ++++ROCKDTBEN++++ MOB PROCS //END
/mob/proc/get_contents()
//Recursive function to find everything a mob is holding.
/mob/living/get_contents(var/obj/item/weapon/storage/Storage = null)
var/list/L = list()
if(Storage) //If it called itself
L += Storage.return_inv()
//Leave this commented out, it will cause storage items to exponentially add duplicate to the list
//for(var/obj/item/weapon/storage/S in Storage.return_inv()) //Check for storage items
// L += get_contents(S)
for(var/obj/item/weapon/gift/G in Storage.return_inv()) //Check for gift-wrapped items
L += G.gift
if(istype(G.gift, /obj/item/weapon/storage))
L += get_contents(G.gift)
for(var/obj/item/smallDelivery/D in Storage.return_inv()) //Check for package wrapped items
L += D.wrapped
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
L += get_contents(D.wrapped)
return L
else
L += src.contents
for(var/obj/item/weapon/storage/S in src.contents) //Check for storage items
L += get_contents(S)
for(var/obj/item/weapon/gift/G in src.contents) //Check for gift-wrapped items
L += G.gift
if(istype(G.gift, /obj/item/weapon/storage))
L += get_contents(G.gift)
for(var/obj/item/smallDelivery/D in src.contents) //Check for package wrapped items
L += D.wrapped
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
L += get_contents(D.wrapped)
return L
/mob/living/proc/check_contents_for(A)
var/list/L = src.get_contents()
for(var/obj/B in L)
if(B.type == A)
return 1
return 0
/mob/living/proc/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.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/get_organ_target()
var/mob/shooter = src
var/t = shooter:zone_sel.selecting
if ((t in list( "eyes", "mouth" )))
t = "head"
var/datum/organ/external/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(var/brute, var/burn)
adjustBruteLoss(-brute)
adjustFireLoss(-burn)
src.updatehealth()
// damage ONE external organ, organ gets randomly selected from damaged ones.
/mob/living/proc/take_organ_damage(var/brute, var/burn)
if(status_flags & GODMODE) return 0 //godmode
adjustBruteLoss(brute)
adjustFireLoss(burn)
src.updatehealth()
// heal MANY external organs, in random order
/mob/living/proc/heal_overall_damage(var/brute, var/burn)
adjustBruteLoss(-brute)
adjustFireLoss(-burn)
src.updatehealth()
// damage MANY external organs, in random order
/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
if(status_flags & GODMODE) return 0 //godmode
adjustBruteLoss(brute)
adjustFireLoss(burn)
src.updatehealth()
/mob/living/proc/restore_all_organs()
return
/mob/living/proc/revive()
rejuvenate()
buckled = initial(src.buckled)
if(iscarbon(src))
var/mob/living/carbon/C = src
C.handcuffed = initial(C.handcuffed)
/mob/living/proc/rejuvenate()
// shut down various types of badness
setToxLoss(0)
setOxyLoss(0)
setCloneLoss(0)
setBrainLoss(0)
SetParalysis(0)
SetStunned(0)
SetWeakened(0)
// shut down ongoing problems
radiation = 0
nutrition = 400
bodytemperature = T20C
sdisabilities = 0
disabilities = 0
// fix blindness and deafness
blinded = 0
eye_blind = 0
eye_blurry = 0
ear_deaf = 0
ear_damage = 0
heal_overall_damage(getBruteLoss(), getFireLoss())
// restore all of a human's blood
if(ishuman(src))
var/mob/living/carbon/human/human_mob = src
human_mob.restore_blood()
// fix all of our organs
restore_all_organs()
// remove the character from the list of the dead
if(stat == 2)
dead_mob_list -= src
living_mob_list += src
tod = null
// restore us to conciousness
stat = CONSCIOUS
// make the icons look correct
regenerate_icons()
return
/mob/living/proc/UpdateDamageIcon()
return
/mob/living/proc/Examine_OOC()
set name = "Examine Meta-Info (OOC)"
set category = "OOC"
set src in view()
if(config.allow_Metadata)
if(client)
usr << "[src]'s Metainfo:<br>[client.prefs.metadata]"
else
usr << "[src] does not have any stored infomation!"
else
usr << "OOC Metadata is not supported by this server!"
return
/mob/living/Move(a, b, flag)
if (buckled)
return
if (restrained())
stop_pulling()
var/t7 = 1
if (restrained())
for(var/mob/living/M in range(src, 1))
if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
t7 = null
if ((t7 && (pulling && ((get_dist(src, pulling) <= 1 || pulling.loc == loc) && (client && client.moving)))))
var/turf/T = loc
. = ..()
if (pulling && pulling.loc)
if(!( isturf(pulling.loc) ))
stop_pulling()
return
else
if(Debug)
diary <<"pulling disappeared? at [__LINE__] in mob.dm - pulling = [pulling]"
diary <<"REPORT THIS"
/////
if(pulling && pulling.anchored)
stop_pulling()
return
if (!restrained())
var/diag = get_dir(src, pulling)
if ((diag - 1) & diag)
else
diag = null
if ((get_dist(src, pulling) > 1 || diag))
if (isliving(pulling))
var/mob/living/M = pulling
var/ok = 1
if (locate(/obj/item/weapon/grab, M.grabbed_by))
if (prob(75))
var/obj/item/weapon/grab/G = pick(M.grabbed_by)
if (istype(G, /obj/item/weapon/grab))
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
//G = null
del(G)
else
ok = 0
if (locate(/obj/item/weapon/grab, M.grabbed_by.len))
ok = 0
if (ok)
var/atom/movable/t = M.pulling
M.stop_pulling()
//this is the gay blood on floor shit -- Added back -- Skie
if (M.lying && (prob(M.getBruteLoss() / 6)))
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
//pull damage with injured people
if(prob(25))
M.adjustBruteLoss(1)
visible_message("\red \The [M]'s wounds open more from being dragged!")
if(M.pull_damage())
if(prob(25))
M.adjustBruteLoss(2)
visible_message("\red \The [M]'s wounds worsen terribly from being dragged!")
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
if(ishuman(M))
var/mob/living/carbon/H = M
var/blood_volume = round(H:vessel.get_reagent_amount("blood"))
if(blood_volume > 0)
H:vessel.remove_reagent("blood",1)
step(pulling, get_dir(pulling.loc, T))
M.start_pulling(t)
else
if (pulling)
if (istype(pulling, /obj/structure/window))
if(pulling:ini_dir == NORTHWEST || pulling:ini_dir == NORTHEAST || pulling:ini_dir == SOUTHWEST || pulling:ini_dir == SOUTHEAST)
for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T)))
stop_pulling()
if (pulling)
step(pulling, get_dir(pulling.loc, T))
else
stop_pulling()
. = ..()
if ((s_active && !( s_active in contents ) ))
s_active.close(src)
if(update_slimes)
for(var/mob/living/carbon/slime/M in view(1,src))
M.UpdateFeed(src)
/mob/living/verb/resist()
set name = "Resist"
set category = "IC"
if(!isliving(usr) || usr.next_move > world.time)
return
usr.next_move = world.time + 20
var/mob/living/L = usr
//Getting out of someone's inventory.
if(istype(src.loc,/obj/item/weapon/holder))
var/obj/item/weapon/holder/H = src.loc
src.loc = get_turf(src.loc)
del(H)
return
//Resisting control by an alien mind.
if(istype(src.loc,/mob/living/simple_animal/borer))
var/mob/living/simple_animal/borer/B = src.loc
var/mob/living/captive_brain/H = src
H << "\red <B>You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).</B>"
B.host << "\red <B>You feel the captive mind of [src] begin to resist your control.</B>"
spawn(rand(350,450)+B.host.brainloss)
if(!B || !B.controlling)
return
B.host.adjustBrainLoss(rand(5,10))
H << "\red <B>With an immense exertion of will, you regain control of your body!</B>"
B.host << "\red <B>You feel control of the host brain ripped from your grasp, and retract your probosci before the wild neural impulses can damage you.</b>"
B.controlling = 0
B.ckey = B.host.ckey
B.host.ckey = H.ckey
H.ckey = null
H.name = "host brain"
H.real_name = "host brain"
verbs -= /mob/living/carbon/proc/release_control
verbs -= /mob/living/carbon/proc/punish_host
verbs -= /mob/living/carbon/proc/spawn_larvae
return
//resisting grabs (as if it helps anyone...)
if ((!( L.stat ) && L.canmove && !( L.restrained() )))
var/resisting = 0
for(var/obj/O in L.requests)
L.requests.Remove(O)
del(O)
resisting++
for(var/obj/item/weapon/grab/G in usr.grabbed_by)
resisting++
if (G.state == 1)
del(G)
else
if (G.state == 2)
if (prob(25))
for(var/mob/O in viewers(L, null))
O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1)
del(G)
else
if (G.state == 3)
if (prob(5))
for(var/mob/O in viewers(usr, null))
O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1)
del(G)
if(resisting)
for(var/mob/O in viewers(usr, null))
O.show_message(text("\red <B>[] resists!</B>", L), 1)
//unbuckling yourself
if(L.buckled && (L.last_special <= world.time) )
if(iscarbon(L))
var/mob/living/carbon/C = L
if( C.handcuffed )
C.next_move = world.time + 100
C.last_special = world.time + 100
C << "\red You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)"
for(var/mob/O in viewers(L))
O.show_message("\red <B>[usr] attempts to unbuckle themself!</B>", 1)
spawn(0)
if(do_after(usr, 1200))
if(!C.buckled)
return
for(var/mob/O in viewers(C))
O.show_message("\red <B>[usr] manages to unbuckle themself!</B>", 1)
C << "\blue You successfully unbuckle yourself."
C.buckled.manual_unbuckle(C)
else
L.buckled.manual_unbuckle(L)
//Breaking out of a locker?
else if( src.loc && (istype(src.loc, /obj/structure/closet)) )
var/breakout_time = 2 //2 minutes by default
var/obj/structure/closet/C = L.loc
if(C.opened)
return //Door's open... wait, why are you in it's contents then?
if(istype(L.loc, /obj/structure/closet/secure_closet))
var/obj/structure/closet/secure_closet/SC = L.loc
if(!SC.locked && !SC.welded)
return //It's a secure closet, but isn't locked. Easily escapable from, no need to 'resist'
else
if(!C.welded)
return //closed but not welded...
// else Meh, lets just keep it at 2 minutes for now
// breakout_time++ //Harder to get out of welded lockers than locked lockers
//okay, so the closet is either welded or locked... resist!!!
usr.next_move = world.time + 100
L.last_special = world.time + 100
L << "\red You lean on the back of \the [C] and start pushing the door open. (this will take about [breakout_time] minutes)"
for(var/mob/O in viewers(usr.loc))
O.show_message("\red <B>The [L.loc] begins to shake violently!</B>", 1)
spawn(0)
if(do_after(usr,(breakout_time*60*10))) //minutes * 60seconds * 10deciseconds
if(!C || !L || L.stat != CONSCIOUS || L.loc != C || C.opened) //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened
return
//Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'...
if(istype(L.loc, /obj/structure/closet/secure_closet))
var/obj/structure/closet/secure_closet/SC = L.loc
if(!SC.locked && !SC.welded)
return
else
if(!C.welded)
return
//Well then break it!
if(istype(usr.loc, /obj/structure/closet/secure_closet))
var/obj/structure/closet/secure_closet/SC = L.loc
SC.desc = "It appears to be broken."
SC.icon_state = SC.icon_off
flick(SC.icon_broken, SC)
sleep(10)
flick(SC.icon_broken, SC)
sleep(10)
SC.broken = 1
SC.locked = 0
usr << "\red You successfully break out!"
for(var/mob/O in viewers(L.loc))
O.show_message("\red <B>\the [usr] successfully broke out of \the [SC]!</B>", 1)
if(istype(SC.loc, /obj/structure/bigDelivery)) //Do this to prevent contents from being opened into nullspace (read: bluespace)
var/obj/structure/bigDelivery/BD = SC.loc
BD.attack_hand(usr)
SC.open()
else
C.welded = 0
usr << "\red You successfully break out!"
for(var/mob/O in viewers(L.loc))
O.show_message("\red <B>\the [usr] successfully broke out of \the [C]!</B>", 1)
if(istype(C.loc, /obj/structure/bigDelivery)) //nullspace ect.. read the comment above
var/obj/structure/bigDelivery/BD = C.loc
BD.attack_hand(usr)
C.open()
//breaking out of handcuffs
else if(iscarbon(L))
var/mob/living/carbon/CM = L
if(CM.handcuffed && CM.canmove && (CM.last_special <= world.time))
CM.next_move = world.time + 100
CM.last_special = world.time + 100
if(isalienadult(CM) || (HULK in usr.mutations))//Don't want to do a lot of logic gating here.
usr << "\red You attempt to break your handcuffs. (This will take around 5 seconds and you need to stand still)"
for(var/mob/O in viewers(CM))
O.show_message(text("\red <B>[] is trying to break the handcuffs!</B>", CM), 1)
spawn(0)
if(do_after(CM, 50))
if(!CM.handcuffed || CM.buckled)
return
for(var/mob/O in viewers(CM))
O.show_message(text("\red <B>[] manages to break the handcuffs!</B>", CM), 1)
CM << "\red You successfully break your handcuffs."
CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
del(CM.handcuffed)
CM.handcuffed = null
CM.update_inv_handcuffed()
else
var/obj/item/weapon/handcuffs/HC = CM.handcuffed
var/breakouttime = 1200 //A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
CM << "\red You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)"
for(var/mob/O in viewers(CM))
O.show_message( "\red <B>[usr] attempts to remove \the [HC]!</B>", 1)
spawn(0)
if(do_after(CM, breakouttime))
if(!CM.handcuffed || CM.buckled)
return // time leniency for lag which also might make this whole thing pointless but the server
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to remove the handcuffs!</B>", 1)
CM << "\blue You successfully remove \the [CM.handcuffed]."
CM.drop_from_inventory(CM.handcuffed)
CM.handcuffed = null
CM.update_inv_handcuffed()
else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time))
CM.next_move = world.time + 100
CM.last_special = world.time + 100
if(isalienadult(CM) || (HULK in usr.mutations))//Don't want to do a lot of logic gating here.
usr << "\red You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)"
for(var/mob/O in viewers(CM))
O.show_message(text("\red <B>[] is trying to break the legcuffs!</B>", CM), 1)
spawn(0)
if(do_after(CM, 50))
if(!CM.legcuffed || CM.buckled)
return
for(var/mob/O in viewers(CM))
O.show_message(text("\red <B>[] manages to break the legcuffs!</B>", CM), 1)
CM << "\red You successfully break your legcuffs."
CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
del(CM.legcuffed)
CM.legcuffed = null
CM.update_inv_legcuffed()
else
var/obj/item/weapon/legcuffs/HC = CM.legcuffed
var/breakouttime = 1200 //A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future...
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
CM << "\red You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)"
for(var/mob/O in viewers(CM))
O.show_message( "\red <B>[usr] attempts to remove \the [HC]!</B>", 1)
spawn(0)
if(do_after(CM, breakouttime))
if(!CM.legcuffed || CM.buckled)
return // time leniency for lag which also might make this whole thing pointless but the server
for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink
O.show_message("\red <B>[CM] manages to remove the legcuffs!</B>", 1)
CM << "\blue You successfully remove \the [CM.legcuffed]."
CM.drop_from_inventory(CM.legcuffed)
CM.legcuffed = null
CM.update_inv_legcuffed()
/mob/living/verb/lay_down()
set name = "Rest"
set category = "IC"
resting = !resting
src << "\blue You are now [resting ? "resting" : "getting up"]"
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
return
if(lying)
src << "You can't vent crawl while you're stunned!"
return
if(vent_found) // one was passed in, probably from vent/AltClick()
if(vent_found.welded)
src << "That vent is welded shut."
return
if(!vent_found.Adjacent(src))
return // don't even acknowledge that
else
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
if(v.Adjacent(src))
vent_found = v
if(!vent_found)
src << "You'll need a non-welded vent to crawl into!"
return
if(!vent_found.network || !vent_found.network.normal_members.len)
src << "This vent is not connected to anything."
return
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
if(temp_vent.welded)
continue
if(temp_vent in loc)
continue
var/turf/T = get_turf(temp_vent)
if(!T || T.z != loc.z)
continue
var/i = 1
var/index = "[T.loc.name]\[[i]\]"
while(index in vents)
i++
index = "[T.loc.name]\[[i]\]"
vents[index] = temp_vent
if(!vents.len)
src << "\red There are no available vents to travel to, they could be welded."
return
var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents)
if(!selection) return
if(!vent_found.Adjacent(src))
src << "Never mind, you left."
return
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
src << "\red You can't be carrying items or have items equipped when vent crawling!"
return
if(isslime(src))
var/mob/living/carbon/slime/S = src
if(S.Victim)
src << "\red You'll have to let [S.Victim] go or finish eating \him first."
return
var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection]
if(!target_vent)
return
for(var/mob/O in viewers(src, null))
O.show_message(text("<B>[src] scrambles into the ventillation ducts!</B>"), 1)
loc = target_vent
var/travel_time = round(get_dist(loc, target_vent.loc) / 2)
spawn(travel_time)
if(!target_vent) return
for(var/mob/O in hearers(target_vent,null))
O.show_message("You hear something squeezing through the ventilation ducts.",2)
sleep(travel_time)
if(!target_vent) return
if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled.
target_vent = vent_found //travel back. No additional time required.
src << "\red The vent you were heading to appears to be welded."
loc = target_vent.loc
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
+128
View File
@@ -0,0 +1,128 @@
/*
run_armor_check(a,b)
args
a:def_zone - What part is getting hit, if null will check entire body
b:attack_flag - What type of attack, bullet, laser, energy, melee
Returns
0 - no block
1 - halfblock
2 - fullblock
*/
/mob/living/proc/run_armor_check(var/def_zone = null, var/attack_flag = "melee", var/absorb_text = null, var/soften_text = null)
var/armor = getarmor(def_zone, attack_flag)
var/absorb = 0
if(prob(armor))
absorb += 1
if(prob(armor))
absorb += 1
if(absorb >= 2)
if(absorb_text)
show_message("[absorb_text]")
else
show_message("\red Your armor absorbs the blow!")
return 2
if(absorb == 1)
if(absorb_text)
show_message("[soften_text]",4)
else
show_message("\red Your armor softens the blow!")
return 1
return 0
/mob/living/proc/getarmor(var/def_zone, var/type)
return 0
/mob/living/bullet_act(var/obj/item/projectile/P, var/def_zone)
var/obj/item/weapon/cloaking_device/C = locate((/obj/item/weapon/cloaking_device) in src)
if(C && C.active)
C.attack_self(src)//Should shut it off
update_icons()
src << "\blue Your [C.name] was disrupted!"
Stun(2)
flash_weak_pain()
if(istype(equipped(),/obj/item/device/assembly/signaler))
var/obj/item/device/assembly/signaler/signaler = equipped()
if(signaler.deadman && prob(80))
src.visible_message("\red [src] triggers their deadman's switch!")
signaler.signal()
var/absorb = run_armor_check(def_zone, P.flag)
if(absorb >= 2)
P.on_hit(src,2)
return 2
if(!P.nodamage)
apply_damage((P.damage/(absorb+1)), P.damage_type, def_zone, absorb, 0, P)
P.on_hit(src, absorb)
return absorb
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
if(istype(AM,/obj/))
var/obj/O = AM
var/zone = ran_zone("chest",75)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
if(istype(O,/obj/item/weapon))
var/obj/item/weapon/W = O
dtype = W.damtype
src.visible_message("\red [src] has been hit by [O].")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened hit to your [zone].")
if(armor < 2)
apply_damage(O.throwforce*(speed/5), dtype, zone, armor, O.sharp, O)
if(!O.fingerprintslast)
return
var/client/assailant = directory[ckey(O.fingerprintslast)]
if(assailant && assailant.mob && istype(assailant.mob,/mob))
var/mob/M = assailant.mob
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been hit with a thrown [O], last touched by [M.name] ([assailant.ckey])</font>")
M.attack_log += text("\[[time_stamp()]\] <font color='red'>Hit [src.name] ([src.ckey]) with a thrown [O]</font>")
if(!istype(src,/mob/living/simple_animal/mouse))
msg_admin_attack("[src.name] ([src.ckey]) was hit by a thrown [O], last touched by [M.name] ([assailant.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
// Begin BS12 momentum-transfer code.
if(speed >= 20)
var/obj/item/weapon/W = O
var/momentum = speed/2
var/dir = get_dir(M,src)
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
if(istype(W.loc,/mob/living) && W.sharp) //Projectile is embedded and suitable for pinning.
if(!istype(src,/mob/living/carbon/human)) //Handles embedding for non-humans and simple_animals.
O.loc = src
src.embedded += O
var/turf/T = near_wall(dir,2)
if(T)
src.loc = T
visible_message("<span class='warning'>[src] is pinned to the wall by [O]!</span>","<span class='warning'>You are pinned to the wall by [O]!</span>")
src.anchored = 1
src.pinned += O
/mob/living/proc/near_wall(var/direction,var/distance=1)
var/turf/T = get_step(get_turf(src),direction)
var/turf/last_turf = src.loc
var/i = 1
while(i>0 && i<=distance)
if(T.density) //Turf is a wall!
return last_turf
i++
last_turf = T
T = get_step(T,direction)
return 0
// End BS12 momentum-transfer code.
+38
View File
@@ -0,0 +1,38 @@
/mob/living
see_invisible = SEE_INVISIBLE_LIVING
//Health and life related vars
var/maxHealth = 100 //Maximum health that should be possible.
var/health = 100 //A mob's health
//Damage related vars, NOTE: THESE SHOULD ONLY BE MODIFIED BY PROCS
var/bruteloss = 0.0 //Brutal damage caused by brute force (punching, being clubbed by a toolbox ect... this also accounts for pressure damage)
var/oxyloss = 0.0 //Oxygen depravation damage (no air in lungs)
var/toxloss = 0.0 //Toxic damage caused by being poisoned or radiated
var/fireloss = 0.0 //Burn damage caused by being way too hot, too cold or burnt.
var/cloneloss = 0 //Damage caused by being cloned or ejected from the cloner early. slimes also deal cloneloss damage to victims
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
var/halloss = 0 //Hallucination damage. 'Fake' damage obtained through hallucinating or the holodeck. Sleeping should cause it to wear off.
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm
var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas.
var/t_plasma = null
var/t_oxygen = null
var/t_sl_gas = null
var/t_n2 = null
var/now_pushing = null
var/cameraFollow = null
var/tod = null // Time of death
var/update_slimes = 1
var/silent = null //Can't talk. Value goes down every life proc.
+57
View File
@@ -0,0 +1,57 @@
/mob/living/Login()
..()
//Mind updates
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
mind.active = 1 //indicates that the mind is currently synced with a client
//Round specific stuff like hud updates
if(ticker && ticker.mode)
switch(ticker.mode.name)
if("revolution")
if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries))
ticker.mode.update_rev_icons_added(src.mind)
if("cult")
if(mind in ticker.mode:cult)
ticker.mode.update_cult_icons_added(src.mind)
if("nuclear emergency")
if(mind in ticker.mode:syndicates)
ticker.mode.update_all_synd_icons()
return .
//This stuff needs to be merged from cloning.dm but I'm not in the mood to be shouted at for breaking all the things :< ~Carn
/* clones
switch(ticker.mode.name)
if("revolution")
if(src.occupant.mind in ticker.mode:revolutionaries)
ticker.mode:update_all_rev_icons() //So the icon actually appears
if(src.occupant.mind in ticker.mode:head_revolutionaries)
ticker.mode:update_all_rev_icons()
if("nuclear emergency")
if (src.occupant.mind in ticker.mode:syndicates)
ticker.mode:update_all_synd_icons()
if("cult")
if (src.occupant.mind in ticker.mode:cult)
ticker.mode:add_cultist(src.occupant.mind)
ticker.mode:update_all_cult_icons() //So the icon actually appears
*/
/* Plantpeople
switch(ticker.mode.name)
if ("revolution")
if (podman.mind in ticker.mode:revolutionaries)
ticker.mode:add_revolutionary(podman.mind)
ticker.mode:update_all_rev_icons() //So the icon actually appears
if (podman.mind in ticker.mode:head_revolutionaries)
ticker.mode:update_all_rev_icons()
if ("nuclear emergency")
if (podman.mind in ticker.mode:syndicates)
ticker.mode:update_all_synd_icons()
if ("cult")
if (podman.mind in ticker.mode:cult)
ticker.mode:add_cultist(podman.mind)
ticker.mode:update_all_cult_icons() //So the icon actually appears
if ("changeling")
if (podman.mind in ticker.mode:changelings)
podman.make_changeling()
*/
+7
View File
@@ -0,0 +1,7 @@
/mob/living/Logout()
..()
if (mind)
if(!key) //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.
if(!immune_to_ssd && sleeping < 2 && mind.active)
sleeping = 2 //This causes instant sleep, but does not prolong it. See life.dm for furthering SSD.
+452
View File
@@ -0,0 +1,452 @@
#define SAY_MINIMUM_PRESSURE 10
var/list/department_radio_keys = list(
":r" = "right ear", "#r" = "right ear", ".r" = "right ear",
":l" = "left ear", "#l" = "left ear", ".l" = "left ear",
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
":h" = "department", "#h" = "department", ".h" = "department",
":c" = "Command", "#c" = "Command", ".c" = "Command",
":n" = "Science", "#n" = "Science", ".n" = "Science",
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
":e" = "Engineering", "#e" = "Engineering", ".e" = "Engineering",
":s" = "Security", "#s" = "Security", ".s" = "Security",
":w" = "whisper", "#w" = "whisper", ".w" = "whisper",
":b" = "binary", "#b" = "binary", ".b" = "binary",
":a" = "alientalk", "#a" = "alientalk", ".a" = "alientalk",
":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate",
":u" = "Supply", "#u" = "Supply", ".u" = "Supply",
":g" = "changeling", "#g" = "changeling", ".g" = "changeling",
":R" = "right ear", "#R" = "right ear", ".R" = "right ear",
":L" = "left ear", "#L" = "left ear", ".L" = "left ear",
":I" = "intercom", "#I" = "intercom", ".I" = "intercom",
":H" = "department", "#H" = "department", ".H" = "department",
":C" = "Command", "#C" = "Command", ".C" = "Command",
":N" = "Science", "#N" = "Science", ".N" = "Science",
":M" = "Medical", "#M" = "Medical", ".M" = "Medical",
":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering",
":S" = "Security", "#S" = "Security", ".S" = "Security",
":W" = "whisper", "#W" = "whisper", ".W" = "whisper",
":B" = "binary", "#B" = "binary", ".B" = "binary",
":A" = "alientalk", "#A" = "alientalk", ".A" = "alientalk",
":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate",
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
":G" = "changeling", "#G" = "changeling", ".G" = "changeling",
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
":ê" = "right ear", "#ê" = "right ear", ".ê" = "right ear",
":ä" = "left ear", "#ä" = "left ear", ".ä" = "left ear",
":ø" = "intercom", "#ø" = "intercom", ".ø" = "intercom",
":ð" = "department", "#ð" = "department", ".ð" = "department",
":ñ" = "Command", "#ñ" = "Command", ".ñ" = "Command",
":ò" = "Science", "#ò" = "Science", ".ò" = "Science",
":ü" = "Medical", "#ü" = "Medical", ".ü" = "Medical",
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
":û" = "Security", "#û" = "Security", ".û" = "Security",
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
":è" = "binary", "#è" = "binary", ".è" = "binary",
":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk",
":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate",
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling"
)
/mob/living/proc/binarycheck()
if (istype(src, /mob/living/silicon/pai))
return
if (issilicon(src))
return 1
if (!ishuman(src))
return
var/mob/living/carbon/human/H = src
if (H.l_ear || H.r_ear)
var/obj/item/device/radio/headset/dongle
if(istype(H.l_ear,/obj/item/device/radio/headset))
dongle = H.l_ear
else
dongle = H.r_ear
if(!istype(dongle)) return
if(dongle.translate_binary) return 1
/mob/living/proc/hivecheck()
if (isalien(src)) return 1
if (!ishuman(src)) return
var/mob/living/carbon/human/H = src
if (H.l_ear || H.r_ear)
var/obj/item/device/radio/headset/dongle
if(istype(H.l_ear,/obj/item/device/radio/headset))
dongle = H.l_ear
else
dongle = H.r_ear
if(!istype(dongle)) return
if(dongle.translate_binary) return 1
/mob/living/say(var/message)
/*
Formatting and sanitizing.
*/
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
/*
Sanity checking and speech failure.
*/
if (!message)
return
if(silent)
return
if (stat == 2) // Dead.
return say_dead(message)
else if (stat) // Unconcious.
return
if (src.client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (muted)."
return
if (src.client.handle_spam_prevention(message, MUTE_IC))
return
// Mute disability
if (sdisabilities & MUTE)
return
// Muzzled.
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
// Emotes.
if (copytext(message, 1, 2) == "*" && !stat)
return emote(copytext(message, 2))
/*
Identity hiding.
*/
var/alt_name = ""
if (istype(src, /mob/living/carbon/human) && name != GetVoice())
var/mob/living/carbon/human/H = src
alt_name = " (as [H.get_id_name("Unknown")])"
/*
Now we get into the real meat of the say processing. Determining the message mode.
*/
var/italics = 0
var/message_range = null
var/message_mode = null
var/datum/language/speaking = null //For use if a specific language is being spoken.
var/braindam = getBrainLoss()
if (braindam >= 60)
if(prob(braindam/4))
message = stutter(message)
if(prob(braindam))
message = uppertext(message)
// General public key. Special message handling
else if (copytext(message, 1, 2) == ";" || prob(braindam/2))
if (ishuman(src))
message_mode = "headset"
else if(ispAI(src) || isrobot(src))
message_mode = "pAI"
message = copytext(message, 2)
// Begin checking for either a message mode or a language to speak.
else if (length(message) >= 2)
var/channel_prefix = copytext(message, 1, 3)
//Check if the person is speaking a language that they know.
if(languages.len)
for(var/datum/language/L in languages)
if(lowertext(channel_prefix) == ":[L.key]")
speaking = L
break
message_mode = department_radio_keys[channel_prefix]
if (message_mode || speaking || copytext(message,1,2) == ":")
message = trim(copytext(message, 3))
if (!(istype(src,/mob/living/carbon/human) || istype(src,/mob/living/carbon/monkey) || istype(src, /mob/living/simple_animal/parrot) || isrobot(src) && (message_mode=="department" || (message_mode in radiochannels))))
message_mode = null //only humans can use headsets
if(src.stunned > 2 || (traumatic_shock > 61 && prob(50)))
message_mode = null //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it
message = capitalize(trim_left(message))
if (!message)
return
if (stuttering)
message = stutter(message)
var/list/obj/item/used_radios = new
var/is_speaking_radio = 0
switch (message_mode)
if ("headset")
if (src:l_ear && istype(src:l_ear,/obj/item/device/radio))
src:l_ear.talk_into(src, message)
used_radios += src:l_ear
is_speaking_radio = 1
else if (src:r_ear)
src:r_ear.talk_into(src, message)
used_radios += src:r_ear
is_speaking_radio = 1
message_range = 1
italics = 1
if ("right ear")
if (src:r_ear)
src:r_ear.talk_into(src, message)
used_radios += src:r_ear
is_speaking_radio = 1
message_range = 1
italics = 1
if ("left ear")
if (src:l_ear)
src:l_ear.talk_into(src, message)
used_radios += src:l_ear
is_speaking_radio = 1
message_range = 1
italics = 1
if ("intercom")
for (var/obj/item/device/radio/intercom/I in view(1, null))
I.talk_into(src, message)
used_radios += I
is_speaking_radio = 1
message_range = 1
italics = 1
//I see no reason to restrict such way of whispering
if ("whisper")
whisper(message)
return
if ("binary")
if(robot_talk_understand || binarycheck())
//message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant
robot_talk(message)
return
if ("alientalk")
if(alien_talk_understand || hivecheck())
//message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) //seems redundant
alien_talk(message)
return
if ("department")
if(istype(src, /mob/living/carbon))
if (src:l_ear && istype(src:l_ear,/obj/item/device/radio))
src:l_ear.talk_into(src, message, message_mode)
used_radios += src:l_ear
is_speaking_radio = 1
if (src:r_ear)
src:r_ear.talk_into(src, message, message_mode)
used_radios += src:r_ear
is_speaking_radio = 1
else if(istype(src, /mob/living/silicon/robot))
if (src:radio)
src:radio.talk_into(src, message, message_mode)
used_radios += src:radio
message_range = 1
italics = 1
if ("pAI")
if (src:radio)
src:radio.talk_into(src, message)
used_radios += src:radio
message_range = 1
italics = 1
if("changeling")
if(mind && mind.changeling)
for(var/mob/Changeling in mob_list)
if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer))
Changeling << "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
return
////SPECIAL HEADSETS START
else
//world << "SPECIAL HEADSETS"
if (message_mode in radiochannels)
if(isrobot(src))//Seperates robots to prevent runtimes from the ear stuff
var/mob/living/silicon/robot/R = src
if(R.radio)//Sanityyyy
R.radio.talk_into(src, message, message_mode)
used_radios += R.radio
else
if (src:l_ear && istype(src:l_ear,/obj/item/device/radio))
src:l_ear.talk_into(src, message, message_mode)
used_radios += src:l_ear
else if (src:r_ear)
src:r_ear.talk_into(src, message, message_mode)
used_radios += src:r_ear
message_range = 1
italics = 1
/////SPECIAL HEADSETS END
var/datum/gas_mixture/environment = loc.return_air()
if(environment)
var/pressure = environment.return_pressure()
if (pressure < SAY_MINIMUM_PRESSURE) //in space no one can hear you scream
italics = 1
message_range = 1
var/list/listening
listening = get_mobs_in_view(message_range, src)
var/list/onscreen = viewers()
for(var/mob/M in player_list)
if (!M.client)
continue //skip monkeys and leavers
if (istype(M, /mob/new_player))
continue
if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && src.client) // src.client is so that ghosts don't have to listen to mice
listening|=M
var/turf/T = get_turf(src)
var/list/W = hear(message_range, T)
for (var/obj/O in ((W | contents)-used_radios))
W |= O
for (var/mob/M in W)
W |= M.contents
for (var/atom/A in W)
if(istype(A, /mob/living/simple_animal/parrot)) //Parrot speech mimickry
if(A == src)
continue //Dont imitate ourselves
var/mob/living/simple_animal/parrot/P = A
if(P.speech_buffer.len >= 10)
P.speech_buffer.Remove(pick(P.speech_buffer))
P.speech_buffer.Add(message)
if(istype(A, /obj/)) //radio in pocket could work, radio in backpack wouldn't --rastaf0
var/obj/O = A
spawn (0)
if(O && !istype(O.loc, /obj/item/weapon/storage))
O.hear_talk(src, message)
/* Commented out as replaced by code above from BS12
for (var/obj/O in ((V | contents)-used_radios)) //radio in pocket could work, radio in backpack wouldn't --rastaf0
spawn (0)
if (O)
O.hear_talk(src, message)
*/
/* if(isbrain(src))//For brains to properly talk if they are in an MMI..or in a brain. Could be extended to other mobs I guess.
for(var/obj/O in loc)//Kinda ugly but whatever.
if(O)
spawn(0)
O.hear_talk(src, message)
*/
var/list/heard_a = list() // understood us
var/list/heard_b = list() // didn't understand us
for (var/M in listening)
if(hascall(M,"say_understands"))
if (M:say_understands(src,speaking))
heard_a += M
else
heard_b += M
else
heard_a += M
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
spawn(30) del(speech_bubble)
for(var/mob/M in hearers(5, src))
if(M != src && is_speaking_radio)
M:show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "radio"]</span>")
var/rendered = null
if (length(heard_a))
var/message_a = say_quote(message,speaking)
if (italics)
message_a = "<i>[message_a]</i>"
var/message_ghost = "<b>[message_a]</b>" // bold so ghosts know the person is in view.
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_a]</span></span>"
var/rendered_ghost = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_ghost]</span></span>"
for (var/mob/M in heard_a)
if(hascall(M,"show_message"))
var/deaf_message = ""
var/deaf_type = 1
if(M != src)
deaf_message = "<span class='name'>[name]</span>[alt_name] talks but you cannot hear them."
else
deaf_message = "<span class='notice'>You cannot hear yourself!</span>"
deaf_type = 2 // Since you should be able to hear yourself without looking
if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen)
M:show_message(rendered_ghost, 2, deaf_message, deaf_type)
else
M:show_message(rendered, 2, deaf_message, deaf_type)
M << speech_bubble
if (length(heard_b))
var/message_b
message_b = stars(message)
message_b = say_quote(message_b,speaking)
if (italics)
message_b = "<i>[message_b]</i>"
rendered = "<span class='game say'><span class='name'>[name]</span>[alt_name] <span class='message'>[message_b]</span></span>" //Voice_name isn't too useful. You'd be able to tell who was talking presumably.
for (var/M in heard_b)
if(hascall(M,"show_message"))
M:show_message(rendered, 2)
M << speech_bubble
/*
if(M.client)
if(!M.client.bubbles || M == src)
var/image/I = image('icons/effects/speechbubble.dmi', B, "override")
I.override = 1
M << I
*/ /*
flick("[presay]say", B)
if(istype(loc, /turf))
B.loc = loc
else
B.loc = loc.loc
spawn()
sleep(11)
del(B)
*/
//talking items
for(var/obj/item/weapon/O in view(3,src))
if(O.listening_to_players)
O.catchMessage(message, src)
log_say("[name]/[key] : [message]")
/obj/effect/speech_bubble
var/mob/parent
/mob/living/proc/GetVoice()
return name

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