GIT IS HITLER

This commit is contained in:
suethecake
2014-12-18 13:08:42 -06:00
179 changed files with 13506 additions and 8789 deletions
+11 -10
View File
@@ -145,8 +145,8 @@ var/global/floorIsLava = 0
else if(ishuman(M))
body += {"<A href='?src=\ref[src];makeai=\ref[M]'>Make AI</A> |
<A href='?src=\ref[src];makerobot=\ref[M]'>Make Robot</A> |
<A href='?src=\ref[src];makealien=\ref[M]'>Make Alien</A> |
<A href='?src=\ref[src];makeslime=\ref[M]'>Make slime</A>
<A href='?src=\ref[src];makeslime=\ref[M]'>Make slime</A> |
<A href='?src=\ref[src];makealien=\ref[M]'>Make Alien(BROKEN)</A> |
"}
//Simple Animals
@@ -156,7 +156,7 @@ var/global/floorIsLava = 0
body += "<A href='?src=\ref[src];makeanimal=\ref[M]'>Animalize</A> | "
// DNA2 - Admin Hax
if(iscarbon(M))
if(M.dna && iscarbon(M))
body += "<br><br>"
body += "<b>DNA Blocks:</b><br><table border='2'><tr><th>&nbsp;</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th>"
var/bname
@@ -189,19 +189,20 @@ var/global/floorIsLava = 0
<A href='?src=\ref[src];simplemake=corgi;mob=\ref[M]'>Corgi</A> |
<A href='?src=\ref[src];simplemake=ian;mob=\ref[M]'>Ian</A> |
<A href='?src=\ref[src];simplemake=crab;mob=\ref[M]'>Crab</A> |
<A href='?src=\ref[src];simplemake=coffee;mob=\ref[M]'>Coffee</A><br>
<A href='?src=\ref[src];simplemake=coffee;mob=\ref[M]'>Coffee</A> |
<A href='?src=\ref[src];simplemake=nymph;mob=\ref[M]'>Nymph</A><br>
Construct: <A href='?src=\ref[src];simplemake=constructarmoured;mob=\ref[M]'>Armoured</A> |
<A href='?src=\ref[src];simplemake=constructbuilder;mob=\ref[M]'>Builder</A> |
<A href='?src=\ref[src];simplemake=constructwraith;mob=\ref[M]'>Wraith</A> |
<A href='?src=\ref[src];simplemake=shade;mob=\ref[M]'>Shade</A><br>
<br><b>Note from sound, Aliens are broken (Disabled)</b><br>
Alien: <A href='?src=\ref[src];simplemake=drone;mob=\ref[M]'>Drone</A> |
<A href='?src=\ref[src];simplemake=hunter;mob=\ref[M]'>Hunter</A> |
<A href='?src=\ref[src];simplemake=queen;mob=\ref[M]'>Queen</A> |
<A href='?src=\ref[src];simplemake=sentinel;mob=\ref[M]'>Sentinel</A> |
<A href='?src=\ref[src];simplemake=larva;mob=\ref[M]'>Larva</A><br>
Construct: <A href='?src=\ref[src];simplemake=constructarmoured;mob=\ref[M]'>Armoured</A> |
<A href='?src=\ref[src];simplemake=constructbuilder;mob=\ref[M]'>Builder</A> |
<A href='?src=\ref[src];simplemake=constructwraith;mob=\ref[M]'>Wraith</A> |
<A href='?src=\ref[src];simplemake=shade;mob=\ref[M]'>Shade</A>
<br>
"}
if (M.client)
+21 -2
View File
@@ -218,7 +218,8 @@ var/list/admin_verbs_debug = list(
/client/proc/SDQL2_query,
/client/proc/cmd_dev_reset_gravity,
/client/proc/cmd_dev_reset_floating,
/client/proc/fillspace
/client/proc/fillspace,
/client/proc/hide_activity
)
var/list/admin_verbs_possess = list(
/proc/possess,
@@ -1051,4 +1052,22 @@ var/list/admin_verbs_mod = list(
S.ChangeTurf(/turf/simulated/floor/plating)
if(A.name == "Space")
for(var/turf/space/S in range(2,usr))
S.ChangeTurf(/turf/simulated/floor/plating)
S.ChangeTurf(/turf/simulated/floor/plating)
/client/proc/hide_activity()
set category = "Preferences"
set name = "Hide Var Edits"
set desc = "Hide Var edit logs from devs"
if(!check_rights(R_DEBUG))
holder.hide_activity = 0
return
if(holder)
holder.hide_activity = !holder.hide_activity
if (holder.hide_activity)
usr << "Your varedits will now be hidden from developers"
else
usr << "Your varedits will now be shown to developers"
return
+1
View File
@@ -12,6 +12,7 @@ var/list/admin_datums = list()
var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders.
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
var/admincaster_signature //What you'll sign the newsfeeds as
var/hide_activity = 0
/datum/admins/New(initial_rank = "Temporary Admin", initial_rights = 0, ckey)
if(!ckey)
+7 -6
View File
@@ -288,13 +288,14 @@
switch(href_list["simplemake"])
if("observer") M.change_mob_type( /mob/dead/observer , null, null, delmob )
if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob )
if("hunter") M.change_mob_type( /mob/living/carbon/alien/humanoid/hunter , null, null, delmob )
if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen , null, null, delmob )
if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob )
if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob )
// if("drone") M.change_mob_type( /mob/living/carbon/alien/humanoid/drone , null, null, delmob )
// if("hunter") M.change_mob_type( /mob/living/carbon/alien/humanoid/hunter , null, null, delmob )
// if("queen") M.change_mob_type( /mob/living/carbon/alien/humanoid/queen , null, null, delmob )
// if("sentinel") M.change_mob_type( /mob/living/carbon/alien/humanoid/sentinel , null, null, delmob )
// if("larva") M.change_mob_type( /mob/living/carbon/alien/larva , null, null, delmob )
if("nymph") M.change_mob_type( /mob/living/carbon/alien/diona , null, null, delmob )
if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob )
if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob )
if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob )
if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob )
if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob )
if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob )
+1 -1
View File
@@ -373,4 +373,4 @@
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1)
msg_scopes("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1)//Tell the devs
msg_scopes("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1, 0, src)//Tell the devs
+1 -1
View File
@@ -504,4 +504,4 @@ var/list/forbidden_varedit_object_types = list(
world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1)
msg_scopes("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1) // Tell dev's to but not log twice
msg_scopes("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]", 1, 0, src) // Tell dev's to but not log twice
+4 -4
View File
@@ -104,13 +104,13 @@
special_assembly.HasProximity(AM)
HasEntered(atom/movable/AM as mob|obj)
Crossed(atom/movable/AM as mob|obj)
if(a_left)
a_left.HasEntered(AM)
a_left.Crossed(AM)
if(a_right)
a_right.HasEntered(AM)
a_right.Crossed(AM)
if(special_assembly)
special_assembly.HasEntered(AM)
special_assembly.Crossed(AM)
on_found(mob/finder as mob)
+1 -1
View File
@@ -251,7 +251,7 @@
hit()
return
/obj/effect/beam/i_beam/HasEntered(atom/movable/AM as mob|obj)
/obj/effect/beam/i_beam/Crossed(atom/movable/AM as mob|obj)
if(istype(AM, /obj/effect/beam))
return
spawn(0)
+1 -1
View File
@@ -81,7 +81,7 @@
..()
HasEntered(AM as mob|obj)
Crossed(AM as mob|obj)
if(armed)
if(ishuman(AM))
var/mob/living/carbon/H = AM
+46 -6
View File
@@ -10,6 +10,10 @@
*/
var/list/sprite_sheets_refit = null
//Updates the icons of the mob wearing the clothing item, if any.
/obj/item/clothing/proc/update_clothing_icon()
return
//BS12: Species-restricted clothing check.
/obj/item/clothing/mob_can_equip(M as mob, slot)
@@ -121,6 +125,11 @@
if(istype(src,/obj/item/clothing/ears/offear))
del(src)
/obj/item/clothing/ears/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_ears()
/obj/item/clothing/ears/offear
name = "Other ear"
w_class = 5.0
@@ -163,6 +172,10 @@ SEE_PIXELS// if an object is located on an unlit area, but some of its pixels ar
BLIND // can't see anything
*/
/obj/item/clothing/glasses/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_glasses()
//Gloves
/obj/item/clothing/gloves
@@ -185,6 +198,11 @@ BLIND // can't see anything
..()
return
/obj/item/clothing/gloves/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_gloves()
/obj/item/clothing/gloves/emp_act(severity)
if(cell)
//why is this not part of the powercell code?
@@ -225,6 +243,12 @@ BLIND // can't see anything
slot_flags = SLOT_HEAD
w_class = 2.0
/obj/item/clothing/head/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_head()
///////////////////////////////////////////////////////////////////////
//Mask
/obj/item/clothing/mask
name = "mask"
@@ -234,7 +258,13 @@ BLIND // can't see anything
// body_parts_covered = FACE|EYES
sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi')
/obj/item/clothing/mask/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_wear_mask()
/obj/item/clothing/mask/proc/filter_air(datum/gas_mixture/air)
return
//Shoes
/obj/item/clothing/shoes
@@ -251,6 +281,10 @@ BLIND // can't see anything
species_restricted = list("exclude","Unathi","Tajaran")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/shoes.dmi')
/obj/item/clothing/shoes/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_shoes()
/obj/item/proc/negates_gravity()
return 0
@@ -269,6 +303,10 @@ BLIND // can't see anything
siemens_coefficient = 0.9
w_class = 3
/obj/item/clothing/suit/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_wear_suit()
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
@@ -361,6 +399,11 @@ BLIND // can't see anything
var/basecolor
sprite_sheets = list("Vox" = 'icons/mob/species/vox/uniform.dmi')
/obj/item/clothing/under/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_w_uniform()
/obj/item/clothing/under/attackby(obj/item/I, mob/user)
if(hastie)
hastie.attackby(I, user)
@@ -486,7 +529,7 @@ BLIND // can't see anything
if(basecolor + "_d_s" in icon_states('icons/mob/uniform.dmi'))
body_parts_covered = "[basecolor]" ? LEGS|LOWER_TORSO : UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
item_color = item_color == "[basecolor]" ? "[basecolor]_d" : "[basecolor]"
usr.update_inv_w_uniform()
update_clothing_icon()
if(rolled_down)
usr << "You roll [src] up"
rolled_down = 0
@@ -509,7 +552,7 @@ BLIND // can't see anything
basecolor = item_color
if(basecolor + "_r_s" in icon_states('icons/mob/uniform.dmi'))
item_color = item_color == "[basecolor]" ? "[basecolor]_r" : "[basecolor]"
usr.update_inv_w_uniform()
update_clothing_icon()
if(rolled_sleeves)
usr << "You roll [src] sleeves down"
rolled_sleeves = 0
@@ -527,10 +570,7 @@ BLIND // can't see anything
hastie.on_removed(user)
hastie = null
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
update_clothing_icon()
/obj/item/clothing/under/verb/removetie()
set name = "Remove Accessory"
+47
View File
@@ -9,15 +9,38 @@
//var/darkness_view = 0//Base human is 2
//var/invisa_view = 0
var/prescription = 0
var/toggleable = 0
var/active = 1
var/obj/screen/overlay = null
body_parts_covered = EYES
/obj/item/clothing/glasses/attack_self(mob/user)
if(toggleable)
if(active)
active = 0
icon_state = "degoggles"
user.update_inv_glasses()
usr << "You deactivate the optical matrix on the [src]."
else
active = 1
icon_state = initial(icon_state)
user.update_inv_glasses()
usr << "You activate the optical matrix on the [src]."
/obj/item/clothing/glasses/meson
name = "Optical Meson Scanner"
desc = "Used for seeing walls, floors, and stuff through anything."
icon_state = "meson"
item_state = "glasses"
icon_action_button = "action_meson" //This doesn't actually matter, the action button is generated from the current icon_state. But, this is the only way to get it to show up.
origin_tech = "magnets=2;engineering=2"
toggleable = 1
vision_flags = SEE_TURFS
/obj/item/clothing/glasses/meson/New()
..()
overlay = global_hud.meson
/obj/item/clothing/glasses/meson/prescription
name = "prescription mesons"
desc = "Optical Meson Scanner with prescription lenses."
@@ -37,24 +60,32 @@
origin_tech = "magnets=2"
darkness_view = 7
/obj/item/clothing/glasses/night/New()
..()
overlay = global_hud.nvg
/obj/item/clothing/glasses/eyepatch
name = "eyepatch"
desc = "Yarr."
icon_state = "eyepatch"
item_state = "eyepatch"
body_parts_covered = 0
/obj/item/clothing/glasses/monocle
name = "monocle"
desc = "Such a dapper eyepiece!"
icon_state = "monocle"
item_state = "headset" // lol
body_parts_covered = 0
/obj/item/clothing/glasses/material
name = "Optical Material Scanner"
desc = "Very confusing glasses."
icon_state = "material"
item_state = "glasses"
icon_action_button = "action_material"
origin_tech = "magnets=3;engineering=3"
toggleable = 1
vision_flags = SEE_OBJS
/obj/item/clothing/glasses/regular
@@ -63,6 +94,7 @@
icon_state = "glasses"
item_state = "glasses"
prescription = 1
body_parts_covered = 0
/obj/item/clothing/glasses/regular/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/clothing/glasses/hud/health))
@@ -93,12 +125,14 @@
name = "3D glasses"
icon_state = "3d"
item_state = "3d"
body_parts_covered = 0
/obj/item/clothing/glasses/gglasses
name = "Green Glasses"
desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme."
icon_state = "gglasses"
item_state = "gglasses"
body_parts_covered = 0
/obj/item/clothing/glasses/sunglasses
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes."
@@ -130,12 +164,14 @@
src.up = !src.up
src.flags |= GLASSESCOVERSEYES
flags_inv |= HIDEEYES
body_parts_covered |= EYES
icon_state = initial(icon_state)
usr << "You flip \the [src] down to protect your eyes."
else
src.up = !src.up
src.flags &= ~HEADCOVERSEYES
flags_inv &= ~HIDEEYES
body_parts_covered &= ~EYES
icon_state = "[initial(icon_state)]up"
usr << "You push \the [src] up out of your face."
@@ -186,6 +222,7 @@
icon_state = "thermal"
item_state = "glasses"
origin_tech = "magnets=3"
toggleable = 1
vision_flags = SEE_MOBS
invisa_view = 2
@@ -201,10 +238,15 @@
M.disabilities &= ~NEARSIGHTED
..()
/obj/item/clothing/glasses/thermal/New()
..()
overlay = global_hud.thermal
/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete
name = "Optical Meson Scanner"
desc = "Used for seeing walls, floors, and stuff through anything."
icon_state = "meson"
icon_action_button = "action_meson"
origin_tech = "magnets=3;syndicate=4"
/obj/item/clothing/glasses/thermal/monocle
@@ -212,15 +254,20 @@
desc = "A monocle thermal."
icon_state = "thermoncle"
flags = null //doesn't protect eyes because it's a monocle, duh
toggleable = 0
body_parts_covered = 0
/obj/item/clothing/glasses/thermal/eyepatch
name = "Optical Thermal Eyepatch"
desc = "An eyepatch with built-in thermal optics"
icon_state = "eyepatch"
item_state = "eyepatch"
toggleable = 0
body_parts_covered = 0
/obj/item/clothing/glasses/thermal/jensen
name = "Optical Thermal Implants"
desc = "A set of implantable lenses designed to augment your vision"
icon_state = "thermalimplants"
item_state = "syringe_kit"
toggleable = 0
+4 -22
View File
@@ -14,18 +14,11 @@
name = "Health Scanner HUD"
desc = "A heads-up display that scans the humans in view and provides accurate data about their health status."
icon_state = "healthhud"
body_parts_covered = 0
/obj/item/clothing/glasses/hud/health/process_hud(var/mob/M)
if(!M) return
if(!M.client) return
var/client/C = M.client
for(var/mob/living/carbon/human/patient in view(get_turf(M)))
if(M.see_invisible < patient.invisibility)
continue
C.images += patient.hud_list[HEALTH_HUD]
C.images += patient.hud_list[STATUS_HUD]
process_med_hud(M, 1)
/obj/item/clothing/glasses/hud/health/prescription
name = "prescription glasses/HUD assembly"
@@ -46,6 +39,7 @@
name = "Security HUD"
desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records."
icon_state = "securityhud"
body_parts_covered = 0
var/global/list/jobs[0]
/obj/item/clothing/glasses/hud/security/prescription
@@ -72,16 +66,4 @@
invisa_view = 2
/obj/item/clothing/glasses/hud/security/process_hud(var/mob/M)
if(!M) return
if(!M.client) return
var/client/C = M.client
for(var/mob/living/carbon/human/perp in view(get_turf(M)))
if(M.see_invisible < perp.invisibility)
continue
if(!C) continue
C.images += perp.hud_list[ID_HUD]
C.images += perp.hud_list[WANTED_HUD]
C.images += perp.hud_list[IMPTRACK_HUD]
C.images += perp.hud_list[IMPLOYAL_HUD]
C.images += perp.hud_list[IMPCHEM_HUD]
process_sec_hud(M, 1)
+2 -1
View File
@@ -292,6 +292,7 @@
icon_state = "tool_flask"
volume = 60
/*
/obj/item/weapon/melee/baton/fluff/omnivac_baton //Tiger Claw - Zander Moon - omnivac - DONE
name = "Tiger Claw"
desc = "A small energy dagger given to Golden Tigers meant to incapacitate people quickly."
@@ -325,7 +326,7 @@
status = 0
user << "<span class='warning'>\The [src] is out of charge.</span>"
add_fingerprint(user)
*/
/*
/obj/item/device/modkit/fluff/omnivac_modkit //Ornate box - Zander Moon - omnivac - SPRITE
name = "ornate box"
+1 -1
View File
@@ -252,7 +252,7 @@ proc/check_panel(mob/M)
return
HasEntered(var/mob/M, somenumber)
Crossed(var/mob/M, somenumber)
if(M == my_target)
step_away(src,my_target,2)
if(prob(30))
+10 -1
View File
@@ -49,9 +49,18 @@ obj/machinery/cooker/proc/checkValid(obj/item/check, mob/user)
/* if(istype(check, /obj/item/flag))
user << "<span class='warning'>That isn't going to fit.</span>"
return 0*/
if(!istype(check, /obj/item/weapon/reagent_containers/food))
if(!istype(check, /obj/item/weapon/reagent_containers/food/snacks))
user << "<span class='warning'>That isn't going to work.</span>"
return 0
if(istype(check, /obj/item/weapon/reagent_containers/food/snacks/customizable/candy))
user << "<span class='warning'>That would probably break [src].</span>"
return 0
if(istype(check, /obj/item/weapon/reagent_containers/food/snacks/cereal))
user << "<span class='warning'>That isn't going to fit.</span>"
return 0
if(istype(check, /obj/item/weapon/reagent_containers/food/snacks/deepfryholder))
user << "<span class='userdanger'>You cannot cook this twice.</span>"
return 0
return 1
obj/machinery/cooker/proc/setIcon(obj/item/copyme, obj/item/copyto)
+11 -1
View File
@@ -16,13 +16,23 @@
updatefood()
/obj/machinery/cooking/attackby(obj/item/I, mob/user)
if(on)
user << "The machine is already running."
return
else
if(!istype(I, /obj/item/weapon/reagent_containers/food))
if(!istype(I, /obj/item/weapon/reagent_containers/food/snacks))
user << "You think yourself better than to place [I] in there"
return
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/deepfryholder))
user << "<span class='userdanger'>You cannot cook this twice.</span>"
return
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/customizable/candy))
user << "<span class='warning'>That would probably taste bad.</span>"
return
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/cereal))
user << "<span class='warning'>That isn't going to be nice.</span>"
return
var/obj/item/F = I
var/obj/item/weapon/reagent_containers/food/snacks/customizable/C
+2 -2
View File
@@ -135,7 +135,7 @@ I said no!
/datum/recipe/brainburger
items = list(
/obj/item/weapon/reagent_containers/food/snacks/bun,
/obj/item/brain
/obj/item/organ/brain
)
result = /obj/item/weapon/reagent_containers/food/snacks/brainburger
@@ -1071,7 +1071,7 @@ I said no!
/obj/item/weapon/reagent_containers/food/snacks/egg,
/obj/item/weapon/reagent_containers/food/snacks/egg,
/obj/item/weapon/reagent_containers/food/snacks/egg,
/obj/item/brain
/obj/item/organ/brain
)
result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake
+2 -2
View File
@@ -270,11 +270,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
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)
if(config.antag_hud_restricted && !M.has_enabled_antagHUD && !(client.holder.rights & (R_ADMIN|R_MOD)))
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)
if(!M.has_enabled_antagHUD && !(client.holder.rights & (R_ADMIN|R_MOD)))
M.has_enabled_antagHUD = 1
if(M.antagHUD)
M.antagHUD = 0
+30 -6
View File
@@ -14,12 +14,12 @@
return
var/style = "body"
//non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet.
if (language && (language.flags & NONVERBAL))
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
message = stars(message)
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
@@ -77,7 +77,7 @@
if (language && (language.flags & NONVERBAL))
if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src)))
message = stars(message)
if(!say_understands(speaker,language))
if(istype(speaker,/mob/living/simple_animal))
var/mob/living/simple_animal/S = speaker
@@ -164,9 +164,31 @@
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
if(!client)
return
if(sleeping || stat == 1)
return
var/speaker_name
var/alt_name
// var/mob/S = speaker
// if(!S && !S.head && !istype(S.head, /obj/item/clothing/head/helmet))
speaker_name = speaker.real_name
// else
// speaker_name = "unknown"
var/track = null
if(istype(src, /mob/dead/observer))
if(speaker_name != speaker.real_name && speaker.real_name)
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "(<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>) "
if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
message = "<b>[message]</b>"
if(say_understands(speaker, language))
message = "<B>[speaker.real_name]</B> [verb], \"[message]\""
message = "<span class='game say'><span class='name'>[speaker.real_name]</span>[alt_name] [track][verb], <span class='message'>\"[message]\"</span></span>"
else
message = "<B>[speaker.real_name]</B> gestures."
@@ -175,7 +197,9 @@
H.show_message(message)
for(var/mob/living/M in src.contents)
M.show_message(message)
src.show_message(message)
src << message
////////////////////////////////////////////////////////////////////////
/mob/proc/hear_sleep(var/message)
var/heard = ""
+193
View File
@@ -6,16 +6,49 @@
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/ask_verb = "asks" // Used when sentence ends in a ?
var/exclaim_verb = "exclaims" // Used when sentence ends in a !
var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
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/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
log_say("[key_name(speaker)] : ([name]) [message]")
for(var/mob/player in player_list)
var/understood = 0
if(istype(player,/mob/dead))
understood = 1
else if((src in player.languages) && check_special_condition(player))
understood = 1
if(understood)
if(!speaker_mask) speaker_mask = speaker.name
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> <span class='message'>[speech_verb], \"<span class='[colour]'>[message]</span><span class='message'>\"</span></span></i>"
player << "[msg]"
/datum/language/proc/check_special_condition(var/mob/other)
return 1
/datum/language/proc/get_spoken_verb(var/msg_end)
switch(msg_end)
if("!")
return exclaim_verb
if("?")
return ask_verb
return speech_verb
/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"
ask_verb = "hisses"
exclaim_verb = "roars"
colour = "soghun"
key = "o"
flags = WHITELISTED
@@ -24,6 +57,8 @@
name = "Siik'Maas"
desc = "An expressive language that combines yowls and chirps with posture, tail and ears. Native to the Tajaran."
speech_verb = "mrowls"
ask_verb = "mrowls"
exclaim_verb = "yowls"
colour = "tajaran"
key = "j"
flags = WHITELISTED
@@ -32,6 +67,8 @@
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"
ask_verb = "warbles"
exclaim_verb = "warbles"
colour = "skrell"
key = "k"
flags = WHITELISTED
@@ -40,6 +77,8 @@
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"
ask_verb = "creels"
exclaim_verb = "SHRIEKS"
colour = "vox"
key = "v"
flags = RESTRICTED
@@ -48,10 +87,27 @@
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"
ask_verb = "creaks"
exclaim_verb = "rustles"
colour = "soghun"
key = "q"
flags = RESTRICTED
/datum/language/common
name = "Ceti Basic"
desc = "The common galactic tongue."
speech_verb = "says"
key = "0"
flags = RESTRICTED
/datum/language/common/get_spoken_verb(var/msg_end)
switch(msg_end)
if("!")
return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs.
if("?")
return ask_verb
return speech_verb
/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."
@@ -90,6 +146,143 @@
key = "4"
flags = SIGNLANG
////////////////////////////////////
//Not sure if stuff but yeah
////////////////////////////////////
/datum/language/xenocommon
name = "Xenomorph"
colour = "alien"
desc = "The common tongue of the xenomorphs."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
key = "5"
flags = RESTRICTED
/datum/language/xenos
name = "Hivemind"
desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
colour = "alien"
key = "a"
flags = RESTRICTED | HIVEMIND
/datum/language/xenos/check_special_condition(var/mob/other)
var/mob/living/carbon/M = other
if(!istype(M))
return 1
if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs)
return 1
return 0
/datum/language/ling
name = "Changeling"
desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance."
speech_verb = "says"
colour = "changeling"
key = "g"
flags = RESTRICTED | HIVEMIND
/datum/language/ling/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
if(speaker.mind && speaker.mind.changeling)
..(speaker,message,speaker.mind.changeling.changelingID)
else
..(speaker,message)
/datum/language/corticalborer
name = "Cortical Link"
desc = "Cortical borers possess a strange link between their tiny minds."
speech_verb = "sings"
ask_verb = "sings"
exclaim_verb = "sings"
colour = "alien"
key = "x"
flags = RESTRICTED | HIVEMIND
/datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
var/mob/living/simple_animal/borer/B
if(istype(speaker,/mob/living/carbon))
var/mob/living/carbon/M = speaker
B = M.has_brain_worms()
else if(istype(speaker,/mob/living/simple_animal/borer))
B = speaker
if(B)
speaker_mask = B.truename
..(speaker,message,speaker_mask)
/datum/language/binary
name = "Robot Talk"
desc = "Most human stations support free-use communications protocols and routing hubs for synthetic use."
colour = "say_quote"
speech_verb = "states"
ask_verb = "queries"
exclaim_verb = "declares"
key = "b"
flags = RESTRICTED | HIVEMIND
var/drone_only
/datum/language/binary/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
if(!speaker.binarycheck())
return
if (!message)
return
var/message_start = "<i><span class='game say'>[name], <span class='name'>[speaker.name]</span>"
var/message_body = "<span class='message'>[speaker.say_quote(message)], \"[message]\"</span></span></i>"
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
M.show_message("[message_start] [message_body]", 2)
for (var/mob/living/S in living_mob_list)
if(drone_only && !istype(S,/mob/living/silicon/robot/drone))
continue
else if(istype(S , /mob/living/silicon/ai))
message_start = "<i><span class='game say'>[name], <a href='byond://?src=\ref[S];track2=\ref[S];track=\ref[src];trackname=[html_encode(speaker.name)]'><span class='name'>[speaker.name]</span></a>"
else if (!S.binarycheck())
continue
S.show_message("[message_start] [message_body]", 2)
var/list/listening = hearers(1, src)
listening -= src
for (var/mob/living/M in listening)
if(istype(M, /mob/living/silicon) || M.binarycheck())
continue
M.show_message("<i><span class='game say'><span class='name'>synthesised voice</span> <span class='message'>beeps, \"beep beep beep\"</span></span></i>",2)
/*
//robot binary xmitter component power usage
if (isrobot(speaker))
var/mob/living/silicon/robot/R = speaker
var/datum/robot_component/C = R.components["comms"]
R.cell_use_power(C.active_usage)
*/
/datum/language/binary/drone
name = "Drone Talk"
desc = "A heavily encoded damage control coordination stream."
speech_verb = "transmits"
ask_verb = "transmits"
exclaim_verb = "transmits"
colour = "say_quote"
key = "d"
flags = RESTRICTED | HIVEMIND
drone_only = 1
///////////////////////////////////////
//Yeah but stuff if sure not
///////////////////////////////////////
// Language handling.
/mob/proc/add_language(var/language)
+47 -201
View File
@@ -1,213 +1,59 @@
#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")
desc = "What IS that?"
icon = 'icons/mob/alien.dmi'
icon_state = "alien"
pass_flags = PASSTABLE
melee_damage_lower = 1
melee_damage_upper = 3
attacktext = "bites"
attack_sound = null
friendly = "nuzzles"
wall_smash = 0
health = 100
maxHealth = 100
var/adult_form
var/dead_icon
var/amount_grown = 0
var/max_grown = 10
var/time_of_birth
var/language
/mob/living/carbon/alien/New()
time_of_birth = world.time
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
name = "[initial(name)] ([rand(1, 1000)])"
real_name = name
regenerate_icons()
if(language)
add_language(language)
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 plasma
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/handle_fire()//Aliens on fire code
if(..())
return
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
return
/mob/living/carbon/alien/IsAdvancedToolUser()
return has_fine_manipulation
/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)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
stat(null, eta_status)
/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
/mob/living/carbon/alien/u_equip(obj/item/W as obj)
return
/mob/living/carbon/alien/getDNA()
return null
/mob/living/carbon/alien/Stat()
..()
stat(null, "Progress: [amount_grown]/[max_grown]")
/mob/living/carbon/alien/setDNA()
return
/mob/living/carbon/alien/restrained()
return 0
/*----------------------------------------
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
/mob/living/carbon/alien/show_inv(mob/user as mob)
return //Consider adding cuffs and hats to this, for the sake of fun.
/*----------------------------------------
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
/mob/living/carbon/alien/can_use_vents()
return
@@ -0,0 +1,183 @@
//There has to be a better way to define this shit. ~ Z
//can't equip anything
/mob/living/carbon/alien/attack_ui(slot_id)
return
/mob/living/carbon/alien/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/attack_animal(mob/living/M as mob)
if(istype(M,/mob/living/simple_animal))
var/mob/living/simple_animal/S = M
if(S.melee_damage_upper == 0)
S.emote("[S.friendly] [src]")
else
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[S]</B> [S.attacktext] [src]!", 1)
var/damage = rand(S.melee_damage_lower, S.melee_damage_upper)
adjustBruteLoss(damage)
S.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 [S.name] ([S.ckey])</font>")
updatehealth()
/mob/living/carbon/alien/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/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(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/alien/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
@@ -0,0 +1,56 @@
/mob/living/carbon/alien/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/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
+9 -37
View File
@@ -1,41 +1,13 @@
/mob/living/carbon/alien/gib()
death(1)
var/atom/movable/overlay/animation = null
monkeyizing = 1
canmove = 0
icon = null
invisibility = 101
/mob/living/carbon/alien/death(gibbed)
animation = new(loc)
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
if(stat == DEAD) return
if(healths) healths.icon_state = "health6"
stat = DEAD
flick("gibbed-a", animation)
xgibs(loc, viruses)
dead_mob_list -= src
if(dead_icon) icon_state = dead_icon
spawn(15)
if(animation) del(animation)
if(src) del(src)
if(!gibbed)
update_canmove()
if(client) blind.layer = 0
/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)
return ..(gibbed)
@@ -0,0 +1,25 @@
/mob/living/carbon/alien/diona
name = "diona nymph"
voice_name = "diona nymph"
adult_form = /mob/living/carbon/human
speak_emote = list("chirrups")
icon_state = "nymph"
language = "Rootspeak"
amount_grown = 0
max_grown = 5 // Target number of donors.
var/list/donors = list()
var/last_checked_stage = 0
universal_understand = 0 // Dionaea do not need to speak to people
universal_speak = 0 // before becoming an adult. Use *chirp.
holder_type = /obj/item/weapon/holder/diona
/mob/living/carbon/alien/diona/New()
..()
verbs += /mob/living/carbon/proc/eat_weeds
verbs += /mob/living/carbon/proc/fertilize_plant
verbs += /mob/living/carbon/alien/diona/proc/steal_blood
verbs += /mob/living/carbon/alien/diona/proc/merge
@@ -0,0 +1,14 @@
/mob/living/carbon/alien/diona/attack_hand(mob/living/carbon/human/M as mob)
//Let people pick the little buggers up.
if(M.a_intent == "help")
if(M.species && M.species.name == "Diona")
M << "You feel your being twine with that of [src] as it merges with your biomass."
src << "You feel your being twine with that of [M] as you merge with its biomass."
src.verbs += /mob/living/carbon/alien/diona/proc/split
src.verbs -= /mob/living/carbon/alien/diona/proc/merge
src.loc = M
else
get_scooped(M)
..()
@@ -0,0 +1,90 @@
//Verbs after this point.
/mob/living/carbon/alien/diona/proc/merge()
set category = "Abilities"
set name = "Merge with gestalt"
set desc = "Merge with another diona."
if(istype(src.loc,/mob/living/carbon))
src.verbs -= /mob/living/carbon/alien/diona/proc/merge
return
var/list/choices = list()
for(var/mob/living/carbon/C in view(1,src))
if(!(src.Adjacent(C)) || !(C.client)) continue
if(istype(C,/mob/living/carbon/human))
var/mob/living/carbon/human/D = C
if(D.species && D.species.name == "Diona")
choices += C
var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices
if(!M || !src || !(src.Adjacent(M))) return
if(istype(M,/mob/living/carbon/human))
M << "You feel your being twine with that of [src] as it merges with your biomass."
M.status_flags |= PASSEMOTES
src << "You feel your being twine with that of [M] as you merge with its biomass."
src.loc = M
src.verbs += /mob/living/carbon/alien/diona/proc/split
src.verbs -= /mob/living/carbon/alien/diona/proc/merge
else
return
/mob/living/carbon/alien/diona/proc/split()
set category = "Abilities"
set name = "Split from gestalt"
set desc = "Split away from your gestalt as a lone nymph."
if(!(istype(src.loc,/mob/living/carbon)))
src.verbs -= /mob/living/carbon/alien/diona/proc/split
return
src.loc << "You feel a pang of loss as [src] splits away from your biomass."
src << "You wiggle out of the depths of [src.loc]'s biomass and plop to the ground."
var/mob/living/M = src.loc
src.loc = get_turf(src)
src.verbs -= /mob/living/carbon/alien/diona/proc/split
src.verbs += /mob/living/carbon/alien/diona/proc/merge
if(istype(M))
for(var/atom/A in M.contents)
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
return
M.status_flags &= ~PASSEMOTES
/mob/living/carbon/alien/diona/proc/steal_blood()
set category = "Abilities"
set name = "Steal Blood"
set desc = "Take a blood sample from a suitable donor."
var/list/choices = list()
for(var/mob/living/carbon/human/H in oview(1,src))
if(src.Adjacent(H))
choices += H
var/mob/living/carbon/human/M = input(src,"Who do you wish to take a sample from?") in null|choices
if(!M || !src) return
if(M.species.flags & NO_BLOOD)
src << "\red That donor has no blood to take."
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
for(var/datum/language/L in M.languages)
languages |= L
spawn(25)
update_progression()
@@ -0,0 +1,20 @@
//Dionaea regenerate health and nutrition in light.
/mob/living/carbon/alien/diona/handle_environment(datum/gas_mixture/environment)
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
if(nutrition > 500)
nutrition = 500
if(light_amount > 2) //if there's enough light, heal
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
adjustOxyLoss(-1)
@@ -0,0 +1,40 @@
/mob/living/carbon/alien/diona/confirm_evolution()
if(!is_alien_whitelisted(src, "Diona") && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play as a full diona.")
return null
if(amount_grown < max_grown)
src << "You are not yet ready for your growth..."
return null
src.split()
if(istype(loc,/obj/item/weapon/holder/diona))
var/obj/item/weapon/holder/diona/L = loc
src.loc = L.loc
del(L)
src.visible_message("\red [src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.","\red You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.")
return "Diona"
/mob/living/carbon/alien/diona/show_evolution_blurb()
//TODO
return
/mob/living/carbon/alien/diona/update_progression()
amount_grown = donors.len
if(amount_grown <= last_checked_stage)
return
// Only fire off these messages once.
last_checked_stage = amount_grown
if(amount_grown == max_grown)
src << "\green You feel ready to move on to your next stage of growth."
else if(amount_grown == 3)
universal_understand = 1
src << "\green You feel your awareness expand, and realize you know how to understand 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,6 @@
/mob/living/carbon/alien/diona/say_understands(var/mob/other,var/datum/language/speaking = null)
if (istype(other, /mob/living/carbon/human) && !speaking)
if(languages.len >= 2) // They have sucked down some blood.
return 1
return ..()
@@ -0,0 +1,8 @@
/mob/living/carbon/alien/diona/update_icons()
if(stat == DEAD)
icon_state = "[initial(icon_state)]_dead"
else if(lying || resting || stunned)
icon_state = "[initial(icon_state)]_sleep"
else
icon_state = "[initial(icon_state)]"
@@ -0,0 +1,127 @@
/mob/living/carbon/alien/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("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("chirp")
message = "<B>The [src.name]</B> chirps!"
playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
m_type = 2
if("help")
src << "burp, chirp, 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
@@ -7,7 +7,7 @@
status_flags = CANPARALYSE
heal_rate = 5
plasma_rate = 20
var/move_delay_add = 0
/mob/living/carbon/alien/humanoid/queen/New()
var/datum/reagents/R = new/datum/reagents(100)
@@ -1,375 +1,20 @@
/mob/living/carbon/alien/larva
name = "alien larva"
real_name = "alien larva"
icon_state = "larva0"
pass_flags = PASSTABLE
adult_form = /mob/living/carbon/human
speak_emote = list("hisses")
icon_state = "larva"
language = "Hivemind"
melee_damage_lower = 3
melee_damage_upper = 6
amount_grown = 0
max_grown = 200
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(M.is_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) */
add_language("Xenomorph") //Bonus language.
internal_organs += new /datum/organ/internal/xenos/hivenode(src)
@@ -1,369 +1,12 @@
//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 phoron in our breath
var/Toxins_pp = (breath.gas["toxins"] / breath.total_moles) * breath_pressure
if(Toxins_pp) // Detect toxins in air
adjustToxLoss(breath.gas["toxins"] * 250)
toxins_alert = max(toxins_alert, 1)
toxins_used = breath.gas["toxins"]
else
toxins_alert = 0
//Breathe in toxins and out oxygen
breath.adjust_gas("toxins", -toxins_used)
breath.adjust_gas("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
handle_statuses()
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
//Larvae regenerate health and nutrition from plasma and alien weeds.
/mob/living/carbon/alien/larva/handle_environment(var/datum/gas_mixture/environment)
if(!environment) return
var/turf/T = get_turf(src)
if(environment.gas["phoron"] > 0 || (T && locate(/obj/effect/alien/weeds) in T.contents))
update_progression()
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
adjustOxyLoss(-1)
@@ -0,0 +1,17 @@
/mob/living/carbon/alien/larva/update_progression()
if(amount_grown < max_grown)
amount_grown++
return
/mob/living/carbon/alien/larva/confirm_evolution()
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")
return alien_caste ? "Xenomorph [alien_caste]" : null
/mob/living/carbon/alien/larva/show_evolution_blurb()
return
@@ -0,0 +1,191 @@
// Alien larva are quite simple.
/mob/living/carbon/alien/Life()
set invisibility = 0
set background = 1
if (monkeyizing) return
if(!loc) return
..()
if (stat != DEAD) //still breathing
// GROW!
update_progression()
// Radiation.
handle_mutations_and_radiation()
// Chemicals in the body
handle_chemicals_in_body()
blinded = null
if(loc)
handle_environment(loc.return_air())
//Status updates, death etc.
handle_regular_status_updates()
update_canmove()
update_icons()
if(client)
handle_regular_hud_updates()
/mob/living/carbon/alien/proc/handle_chemicals_in_body()
return // Nothing yet. Maybe check it out at a later date.
/mob/living/carbon/alien/proc/handle_mutations_and_radiation()
// Currently both Dionaea and larvae like to eat radiation, so I'm defining the
// rad absorbtion here. This will need to be changed if other baby aliens are added.
if(!radiation)
return
var/rads = radiation/25
radiation -= rads
nutrition += rads
heal_overall_damage(rads,rads)
adjustOxyLoss(-(rads))
adjustToxLoss(-(rads))
return
/mob/living/carbon/alien/proc/handle_regular_status_updates()
if(status_flags & GODMODE) return 0
if(stat == DEAD)
blinded = 1
silent = 0
else
updatehealth()
if(health <= 0)
death()
blinded = 1
silent = 0
return 1
if(paralysis)
AdjustParalysis(-1)
blinded = 1
stat = UNCONSCIOUS
if(halloss > 0)
adjustHalLoss(-3)
else if(sleeping)
adjustHalLoss(-3)
if (mind)
if((mind.active && client != null) || immune_to_ssd)
sleeping = max(sleeping-1, 0)
blinded = 1
stat = UNCONSCIOUS
else if(resting)
if(halloss > 0)
adjustHalLoss(-3)
else
stat = CONSCIOUS
if(halloss > 0)
adjustHalLoss(-1)
// Eyes and blindness.
if(!has_eyes())
eye_blind = 1
blinded = 1
eye_blurry = 1
else if(eye_blind)
eye_blind = max(eye_blind-1,0)
blinded = 1
else if(eye_blurry)
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)
ear_damage = max(ear_damage-0.05, 0)
update_icons()
return 1
/mob/living/carbon/alien/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/alien/proc/handle_environment(var/datum/gas_mixture/environment)
// Both alien subtypes survive in vaccum and suffer in high temperatures,
// so I'll just define this once, for both (see radiation comment above)
if(!environment) return
if(environment.temperature > (T0C+66))
adjustFireLoss((environment.temperature - (T0C+66))/5) // Might be too high, check in testing.
if (fire) fire.icon_state = "fire2"
if(prob(20))
src << "\red You feel a searing heat!"
else
if (fire) fire.icon_state = "fire0"
@@ -0,0 +1,50 @@
/mob/living/carbon/alien/verb/evolve()
set name = "Evolve"
set desc = "Evolve into your adult form."
set category = "Abilities"
if(stat != CONSCIOUS)
return
if(!adult_form)
verbs -= /mob/living/carbon/alien/verb/evolve
return
if(handcuffed || legcuffed)
src << "\red You cannot evolve when you are cuffed."
return
if(amount_grown < max_grown)
src << "\red You are not fully grown."
return
// confirm_evolution() handles choices and other specific requirements.
var/new_species = confirm_evolution()
if(!new_species || !adult_form )
return
var/mob/living/carbon/human/adult = new adult_form(get_turf(src))
adult.set_species(new_species)
show_evolution_blurb()
if(mind)
mind.transfer_to(adult)
else
adult.key = src.key
for (var/obj/item/W in src.contents)
src.drop_from_inventory(W)
for(var/datum/language/L in languages)
adult.add_language(L.name)
del(src)
/mob/living/carbon/alien/proc/update_progression()
return
/mob/living/carbon/alien/proc/confirm_evolution()
return
/mob/living/carbon/alien/proc/show_evolution_blurb()
return
@@ -0,0 +1,20 @@
/mob/living/carbon/alien/regenerate_icons()
overlays = list()
update_icons()
/mob/living/carbon/alien/update_icons()
var/state = 0
if(amount_grown > max_grown*0.75)
state = 2
else if(amount_grown > max_grown*0.25)
state = 1
if(stat == DEAD)
icon_state = "[initial(icon_state)][state]_dead"
else if (stunned)
icon_state = "[initial(icon_state)][state]_stun"
else if(lying || resting)
icon_state = "[initial(icon_state)][state]_sleep"
else
icon_state = "[initial(icon_state)][state]"
+10 -3
View File
@@ -22,10 +22,16 @@
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)
if(istype(O,/obj/item/organ/brain) && !brainmob) //Time to stick a brain in it --NEO
var/obj/item/organ/brain/B = O
if(B.health <= 0)
user << "\red That brain is well and truly dead."
return
else if(!B.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]."))
@@ -61,6 +67,7 @@
return
..()
//TODO: ORGAN REMOVAL UPDATE. Make the brain remain in the MMI so it doesn't lose organ data.
attack_self(mob/user as mob)
if(!brainmob)
user << "\red You upend the MMI, but there's nothing in it."
@@ -68,7 +75,7 @@
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)
var/obj/item/organ/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
@@ -1,7 +1,7 @@
/obj/item/brain
/obj/item/organ/brain
name = "brain"
desc = "A piece of juicy meat found in a persons head."
icon = 'icons/obj/surgery.dmi'
health = 400 //They need to live awhile longer than other organs.
desc = "A piece of juicy meat found in a person's head."
icon_state = "brain2"
flags = TABLEPASS
force = 1.0
@@ -11,32 +11,38 @@
throw_range = 5
origin_tech = "biotech=3"
attack_verb = list("attacked", "slapped", "whacked")
prosthetic_name = "cyberbrain"
prosthetic_icon = "brain-prosthetic"
organ_tag = "brain"
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
/obj/item/organ/brain/xeno
name = "thinkpan"
desc = "It looks kind of like an enormous wad of purple bubblegum."
icon = 'icons/mob/alien.dmi'
icon_state = "chitin"
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)
/obj/item/organ/brain/New()
..()
spawn(5)
if(brainmob && brainmob.client)
brainmob.client.screen.len = null //clear the hud
brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain."
callHook("debrain", list(brainmob))
/obj/item/organ/brain/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)
/obj/item/brain/examine() // -- TLE
brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain."
callHook("debrain", list(brainmob))
/obj/item/organ/brain/examine() // -- TLE
set src in oview(12)
if (!( usr ))
return
@@ -47,53 +53,27 @@
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
/obj/item/organ/brain/removed(var/mob/living/target,var/mob/living/user)
add_fingerprint(user)
..()
if(!(user.zone_sel.selecting == ("head")) || !istype(M, /mob/living/carbon/human))
return ..()
var/mob/living/simple_animal/borer/borer = target.has_brain_worms()
if( !(locate(/obj/machinery/optable, M.loc) && M.resting) && ( !(locate(/obj/structure/table/, M.loc) && M.lying) && prob(50) ) )
return ..()
if(borer)
borer.detatch() //Should remove borer if the brain is removed - RR
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
var/mob/living/carbon/human/H = target
var/obj/item/organ/brain/B = src
if(istype(B) && istype(H))
B.transfer_identity(target)
//since these people will be dead M != usr
/obj/item/organ/brain/replaced(var/mob/living/target)
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(target.key)
target.ghostize()
if(brainmob)
if(brainmob.mind)
brainmob.mind.transfer_to(M)
brainmob.mind.transfer_to(target)
else
M.key = brainmob.key
M:brain_op_stage = 3.0
del(src)
else
..()
return
target.key = brainmob.key
@@ -36,7 +36,7 @@
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))
if(istype(loc,/obj/item/organ/brain))
del(loc)//Gets rid of the brain item
spawn(15)
if(animation) del(animation)
@@ -10,7 +10,6 @@
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.
@@ -140,7 +139,7 @@
src.brainmob.robot_talk_understand = 1
src.brainmob.stat = 0
src.brainmob.silent = 0
src.brainmob.brain_op_stage = 4.0
// src.brainmob.brain_op_stage = 4.0
dead_mob_list -= src.brainmob
..()
+2 -1
View File
@@ -423,7 +423,7 @@
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()
@@ -492,3 +492,4 @@
else
src << "You do not have enough chemicals stored to reproduce."
return
*/
@@ -1,7 +1,6 @@
/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
@@ -0,0 +1,99 @@
//TODO: Consider renaming carbon/monkey to carbon/small.
/mob/living/carbon/proc/fertilize_plant()
set category = "Abilities"
set name = "Fertilize plant"
set desc = "Turn your food into nutrients for plants."
var/list/trays = list()
for(var/obj/machinery/portable_atmospherics/hydroponics/tray in range(1))
if(tray.nutrilevel < 10 && src.Adjacent(tray))
trays += tray
var/obj/machinery/portable_atmospherics/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, refilling [target]'s nutrient tray.","\red You secrete a trickle of green liquid from your tail, refilling [target]'s nutrient tray.")
/mob/living/carbon/proc/eat_weeds()
set category = "Abilities"
set name = "Eat Weeds"
set desc = "Clean the weeds out of soil or a hydroponics tray."
var/list/trays = list()
for(var/obj/machinery/portable_atmospherics/hydroponics/tray in range(1))
if(tray.weedlevel > 0 && src.Adjacent(tray))
trays += tray
var/obj/machinery/portable_atmospherics/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.")
//Brain slug proc for voluntary removal of control.
/mob/living/carbon/proc/release_control()
set category = "Abilities"
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 && B.host_brain)
src << "\red <B>You withdraw your probosci, releasing control of [B.host_brain]</B>"
B.detatch()
verbs -= /mob/living/carbon/proc/release_control
verbs -= /mob/living/carbon/proc/punish_host
verbs -= /mob/living/carbon/proc/spawn_larvae
else
src << "\red <B>ERROR NO BORER OR BRAINMOB DETECTED IN THIS MOB, THIS IS A BUG !</B>"
//Brain slug proc for tormenting the host.
/mob/living/carbon/proc/punish_host()
set category = "Abilities"
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>"
/mob/living/carbon/proc/spawn_larvae()
set category = "Abilities"
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 rapidly excrete a larva 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
B.has_reproduced = 1
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,88 @@
proc/create_new_xenomorph(var/alien_caste,var/target)
target = get_turf(target)
if(!target || !alien_caste) return
var/mob/living/carbon/human/new_alien = new(target)
new_alien.set_species("Xenomorph [alien_caste]")
return new_alien
/mob/living/carbon/human/xdrone/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Drone")
/mob/living/carbon/human/xsentinel/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Sentinel")
/mob/living/carbon/human/xhunter/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Hunter")
/mob/living/carbon/human/xqueen/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Queen")
// I feel like we should generalize/condense down all the various icon-rendering antag procs.
/*----------------------------------------
Proc: AddInfectionImages()
Des: Gives the client of the alien an image on each infected mob.
----------------------------------------*/
/mob/living/carbon/human/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/human/proc/RemoveInfectionImages()
if (client)
for(var/image/I in client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
del(I)
return
/* TODO: Convert this over.
/mob/living/carbon/human/alien/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
*/
/* TODO: Convert this over.
/mob/living/carbon/human/alien/queen/large
icon = 'icons/mob/alienqueen.dmi'
icon_state = "queen_s"
pixel_x = -16
/mob/living/carbon/human/alien/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,159 @@
// 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 in player_list)
if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
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 in player_list)
if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
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 in player_list)
if(!locate(/datum/organ/internal/xenos/hivenode) in alien.internal_organs)
continue
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,240 @@
//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
body_parts_covered = FACE|EYES
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
attack_hand(user)
return
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile))
if(Attach(user))
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/fire_act(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/Crossed(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)
throwing = 0
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
if((!iscorgi(M) && !iscarbon(M)))
return
if(attached)
return
var/mob/living/carbon/C = M
if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs)
return
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)
target.contents += src // Monkey sanity check - Snapshot
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/corgi = M
src.loc = corgi
corgi.facehugger = src
corgi.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)]"
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))
return 0
var/mob/living/carbon/C = M
if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs)
return 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.head && H.head.flags & HEADCOVERSMOUTH)
return 0
return 1
@@ -0,0 +1,233 @@
/proc/alien_queen_exists(var/ignore_self,var/mob/living/carbon/human/self)
for(var/mob/living/carbon/human/Q in living_mob_list)
if(self && ignore_self && self == Q)
continue
if(Q.species.name != "Xenomorph Queen")
continue
if(!Q.key || !Q.client || Q.stat)
continue
return 1
return 0
/mob/living/carbon/human/proc/gain_plasma(var/amount)
var/datum/organ/internal/xenos/plasmavessel/I = internal_organs_by_name["plasma vessel"]
if(!istype(I)) return
if(amount)
I.stored_plasma += amount
I.stored_plasma = max(0,min(I.stored_plasma,I.max_plasma))
/mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ)
var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
if(!istype(P))
src << "<span class='danger'>Your plasma vessel has been removed!</span>"
return
if(needs_organ)
var/datum/organ/internal/I = internal_organs_by_name[needs_organ]
if(!I)
src << "<span class='danger'>Your [needs_organ] has been removed!</span>"
return
else if((I.status & ORGAN_CUT_AWAY) || I.is_broken())
src << "<span class='danger'>Your [needs_organ] is too damaged to function!</span>"
return
if(P.stored_plasma < cost)
src << "\red You don't have enough phoron stored to do that."
return 0
if(needs_foundation)
var/turf/T = get_turf(src)
var/has_foundation
if(T)
//TODO: Work out the actual conditions this needs.
if(!(istype(T,/turf/space)))
has_foundation = 1
if(!has_foundation)
src << "\red You need a solid foundation to do that on."
return 0
P.stored_plasma -= cost
return 1
// Free abilities.
/mob/living/carbon/human/proc/transfer_plasma(mob/living/carbon/human/M as mob in oview())
set name = "Transfer Plasma"
set desc = "Transfer Plasma to another alien"
set category = "Abilities"
if (get_dist(src,M) <= 1)
src << "\green You need to be closer."
return
var/datum/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name["plasma vessel"]
if(!istype(I))
src << "\green Their plasma vessel is missing."
return
var/amount = input("Amount:", "Transfer Plasma to [M]") as num
if (amount)
amount = abs(round(amount))
if(check_alien_ability(amount,0,"plasma vessel"))
M.gain_plasma(amount)
M << "\green [src] has transfered [amount] plasma to you."
src << "\green You have transferred [amount] plasma to [M]"
return
// Queen verbs.
/mob/living/carbon/human/proc/lay_egg()
set name = "Lay Egg (75)"
set desc = "Lay an egg to produce huggers to impregnate prey with."
set category = "Abilities"
if(!aliens_allowed)
src << "You begin to lay an egg, but hesitate. You suspect it isn't allowed."
verbs -= /mob/living/carbon/human/proc/lay_egg
return
if(locate(/obj/effect/alien/egg) in get_turf(src))
src << "There's already an egg here."
return
if(check_alien_ability(75,1,"egg sac"))
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
// Drone verbs.
/mob/living/carbon/human/proc/evolve()
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 = "Abilities"
if(alien_queen_exists())
src << "<span class='notice'>We already have an active queen.</span>"
return
if(check_alien_ability(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)
src.set_species("Xenomorph Queen")
return
/mob/living/carbon/human/proc/plant()
set name = "Plant Weeds (50)"
set desc = "Plants some alien weeds"
set category = "Abilities"
if(check_alien_ability(50,1,"resin spinner"))
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/human/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 = "Corrosive Acid (200)"
set desc = "Drench an object in acid, destroying it over time."
set category = "Abilities"
if(!O in oview(1))
src << "\green [O] is too far away."
return
// 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
if(check_alien_ability(200,0,"acid gland"))
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>")
return
/mob/living/carbon/human/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 = "Abilities"
if(!check_alien_ability(50,0,"acid gland"))
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot spit neurotoxin in your current state."
return
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.
// Maybe change this to use throw_at? ~ Z
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/human/proc/resin() // -- TLE
set name = "Secrete Resin (75)"
set desc = "Secrete tough malleable resin."
set category = "Abilities"
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)
return
if(!check_alien_ability(75,1,"resin spinner"))
return
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
@@ -0,0 +1,276 @@
//Stand-in until this is made more lore-friendly.
/datum/species/xenos
name = "Xenomorph"
name_plural = "Xenomorphs"
default_language = "Xenomorph"
language = "Hivemind"
unarmed_type = /datum/unarmed_attack/claws/strong
secondary_unarmed_type = /datum/unarmed_attack/bite/strong
hud_type = /datum/hud_data/alien
rarity_value = 3
has_fine_manipulation = 0
insulated = 1
gluttonous = 2
eyes = "blank_eyes"
brute_mod = 0.5 // Hardened carapace.
burn_mod = 2 // Weak to fire.
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
flags = NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON
reagent_tag = IS_XENOS
blood_color = "#05EE05"
flesh_color = "#282846"
gibbed_anim = "gibbed-a"
dusted_anim = "dust-a"
death_message = "lets out a waning guttural screech, green blood bubbling from its maw."
death_sound = 'sound/voice/hiss6.ogg'
speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
speech_chance = 100
breath_type = null
poison_type = null
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel,
"hive node" = /datum/organ/internal/xenos/hivenode,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
)
var/alien_number = 0
var/caste_name = "creature" // Used to update alien name.
var/weeds_heal_rate = 1 // Health regen on weeds.
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
/datum/species/xenos/can_understand(var/mob/other)
if(istype(other,/mob/living/carbon/alien/larva))
return 1
return 0
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
H.visible_message("<span class='notice'>[H] caresses [target] with its scythe-like arm.</span>", \
"<span class='notice'>You caress [target] with your scythe-like arm.</span>")
/datum/species/xenos/handle_post_spawn(var/mob/living/carbon/human/H)
if(H.mind)
H.mind.assigned_role = "Alien"
H.mind.special_role = "Alien"
alien_number++ //Keep track of how many aliens we've had so far.
H.real_name = "alien [caste_name] ([alien_number])"
H.name = H.real_name
..()
/datum/species/xenos/handle_environment_special(var/mob/living/carbon/human/H)
var/turf/T = H.loc
if(!T) return
var/datum/gas_mixture/environment = T.return_air()
if(!environment) return
if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T)
if(H.health >= H.maxHealth - H.getCloneLoss())
var/datum/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
P.stored_plasma += weeds_plasma_rate
P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
else
H.adjustBruteLoss(-weeds_heal_rate)
H.adjustFireLoss(-weeds_heal_rate)
H.adjustOxyLoss(-weeds_heal_rate)
H.adjustToxLoss(-weeds_heal_rate)
..()
/datum/species/xenos/handle_login_special(var/mob/living/carbon/human/H)
H.AddInfectionImages()
..()
/datum/species/xenos/handle_logout_special(var/mob/living/carbon/human/H)
H.RemoveInfectionImages()
..()
/datum/species/xenos/drone
name = "Xenomorph Drone"
caste_name = "drone"
weeds_plasma_rate = 15
slowdown = 2
tail = "xenos_drone_tail"
rarity_value = 5
icobase = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen,
"acid gland" = /datum/organ/internal/xenos/acidgland,
"hive node" = /datum/organ/internal/xenos/hivenode,
"resin spinner" = /datum/organ/internal/xenos/resinspinner,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/evolve,
/mob/living/carbon/human/proc/resin,
/mob/living/carbon/human/proc/corrosive_acid
)
/datum/species/xenos/drone/handle_post_spawn(var/mob/living/carbon/human/H)
var/mob/living/carbon/human/A = H
if(!istype(A))
return ..()
..()
/datum/species/xenos/hunter
name = "Xenomorph Hunter"
weeds_plasma_rate = 5
caste_name = "hunter"
slowdown = -1
total_health = 150
tail = "xenos_hunter_tail"
icobase = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/hunter,
"hive node" = /datum/organ/internal/xenos/hivenode,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate
)
/datum/species/xenos/sentinel
name = "Xenomorph Sentinel"
weeds_plasma_rate = 10
caste_name = "sentinel"
slowdown = 1
total_health = 125
tail = "xenos_sentinel_tail"
icobase = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain/xeno,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/sentinel,
"acid gland" = /datum/organ/internal/xenos/acidgland,
"hive node" = /datum/organ/internal/xenos/hivenode,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin
)
/datum/species/xenos/queen
name = "Xenomorph Queen"
total_health = 250
weeds_heal_rate = 5
weeds_plasma_rate = 20
caste_name = "queen"
slowdown = 5
tail = "xenos_queen_tail"
rarity_value = 10
icobase = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain/xeno,
"egg sac" = /datum/organ/internal/xenos/eggsac,
"plasma vessel" = /datum/organ/internal/xenos/plasmavessel/queen,
"acid gland" = /datum/organ/internal/xenos/acidgland,
"hive node" = /datum/organ/internal/xenos/hivenode,
"resin spinner" = /datum/organ/internal/xenos/resinspinner,
"nutrient vessel" = /datum/organ/internal/diona/nutrients
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/lay_egg,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin,
/mob/living/carbon/human/proc/resin
)
//maxHealth = 250
//health = 250
/datum/species/xenos/queen/handle_login_special(var/mob/living/carbon/human/H)
..()
// Make sure only one official queen exists at any point.
if(!alien_queen_exists(1,H))
H.real_name = "alien queen ([alien_number])"
H.name = H.real_name
else
H.real_name = "alien princess ([alien_number])"
H.name = H.real_name
/datum/hud_data/alien
icon = 'icons/mob/screen1_alien.dmi'
has_a_intent = 1
has_m_intent = 1
has_warnings = 1
has_hands = 1
has_drop = 1
has_throw = 1
has_resist = 1
has_pressure = 0
has_nutrition = 0
has_bodytemp = 0
has_internals = 0
gear = list(
"o_clothing" = list("loc" = ui_belt, "slot" = slot_wear_suit, "state" = "equip", "dir" = SOUTH),
"head" = list("loc" = ui_id, "slot" = slot_head, "state" = "hair"),
"storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"),
"storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"),
)
@@ -21,8 +21,10 @@
flick("gibbed-h", animation)
if(species)
flick(species.gibbed_anim, animation)
hgibs(loc, viruses, dna, species.flesh_color, species.blood_color)
else
flick("gibbed-h", animation)
hgibs(loc, viruses, dna)
spawn(15)
@@ -42,8 +44,8 @@
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
flick("dust-h", animation)
new /obj/effect/decal/remains/human(loc)
flick(species.dusted_anim, animation)
new species.remains_type(loc)
spawn(15)
if(animation) del(animation)
@@ -207,7 +207,7 @@
m_type = 2
if ("deathgasp")
message = "<B>[src]</B> seizes up and falls limp, \his eyes dead and lifeless..."
message = "<B>[src]</B> [species.death_message]"
m_type = 1
if ("giggle")
+11 -10
View File
@@ -239,9 +239,8 @@
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)
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(pulse == PULSE_NONE)
@@ -271,10 +270,11 @@
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"
if((!species.has_organ["brain"] || has_brain()) && stat != DEAD)
if(!key)
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely</span>\n"
else if(!client)
msg += "[t_He] [t_has] suddenly fallen asleep.\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
@@ -291,7 +291,7 @@
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"
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"
@@ -311,10 +311,11 @@
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.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_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(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
if(this_wound_desc in wound_descriptors)
wound_descriptors[this_wound_desc] += W.amount
continue
+88 -17
View File
@@ -8,6 +8,7 @@
var/datum/species/species //Contains icon generation and language information, set during New().
var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us.
/*
/mob/living/carbon/human/dummy
real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH
@@ -47,22 +48,28 @@
..(new_loc, "Kocasslani")
*/
/mob/living/carbon/human/New(var/new_loc, var/new_species = null)
if(!dna)
dna = new /datum/dna(null)
// Species name is handled by set_species()
if(!species)
if(new_species)
set_species(new_species,null,1)
set_species(new_species)
else
set_species()
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
/*
if(!dna)
dna = new /datum/dna(null)
dna.species=species.name
*/
hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100")
hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy")
hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudunknown")
@@ -82,6 +89,7 @@
prev_gender = gender // Debug for plural genders
make_blood()
/*
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing))
return
@@ -169,6 +177,7 @@
return
return
*/
/mob/living/carbon/human/Stat()
..()
statpanel("Status")
@@ -191,6 +200,10 @@
stat("Internal Atmosphere Info", internal.name)
stat("Tank Pressure", internal.air_contents.return_pressure())
stat("Distribution Pressure", internal.distribute_pressure)
var/datum/organ/internal/xenos/plasmavessel/P = internal_organs_by_name["plasma vessel"]
if(P)
stat(null, "Plasma Stored: [P.stored_plasma]/[P.max_plasma]")
if(mind)
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
@@ -309,7 +322,7 @@
return
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M as mob)
/mob/living/carbon/human/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
@@ -326,6 +339,17 @@
apply_damage(damage, BRUTE, affecting, armor)
if(armor >= 2) return
/mob/living/carbon/human/proc/implant_loyalty(mob/living/carbon/human/M, override = FALSE) // Won't override by default.
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(M)
L.imp_in = M
L.implanted = 1
var/datum/organ/external/affected = M.organs_by_name["head"]
affected.implants += L
L.part = affected
/mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M)
for(var/L in M.contents)
if(istype(L, /obj/item/weapon/implant/loyalty))
@@ -860,6 +884,17 @@
///Returns a number between -1 to 2
/mob/living/carbon/human/eyecheck()
var/number = 0
if(!species.has_organ["eyes"]) //No eyes, can't hurt them.
return 2
if(internal_organs_by_name["eyes"]) // Eyes are fucked, not a 'weak point'.
var/datum/organ/internal/I = internal_organs_by_name["eyes"]
if(I.status & ORGAN_CUT_AWAY)
return 2
else
return 2
if(istype(src.head, /obj/item/clothing/head/welding))
if(!src.head:up)
number += 2
@@ -877,7 +912,7 @@
/mob/living/carbon/human/IsAdvancedToolUser()
return 1//Humans can use guns and such
return species.has_fine_manipulation
/mob/living/carbon/human/abiotic(var/full_body = 0)
@@ -1134,12 +1169,12 @@
/mob/living/carbon/human/proc/is_lung_ruptured()
var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
return L.is_bruised()
return L && L.is_bruised()
/mob/living/carbon/human/proc/rupture_lung()
var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
if(!L.is_bruised())
if(L && !L.is_bruised())
src.custom_pain("You feel a stabbing pain in your chest!", 1)
L.damage = L.min_bruised_damage
@@ -1224,7 +1259,7 @@
src << msg
organ.take_damage(rand(1,3), 0, 0)
if(!(organ.status & ORGAN_ROBOT)) //There is no blood in protheses.
if(!(organ.status & ORGAN_ROBOT) && !(species.flags & NO_BLOOD)) //There is no blood in protheses.
organ.status |= ORGAN_BLEEDING
src.adjustToxLoss(rand(1,3))
@@ -1260,7 +1295,7 @@
else
usr << "\blue [self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)]."
/mob/living/carbon/human/proc/set_species(var/new_species, var/force_organs, var/default_colour)
/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour)
if(!dna)
if(!new_species)
@@ -1271,20 +1306,29 @@
else
dna.species = new_species
if(species && (species.name && species.name == new_species))
return
if(species)
if(species && species.language)
remove_language(species.language)
if(species.name && species.name == new_species)
return
if(species.language)
remove_language(species.language)
if(species.default_language)
remove_language(species.default_language)
// Clear out their species abilities.
species.remove_inherent_verbs(src)
species = all_species[new_species]
if(force_organs || !organs || !organs.len)
species.create_organs(src)
species.create_organs(src)
if(species.language)
add_language(species.language)
if(species.default_language)
add_language(species.default_language)
if(species.base_color && default_colour)
//Apply colour.
r_skin = hex2num(copytext(species.base_color,2,4))
@@ -1298,7 +1342,9 @@
species.handle_post_spawn(src)
spawn(0)
update_icons()
regenerate_icons()
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
if(species)
return 1
@@ -1382,7 +1428,7 @@
//Putting a couple of procs here that I don't know where else to dump.
//Mostly going to be used for Vox and Vox Armalis, but other human mobs might like them (for adminbuse).
/*
/mob/living/carbon/human/proc/leap()
set category = "IC"
set name = "Leap"
@@ -1456,6 +1502,7 @@
G.icon_state = "grabbed1"
G.synch()
/mob/living/carbon/human/proc/gut()
set category = "IC"
set name = "Gut"
@@ -1528,7 +1575,7 @@
return
H << "\red Your nose begins to bleed..."
H.drip(1)
*/
/mob/living/carbon/human/print_flavor_text()
var/list/equipment = list(src.head,src.wear_mask,src.glasses,src.w_uniform,src.wear_suit,src.gloves,src.shoes)
var/head_exposed = 1
@@ -1566,3 +1613,27 @@
flavor_text += flavor_texts[T]
flavor_text += "\n\n"
return ..()
/mob/living/carbon/human/getDNA()
if(species.flags & NO_SCAN)
return null
..()
/mob/living/carbon/human/setDNA()
if(species.flags & NO_SCAN)
return
..()
/mob/living/carbon/human/has_brain()
if(internal_organs_by_name["brain"])
var/datum/organ/internal/brain = internal_organs_by_name["brain"]
if(brain && istype(brain))
return 1
return 0
/mob/living/carbon/human/has_eyes()
if(internal_organs_by_name["eyes"])
var/datum/organ/internal/eyes = internal_organs_by_name["eyes"]
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
return 1
return 0
@@ -111,7 +111,13 @@
return 1
if("hurt")
// See if they can attack, and which attacks to use.
var/datum/unarmed_attack/attack = M.species.unarmed
if(!attack.is_usable(M))
attack = M.species.secondary_unarmed
if(!attack.is_usable(M))
return 0
//Vampire code
if(M.zone_sel && M.zone_sel.selecting == "head")
if(M.mind && M.mind.vampire && (M.mind in ticker.mode.vampires) && !M.mind.vampire.draining)
@@ -1,7 +1,7 @@
//Updates the mob's health from organs and mob damage variables
/mob/living/carbon/human/updatehealth()
if(status_flags & GODMODE)
health = 100
health = species.total_health
stat = CONSCIOUS
return
var/total_burn = 0
@@ -9,21 +9,57 @@
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
var/oxy_l = ((species.flags & NO_BREATHE) ? 0 : getOxyLoss())
var/tox_l = ((species.flags & NO_POISON) ? 0 : getToxLoss())
var/clone_l = getCloneLoss()
health = species.total_health - oxy_l - tox_l - clone_l - 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
if( ((species.total_health - total_burn) < config.health_threshold_dead) && stat == DEAD)
ChangeToHusk()
return
/mob/living/carbon/human/adjustBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
if(species && species.has_organ["brain"])
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.take_damage(amount)
sponge.damage = min(max(brainloss, 0),(maxHealth*2))
brainloss = sponge.damage
else
brainloss = 200
else
brainloss = 0
/mob/living/carbon/human/setBrainLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
if(species && species.has_organ["brain"])
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if(sponge)
sponge.damage = min(max(amount, 0),(maxHealth*2))
brainloss = sponge.damage
else
brainloss = 200
else
brainloss = 0
/mob/living/carbon/human/getBrainLoss()
var/res = brainloss
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
if (sponge.is_bruised())
res += 20
if (sponge.is_broken())
res += 50
res = min(res,maxHealth*2)
return res
if(status_flags & GODMODE) return 0 //godmode
if(species && species.has_organ["brain"])
var/datum/organ/internal/brain/sponge = internal_organs_by_name["brain"]
brainloss = min(sponge.damage,maxHealth*2)
else
brainloss = 0
return brainloss
//These procs fetch a cumulative total damage from all organs
/mob/living/carbon/human/getBruteLoss()
@@ -101,16 +137,24 @@
if(HULK in mutations) return
..()
/mob/living/carbon/human/adjustHalLoss(var/amount)
if(species.flags & NO_PAIN) //pain immune
return
..()
/mob/living/carbon/human/getCloneLoss()
if(species.flags & (IS_SYNTHETIC | NO_SCAN))
cloneloss = 0
return ..()
/mob/living/carbon/human/setCloneLoss(var/amount)
if(species.flags & (IS_SYNTHETIC | NO_SCAN))
cloneloss = 0
else
..()
/mob/living/carbon/human/adjustCloneLoss(var/amount)
if(species.flags & IS_SYNTHETIC)
return
..()
if(species.flags & (IS_SYNTHETIC | NO_SCAN))
cloneloss = 0
return
var/heal_prob = max(0, 80 - getCloneLoss())
var/mut_prob = min(80, getCloneLoss()+10)
if (amount > 0)
@@ -139,6 +183,41 @@
src << "<span class = 'notice'>Your [O.display_name] is shaped normally again.</span>"
hud_updateflag |= 1 << HEALTH_HUD
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/getOxyLoss()
if(species.flags & NO_BREATHE)
oxyloss = 0
return ..()
/mob/living/carbon/human/adjustOxyLoss(var/amount)
if(species.flags & NO_BREATHE)
oxyloss = 0
else
..()
/mob/living/carbon/human/setOxyLoss(var/amount)
if(species.flags & NO_BREATHE)
oxyloss = 0
else
..()
/mob/living/carbon/human/getToxLoss()
if(species.flags & NO_POISON)
toxloss = 0
return ..()
/mob/living/carbon/human/adjustToxLoss(var/amount)
if(species.flags & NO_POISON)
toxloss = 0
else
..()
/mob/living/carbon/human/setToxLoss(var/amount)
if(species.flags & NO_POISON)
toxloss = 0
else
..()
////////////////////////////////////////////
//Returns a list of damaged organs
@@ -231,6 +231,7 @@ emp_act
if(armor >= 2) return 0
if(!I.force) return 0
// var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
apply_damage(I.force, I.damtype, affecting, armor, sharp=weapon_sharp, edge=weapon_edge, used_weapon=I)
@@ -277,6 +278,9 @@ emp_act
if(bloody)
bloody_body(src)
// if(Iforce > 10 || Iforce >= 5 && prob(33))
// forcesay(hit_appends) //forcesay checks stat already
//Melee weapon embedded object code.
if (I.damtype == BRUTE && !I.is_robot_module())
var/damage = I.force
@@ -296,6 +300,15 @@ emp_act
/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5)
if(istype(AM,/obj/))
var/obj/O = AM
if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode
if(canmove && !restrained())
if(isturf(O.loc))
put_in_active_hand(O)
visible_message("<span class='warning'>[src] catches [O]!</span>")
throw_mode_off()
return
var/dtype = BRUTE
if(istype(O,/obj/item/weapon))
var/obj/item/weapon/W = O
@@ -23,6 +23,9 @@
var/g_skin = 0
var/b_skin = 0
var/size_multiplier = 1 //multiplier for the mob's icon size
var/icon_update = 1 //whether icon updating shall take place
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)
@@ -32,6 +35,12 @@
var/undershirt = 0 //Which undershirt the player wants.
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
// General information
var/home_system = ""
var/citizenship = ""
var/personal_faction = ""
var/religion = ""
//Equipment slots
var/obj/item/wear_suit = null
var/obj/item/w_uniform = null
@@ -1,8 +1,8 @@
/mob/living/carbon/human/movement_delay()
var/tally = 0
if(species && species.flags & IS_SLOW)
tally = 7
if(species.slowdown)
tally = species.slowdown
if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything
@@ -79,6 +79,10 @@
/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(species.flags & NO_SLIP)
return
if(stat)
prob_slip = 0 // Changing this to zero to make it line up with the comment, and also, make more sense.
@@ -0,0 +1,221 @@
// These should all be procs, you can add them to humans/subspecies by
// species.dm's inherent_verbs ~ Z
/mob/living/carbon/human/proc/tackle()
set category = "Abilities"
set name = "Tackle"
set desc = "Tackle someone down."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot tackle someone in your current state."
return
var/list/choices = list()
for(var/mob/living/M in view(1,src))
if(!istype(M,/mob/living/silicon) && Adjacent(M))
choices += M
choices -= src
var/mob/living/T = input(src,"Who do you wish to tackle?") as null|anything in choices
if(!T || !src || src.stat) return
if(!Adjacent(T)) return
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot tackle in your current state."
return
last_special = world.time + 50
var/failed
if(prob(75))
T.Weaken(rand(0.5,3))
else
src.Weaken(rand(2,4))
failed = 1
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
if(failed)
src.Weaken(rand(2,4))
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red <B>[] [failed ? "tried to tackle" : "has tackled"] down []!</B>", src, T), 1)
/mob/living/carbon/human/proc/leap()
set category = "Abilities"
set name = "Leap"
set desc = "Leap at a target and grab them aggressively."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
return
var/list/choices = list()
for(var/mob/living/M in view(6,src))
if(!istype(M,/mob/living/silicon))
choices += M
choices -= src
var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices
if(!T || !src || src.stat) return
if(get_dist(get_turf(T), get_turf(src)) > 6) return
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
return
last_special = world.time + 75
status_flags |= LEAPING
src.visible_message("<span class='warning'><b>\The [src]</b> leaps at [T]!</span>")
src.throw_at(get_step(get_turf(T),get_turf(src)), 5, 1, src)
playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1)
sleep(5)
if(status_flags & LEAPING) status_flags &= ~LEAPING
if(!src.Adjacent(T))
src << "\red You miss!"
return
T.Weaken(5)
//Only official cool kids get the grab and no self-prone.
if(src.mind && src.mind.special_role)
src.Weaken(5)
return
var/use_hand = "left"
if(l_hand)
if(r_hand)
src << "\red You need to have one hand free to grab someone."
return
else
use_hand = "right"
src.visible_message("<span class='warning'><b>\The [src]</b> seizes [T] aggressively!</span>")
var/obj/item/weapon/grab/G = new(src,T)
if(use_hand == "left")
l_hand = G
else
r_hand = G
G.state = GRAB_AGGRESSIVE
G.icon_state = "grabbed1"
G.synch()
/mob/living/carbon/human/proc/gut()
set category = "Abilities"
set name = "Gut"
set desc = "While grabbing someone aggressively, rip their guts out or tear them apart."
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying)
src << "\red You cannot do that in your current state."
return
var/obj/item/weapon/grab/G = locate() in src
if(!G || !istype(G))
src << "\red You are not grabbing anyone."
return
if(G.state < GRAB_AGGRESSIVE)
src << "\red You must have an aggressive grab to gut your prey!"
return
last_special = world.time + 50
visible_message("<span class='warning'><b>\The [src]</b> rips viciously at \the [G.affecting]'s body with its claws!</span>")
if(istype(G.affecting,/mob/living/carbon/human))
var/mob/living/carbon/human/H = G.affecting
H.apply_damage(50,BRUTE)
if(H.stat == 2)
H.gib()
else
var/mob/living/M = G.affecting
if(!istype(M)) return //wut
M.apply_damage(50,BRUTE)
if(M.stat == 2)
M.gib()
/mob/living/carbon/human/proc/commune()
set category = "Abilities"
set name = "Commune with creature"
set desc = "Send a telepathic message to an unlucky recipient."
var/list/targets = list()
var/target = null
var/text = null
targets += getmobs() //Fill list, prompt user with list
target = input("Select a creature!", "Speak to creature", null, null) as null|anything in targets
if(!target) return
text = input("What would you like to say?", "Speak to creature", null, null)
text = trim(copytext(sanitize(text), 1, MAX_MESSAGE_LEN))
if(!text) return
var/mob/M = targets[target]
if(istype(M, /mob/dead/observer) || M.stat == DEAD)
src << "Not even a [src.species.name] can speak to the dead."
return
log_say("[key_name(src)] communed to [key_name(M)]: [text]")
M << "\blue Like lead slabs crashing into the ocean, alien thoughts drop into your mind: [text]"
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.name == src.species.name)
return
H << "\red Your nose begins to bleed..."
H.drip(1)
/mob/living/carbon/human/proc/regurgitate()
set name = "Regurgitate"
set desc = "Empties the contents of your stomach"
set category = "Abilities"
if(stomach_contents.len)
for(var/mob/M in src)
if(M in stomach_contents)
stomach_contents.Remove(M)
M.loc = loc
src.visible_message("\red <B>[src] hurls out the contents of their stomach!</B>")
return
/mob/living/carbon/human/proc/psychic_whisper(mob/M as mob in oview())
set name = "Psychic Whisper"
set desc = "Whisper silently to someone over a distance."
set category = "Abilities"
var/msg = sanitize(input("Message:", "Psychic Whisper") as text|null)
if(msg)
log_say("PsychicWhisper: [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
@@ -0,0 +1,34 @@
// These may have some say.dm bugs regarding understanding common,
// might be worth adapting the bugs into a feature and using these
// subtypes as a basis for non-common-speaking alien foreigners. ~ Z
/mob/living/carbon/human/dummy
real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH
/mob/living/carbon/human/skrell/New(var/new_loc)
h_style = "Skrell Male Tentacles"
..(new_loc, "Skrell")
/mob/living/carbon/human/tajaran/New(var/new_loc)
h_style = "Tajaran Ears"
..(new_loc, "Tajaran")
/mob/living/carbon/human/unathi/New(var/new_loc)
h_style = "Unathi Horns"
..(new_loc, "Unathi")
/mob/living/carbon/human/vox/New(var/new_loc)
h_style = "Short Vox Quills"
..(new_loc, "Vox")
/mob/living/carbon/human/voxarmalis/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Vox Armalis")
/mob/living/carbon/human/diona/New(var/new_loc)
..(new_loc, "Diona")
/mob/living/carbon/human/machine/New(var/new_loc)
h_style = "blue IPC screen"
..(new_loc, "Machine")
@@ -85,6 +85,8 @@
if(W)
success = 1
wear_suit = null
if(W.flags_inv & HIDESHOES)
update_inv_shoes(0)
update_inv_wear_suit()
else if (W == w_uniform)
if (r_store)
@@ -108,9 +110,10 @@
update_inv_glasses()
else if (W == head)
head = null
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR))
if((W.flags & BLOCKHAIR) || (W.flags & BLOCKHEADHAIR)|| (W.flags_inv & HIDEMASK))
update_hair(0) //rebuild hair
update_inv_ears(0)
update_inv_wear_mask(0)
success = 1
update_inv_head()
else if (W == l_ear)
@@ -270,9 +273,10 @@
update_inv_gloves(redraw_mob)
if(slot_head)
src.head = W
if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR))
if((head.flags & BLOCKHAIR) || (head.flags & BLOCKHEADHAIR) || (head.flags_inv & HIDEMASK))
update_hair(redraw_mob) //rebuild hair
update_inv_ears(0)
update_inv_wear_mask(0)
if(istype(W,/obj/item/clothing/head/kitty))
W.update_icon(src)
W.equipped(src, slot)
@@ -283,6 +287,8 @@
update_inv_shoes(redraw_mob)
if(slot_wear_suit)
src.wear_suit = W
if(wear_suit.flags_inv & HIDESHOES)
update_inv_shoes(0)
W.equipped(src, slot)
update_inv_wear_suit(redraw_mob)
if(slot_w_uniform)
+74 -49
View File
@@ -95,6 +95,9 @@
//Disabilities
handle_disabilities()
//Organ failure.
handle_organs()
//Random events (vomiting etc)
handle_random_events()
@@ -287,7 +290,8 @@
radiation = Clamp(radiation,0,100)
if (radiation)
if(species.flags & RAD_ABSORB)
var/datum/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
if(rad_organ && !rad_organ.is_broken())
var/rads = radiation/25
radiation -= rads
nutrition += rads
@@ -439,6 +443,7 @@
proc/handle_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return
@@ -460,7 +465,17 @@
return 0
var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa
//var/safe_pressure_max = 140 // Maximum safe partial pressure of breathable gas in kPa (Not used for now)
// Lung damage increases the minimum safe pressure.
if(species.has_organ["lungs"])
var/datum/organ/internal/lungs/L = internal_organs_by_name["lungs"]
if(!L)
safe_pressure_min = INFINITY //No lungs, how are you breathing?
else if(L.is_broken())
safe_pressure_min *= 1.5
else if(L.is_bruised())
safe_pressure_min *= 1.25
var/safe_exhaled_max = 10
var/safe_toxins_max = 0.005
var/SA_para_min = 1
@@ -643,9 +658,13 @@
return 1
proc/handle_environment(datum/gas_mixture/environment)
if(!environment)
return
//Stuff like the xenomorph's plasma regen happens here.
species.handle_environment_special(src)
//Moved pressure calculations here for use in skip-processing check.
var/pressure = environment.return_pressure()
var/adjusted_pressure = calculate_affecting_pressure(pressure)
@@ -992,7 +1011,8 @@
if(status_flags & GODMODE) return 0 //godmode
if(species.flags & REQUIRE_LIGHT)
var/datum/organ/internal/diona/node/light_organ = locate() in internal_organs
if(light_organ && !light_organ.is_broken())
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
@@ -1055,7 +1075,7 @@
if(overeatduration > 1)
overeatduration -= 2 //doubled the unfat rate
if(species.flags & REQUIRE_LIGHT)
if(species.flags & IS_PLANT && (!light_organ || light_organ.is_broken()))
if(nutrition < 200)
take_overall_damage(2,0)
traumatic_shock++
@@ -1096,7 +1116,7 @@
handle_organs() //Optimized.
handle_blood()
if(health <= config.health_threshold_dead || brain_op_stage == 4.0)
if(health <= config.health_threshold_dead || (species.has_organ["brain"] && !has_brain()))
death()
blinded = 1
silent = 0
@@ -1181,15 +1201,23 @@
//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
if(!species.has_organ["eyes"]) // Presumably if a species has no eyes, they see via something else.
eye_blind = 0
blinded = 0
eye_blurry = 0
else if(!has_eyes()) // Eyes cut out? Permablind.
eye_blind = 1
blinded = 1
eye_blurry = 1
else 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(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
eye_blurry = max(eye_blurry-3, 0)
blinded = 1
else if(eye_blurry) //blurry eyes heal slowly
blinded = 1
else if(eye_blurry) // Blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
//Ears
@@ -1213,9 +1241,10 @@
return 1
proc/handle_regular_hud_updates()
if(hud_updateflag)
if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head
handle_hud_list()
// now handle what we see on our screen
if(!client) return 0
@@ -1227,7 +1256,7 @@
if(copytext(hud.icon_state,1,4) == "hud") //ugly, but icon comparison is worse, I believe
client.images.Remove(hud)
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask, global_hud.nvg, global_hud.lum)
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask, global_hud.nvg, global_hud.lum, global_hud.thermal, global_hud.meson)
update_action_buttons()
@@ -1307,7 +1336,7 @@
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(healths) healths.icon_state = "health7" //DEAD healthmeter
if(client)
if(client.view != world.view)
if(client.view != world.view)if(client.view != world.view) // If mob moves while zoomed in with device, unzoom them.
if(locate(/obj/item/weapon/gun/energy/rifle/sniperrifle, contents))
var/obj/item/weapon/gun/energy/rifle/sniperrifle/s = locate() in src
if(s.zoom)
@@ -1351,9 +1380,9 @@
see_invisible = SEE_INVISIBLE_LIVING
seer = 0
var/tmp/has_ninja_mask = 0
var/tmp/glasses_processed = 0
if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja))
has_ninja_mask = 1
glasses_processed = 1
var/obj/item/clothing/mask/gas/voice/space_ninja/O = wear_mask
switch(O.mode)
if(0)
@@ -1373,40 +1402,13 @@
if(3)
sight |= SEE_TURFS
if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
if(glasses)
var/obj/item/clothing/glasses/G = glasses
if(istype(G))
see_in_dark += G.darkness_view
if(G.vision_flags) // MESONS
sight |= G.vision_flags
if(!druggy)
see_invisible = SEE_INVISIBLE_MINIMUM
if(istype(G,/obj/item/clothing/glasses/night))
see_invisible = SEE_INVISIBLE_MINIMUM
client.screen += global_hud.nvg
if(istype(G,/obj/item/clothing/glasses/UV))
see_invisible = SEE_INVISIBLE_LIVING
client.screen += global_hud.lum
glasses_processed = 1
process_glasses(glasses)
/* HUD shit goes here, as long as it doesn't modify sight flags */
// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl
if(istype(glasses, /obj/item/clothing/glasses/sunglasses/sechud))
var/obj/item/clothing/glasses/sunglasses/sechud/O = glasses
if(O.hud) O.hud.process_hud(src)
if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
else if(istype(glasses, /obj/item/clothing/glasses/hud))
var/obj/item/clothing/glasses/hud/O = glasses
O.process_hud(src)
if(!druggy)
see_invisible = SEE_INVISIBLE_LIVING
else if(!seer && !has_ninja_mask)
if(!seer && !glasses_processed)
see_invisible = SEE_INVISIBLE_LIVING
if(healths)
if (analgesic)
healths.icon_state = "health_health_numb"
@@ -1533,6 +1535,29 @@
reset_view(null)
return 1
proc/process_glasses(var/obj/item/clothing/glasses/G)
if(G && G.active)
see_in_dark += G.darkness_view
if(G.overlay)
client.screen |= G.overlay
if(G.vision_flags)
sight |= G.vision_flags
if(!druggy)
see_invisible = SEE_INVISIBLE_MINIMUM
if(istype(G,/obj/item/clothing/glasses/night))
see_invisible = SEE_INVISIBLE_MINIMUM
/* HUD shit goes here, as long as it doesn't modify sight flags */
// The purpose of this is to stop xray and w/e from preventing you from using huds -- Love, Doohl
if(istype(G, /obj/item/clothing/glasses/sunglasses/sechud))
var/obj/item/clothing/glasses/sunglasses/sechud/O = G
if(O.hud) O.hud.process_hud(src)
if(!druggy) see_invisible = SEE_INVISIBLE_LIVING
else if(istype(G, /obj/item/clothing/glasses/hud))
var/obj/item/clothing/glasses/hud/O = G
O.process_hud(src)
if(!druggy)
see_invisible = SEE_INVISIBLE_LIVING
proc/handle_random_events()
// Puke if toxloss is too high
if(!stat)
@@ -1705,8 +1730,8 @@
if(stat == 2)
holder.icon_state = "hudhealth-100" // X_X
else
holder.icon_state = "hud[RoundHealth(health)]"
var/percentage_health = RoundHealth(((0.0+health)/species.total_health)*100)
holder.icon_state = "hud[percentage_health]"
hud_list[HEALTH_HUD] = holder
if(hud_updateflag & 1 << STATUS_HUD)
@@ -2,4 +2,5 @@
..()
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
if(species) species.handle_login_special(src)
return
@@ -0,0 +1,4 @@
/mob/living/carbon/human/Logout()
..()
if(species) species.handle_logout_special(src)
return
@@ -0,0 +1,604 @@
/*
Datum-based species. Should make for much cleaner and easier to maintain mutantrace code.
*/
/datum/species
var/name // Species name.
var/name_plural
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/prone_icon // If set, draws this from icobase when mob is prone.
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/datum/unarmed_attack/unarmed // For empty hand harm-intent attack
var/datum/unarmed_attack/secondary_unarmed // For empty hand harm-intent attack if the first fails.
var/datum/hud_data/hud
var/hud_type
var/slowdown = 0
var/gluttonous // Can eat some mobs. 1 for monkeys, 2 for people.
var/rarity_value = 1 // Relative rarity/collector value for this species. Only used by ninja and cultists atm.
var/unarmed_type = /datum/unarmed_attack
var/secondary_unarmed_type = /datum/unarmed_attack/bite
var/language // Default racial language, if any.
// Default language is used when 'say' is used without modifiers.
var/default_language = "Ceti Basic"
var/secondary_langs = list() // The names of secondary languages that are available to this species.
var/mutantrace // Safeguard due to old code.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance
var/has_fine_manipulation = 1 // Can use small items.
var/insulated // Immune to electrocution and glass shards to the feet.
// Some species-specific gibbing data.
var/gibbed_anim = "gibbed-h"
var/dusted_anim = "dust-h"
var/remains_type = /obj/effect/decal/remains/xeno
var/death_sound
var/death_message = "seizes up and falls limp, their eyes dead and lifeless..."
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
var/poison_type = "phoron" // Poisonous air.
var/exhale_type = "carbon_dioxide" // Exhaled gas type.
var/total_health = 100 //Point at which the mob will enter crit.
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/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing)
var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second
var/reagent_tag //Used for metabolizing reagents.
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_mod = null // Physical damage reduction/malus.
var/burn_mod = null // Burn damage reduction/malus.
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.
var/base_color //Used when setting species.
//Used in icon caching.
var/race_key = 0
var/icon/icon_template
// Species-specific abilities.
var/list/inherent_verbs
var/list/has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes
)
/datum/species/New()
if(hud_type)
hud = new hud_type()
else
hud = new()
if(unarmed_type) unarmed = new unarmed_type()
if(secondary_unarmed_type) secondary_unarmed = new secondary_unarmed_type()
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
//Trying to work out why species changes aren't fixing organs properly.
if(H.organs) H.organs.Cut()
if(H.internal_organs) H.internal_organs.Cut()
if(H.organs_by_name) H.organs_by_name.Cut()
if(H.internal_organs_by_name) H.internal_organs_by_name.Cut()
H.organs = list()
H.internal_organs = list()
H.organs_by_name = list()
H.internal_organs_by_name = list()
//This is a basic humanoid limb setup.
H.organs_by_name["chest"] = new/datum/organ/external/chest()
H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"])
H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"])
H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"])
H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"])
H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"])
H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"])
H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"])
H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"])
H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"])
H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"])
for(var/organ in has_organ)
var/organ_type = has_organ[organ]
H.internal_organs_by_name[organ] = new organ_type(H)
for(var/name in H.organs_by_name)
H.organs += H.organs_by_name[name]
for(var/datum/organ/external/O in H.organs)
O.owner = H
if(flags & IS_SYNTHETIC)
for(var/datum/organ/external/E in H.organs)
if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
E.status |= ORGAN_ROBOT
for(var/datum/organ/internal/I in H.internal_organs)
I.mechanize()
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
var/t_him = "them"
switch(target.gender)
if(MALE)
t_him = "him"
if(FEMALE)
t_him = "her"
H.visible_message("<span class='notice'>[H] hugs [target] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [target] to make [t_him] feel better!</span>")
/datum/species/proc/remove_inherent_verbs(var/mob/living/carbon/human/H)
if(inherent_verbs)
for(var/verb_path in inherent_verbs)
H.verbs -= verb_path
return
/datum/species/proc/add_inherent_verbs(var/mob/living/carbon/human/H)
if(inherent_verbs)
for(var/verb_path in inherent_verbs)
H.verbs |= verb_path
return
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
add_inherent_verbs(H)
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
if(flags & IS_SYNTHETIC)
H.h_style = ""
spawn(100)
H.update_hair()
return
// Only used for alien plasma weeds atm, but could be used for Dionaea later.
/datum/species/proc/handle_environment_special(var/mob/living/carbon/human/H)
return
// Used to update alien icons for aliens.
/datum/species/proc/handle_login_special(var/mob/living/carbon/human/H)
return
// As above.
/datum/species/proc/handle_logout_special(var/mob/living/carbon/human/H)
return
// Builds the HUD using species-specific icons and usable slots.
/datum/species/proc/build_hud(var/mob/living/carbon/human/H)
return
// Grabs the window recieved when you click-drag someone onto you.
/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H)
return
//Used by xenos understanding larvae and dionaea understanding nymphs.
/datum/species/proc/can_understand(var/mob/other)
return
/datum/species/human
name = "Human"
name_plural = "Humans"
language = "Sol Common"
primitive = /mob/living/carbon/monkey
unarmed_type = /datum/unarmed_attack/punch
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"
name_plural = "Unathi"
icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi'
language = "Sinta'unathi"
tail = "sogtail"
unarmed_type = /datum/unarmed_attack/claws
secondary_unarmed_type = /datum/unarmed_attack/bite/strong
primitive = /mob/living/carbon/monkey/unathi
darksight = 3
gluttonous = 1
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_SKIN_COLOR
flesh_color = "#34AF10"
reagent_tag = IS_UNATHI
base_color = "#066000"
/datum/species/tajaran
name = "Tajaran"
name_plural = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
language = "Siik'Maas"
tail = "tajtail"
unarmed_type = /datum/unarmed_attack/claws
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_SKIN_COLOR
flesh_color = "#AFA59E"
base_color = "#333333"
/datum/species/skrell
name = "Skrell"
name_plural = "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
unarmed_type = /datum/unarmed_attack/punch
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
reagent_tag = IS_SKRELL
/datum/species/vox
name = "Vox"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
default_language = "Vox-pidgin"
language = "Ceti Basic"
unarmed_type = /datum/unarmed_attack/claws/strong
secondary_unarmed_type = /datum/unarmed_attack/bite/strong
rarity_value = 2
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
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"
poison_type = "oxygen"
insulated = 1
flags = NO_SCAN
blood_color = "#2299FC"
flesh_color = "#808D11"
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap
)
has_organ = list(
"heart" = /datum/organ/internal/heart,
"lungs" = /datum/organ/internal/lungs,
"liver" = /datum/organ/internal/liver,
"kidneys" = /datum/organ/internal/kidney,
"brain" = /datum/organ/internal/brain,
"eyes" = /datum/organ/internal/eyes,
"stack" = /datum/organ/internal/stack/vox
)
/datum/species/vox/armalis
name = "Vox Armalis"
name_plural = "Vox"
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
rarity_value = 10
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
brute_mod = 0.2
burn_mod = 0.2
eyes = "blank_eyes"
breath_type = "nitrogen"
poison_type = "oxygen"
flags = NO_SCAN | NO_BLOOD | NO_PAIN
blood_color = "#2299FC"
flesh_color = "#808D11"
tail = "armalis_tail"
icon_template = 'icons/mob/human_races/r_armalis.dmi'
reagent_tag = IS_VOX
inherent_verbs = list(
/mob/living/carbon/human/proc/leap,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/commune
)
/datum/species/diona
name = "Diona"
name_plural = "Dionaea"
icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
unarmed_type = /datum/unarmed_attack/diona
primitive = /mob/living/carbon/alien/diona
slowdown = 7
rarity_value = 3
has_organ = list(
"nutrient channel" = /datum/organ/internal/diona/nutrients,
"neural strata" = /datum/organ/internal/diona/strata,
"response node" = /datum/organ/internal/diona/node,
"gas bladder" = /datum/organ/internal/diona/bladder,
"polyp segment" = /datum/organ/internal/diona/polyp,
"anchoring ligament" = /datum/organ/internal/diona/ligament
)
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
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP
blood_color = "#004400"
flesh_color = "#907E4A"
reagent_tag = IS_DIONA
/datum/species/diona/can_understand(var/mob/other)
var/mob/living/carbon/alien/diona/D = other
if(istype(D))
return 1
return 0
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
return ..()
/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
var/mob/living/carbon/alien/diona/S = new(get_turf(H))
if(H.mind)
H.mind.transfer_to(S)
for(var/mob/living/carbon/alien/diona/D in H.contents)
if(D.client)
D.loc = H.loc
else
del(D)
H.visible_message("\red[H] splits apart with a wet slithering noise!")
/datum/species/machine
name = "Machine"
name_plural = "machines"
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
language = "Tradeband"
unarmed_type = /datum/unarmed_attack/punch
rarity_value = 2
eyes = "blank_eyes"
brute_mod = 0.5
burn_mod = 1
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
heat_level_2 = 1000
heat_level_3 = 2000
synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
blood_color = "#1F181F"
flesh_color = "#575757"
has_organ = list(
"heart" = /datum/organ/internal/heart,
"brain" = /datum/organ/internal/brain,
)
// Called when using the shredding behavior.
/datum/species/proc/can_shred(var/mob/living/carbon/human/H)
if(H.a_intent != "hurt")
return 0
if(unarmed.is_usable(H))
if(unarmed.shredding)
return 1
else if(secondary_unarmed.is_usable(H))
if(secondary_unarmed.shredding)
return 1
return 0
//Species unarmed attacks
/datum/unarmed_attack
var/attack_verb = list("attack") // Empty hand hurt intent verb.
var/damage = 0 // Extra empty hand attack damage.
var/attack_sound = "punch"
var/miss_sound = 'sound/weapons/punchmiss.ogg'
var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent.
var/sharp = 0
var/edge = 0
/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user)
if(user.restrained())
return 0
// Check if they have a functioning hand.
var/datum/organ/external/E = user.organs_by_name["l_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
E = user.organs_by_name["r_hand"]
if(E && !(E.status & ORGAN_DESTROYED))
return 1
return 0
/datum/unarmed_attack/bite
attack_verb = list("bite") // 'x has biteed y', needs work.
attack_sound = 'sound/weapons/bite.ogg'
shredding = 0
damage = 5
sharp = 1
edge = 1
/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user)
if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle))
return 0
return 1
/datum/unarmed_attack/punch
attack_verb = list("punch")
damage = 3
/datum/unarmed_attack/diona
attack_verb = list("lash", "bludgeon")
damage = 5
/datum/unarmed_attack/claws
attack_verb = list("scratch", "claw")
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
damage = 5
sharp = 1
edge = 1
/datum/unarmed_attack/claws/strong
attack_verb = list("slash")
damage = 10
shredding = 1
/datum/unarmed_attack/bite/strong
attack_verb = list("maul")
damage = 15
shredding = 1
/datum/hud_data
var/icon // If set, overrides ui_style.
var/has_a_intent = 1 // Set to draw intent box.
var/has_m_intent = 1 // Set to draw move intent box.
var/has_warnings = 1 // Set to draw environment warnings.
var/has_pressure = 1 // Draw the pressure indicator.
var/has_nutrition = 1 // Draw the nutrition indicator.
var/has_bodytemp = 1 // Draw the bodytemp indicator.
var/has_hands = 1 // Set to draw shand.
var/has_drop = 1 // Set to draw drop button.
var/has_throw = 1 // Set to draw throw button.
var/has_resist = 1 // Set to draw resist button.
var/has_internals = 1 // Set to draw the internals toggle button.
var/list/equip_slots = list() // Checked by mob_can_equip().
// Contains information on the position and tag for all inventory slots
// to be drawn for the mob. This is fairly delicate, try to avoid messing with it
// unless you know exactly what it does.
var/list/gear = list(
"i_clothing" = list("loc" = ui_iclothing, "slot" = slot_w_uniform, "state" = "center", "toggle" = 1, "dir" = SOUTH),
"o_clothing" = list("loc" = ui_oclothing, "slot" = slot_wear_suit, "state" = "equip", "toggle" = 1, "dir" = SOUTH),
"mask" = list("loc" = ui_mask, "slot" = slot_wear_mask, "state" = "equip", "toggle" = 1, "dir" = NORTH),
"gloves" = list("loc" = ui_gloves, "slot" = slot_gloves, "state" = "gloves", "toggle" = 1),
"eyes" = list("loc" = ui_glasses, "slot" = slot_glasses, "state" = "glasses","toggle" = 1),
"l_ear" = list("loc" = ui_l_ear, "slot" = slot_l_ear, "state" = "ears", "toggle" = 1),
"r_ear" = list("loc" = ui_r_ear, "slot" = slot_r_ear, "state" = "ears", "toggle" = 1),
"head" = list("loc" = ui_head, "slot" = slot_head, "state" = "hair", "toggle" = 1),
"shoes" = list("loc" = ui_shoes, "slot" = slot_shoes, "state" = "shoes", "toggle" = 1),
"suit storage" = list("loc" = ui_sstore1, "slot" = slot_s_store, "state" = "belt", "dir" = 8),
"back" = list("loc" = ui_back, "slot" = slot_back, "state" = "back", "dir" = NORTH),
"id" = list("loc" = ui_id, "slot" = slot_wear_id, "state" = "id", "dir" = NORTH),
"storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"),
"storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"),
"belt" = list("loc" = ui_belt, "slot" = slot_belt, "state" = "belt")
)
/datum/hud_data/New()
..()
for(var/slot in gear)
equip_slots |= gear[slot]["slot"]
if(has_hands)
equip_slots |= slot_l_hand
equip_slots |= slot_r_hand
equip_slots |= slot_handcuffed
if(slot_back in equip_slots)
equip_slots |= slot_in_backpack
equip_slots |= slot_legcuffed
@@ -171,24 +171,28 @@ Please contact me on #coderbus IRC. ~Carn x
if(istype(I)) overlays += I
I = overlays_standing[R_HAND_LAYER]
if(istype(I)) overlays += I
else
else if (icon_update)
icon = stand_icon
for(var/image/I in overlays_standing)
overlays += I
if(lying)
if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone.
var/matrix/M = matrix()
M.Turn(90)
M.Scale(size_multiplier)
M.Translate(1,-6)
src.transform = M
else
var/matrix/M = matrix()
M.Scale(size_multiplier)
M.Translate(0, 16*(size_multiplier-1))
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
// TODO: Convert dam_human.dmi to greyscale and blend in species.blood_colour here.
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
@@ -392,7 +396,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(!fat && !skeleton)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
if(undershirt>0 && undershirt < 5 && species.flags & HAS_UNDERWEAR)
if(undershirt>0 && undershirt <= undershirt_t.len && species.flags & HAS_UNDERWEAR)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "undershirt[undershirt]_s"), ICON_OVERLAY)
if(update_icons)
@@ -424,7 +428,7 @@ proc/get_damage_icon_part(damage_state, body_part)
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)
if(facial_hair_style && facial_hair_style.species_allowed && 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)
@@ -703,7 +707,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(update_icons) update_icons()
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
if(shoes)
if(shoes && !(wear_suit && wear_suit.flags_inv & HIDESHOES))
var/image/standing
if(shoes.icon_override)
@@ -838,7 +842,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/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) ) )
if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) && !(head && head.flags_inv & HIDEMASK))
wear_mask.screen_loc = ui_mask //TODO
var/image/standing
@@ -945,7 +949,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/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(species.tail)
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
@@ -1,2 +1,2 @@
/mob/living/carbon/slime/proc/regular_hud_updates()
/mob/living/carbon/slime/regular_hud_updates()
return
@@ -362,11 +362,11 @@
else
for(var/mob/living/carbon/C in targets)
if(!Discipline && prob(5))
if(ishuman(C) || isalienadult(C))
if(ishuman(C))
Target = C
break
if(islarva(C) || ismonkey(C))
if(isalien(C) || ismonkey(C))
Target = C
break
@@ -51,7 +51,12 @@
var/coretype = /obj/item/slime_extract/grey
var/list/slime_mutation[4]
var/core_removal_stage = 0 //For removing cores.
/mob/living/carbon/slime/New()
verbs += /mob/living/proc/ventcrawl
create_reagents(100)
spawn (0)
number = rand(1, 1000)
@@ -272,7 +277,7 @@
updatehealth()
return
/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M as mob)
/mob/living/carbon/slime/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
@@ -445,93 +450,6 @@
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
return
/mob/living/carbon/slime/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")
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
if ("hurt")
if (prob(95))
attacked += 10
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if (damage >= 25)
damage = rand(20, 40)
visible_message("<span class='danger'>[M] has attacked [name]!</span>", \
"<span class='userdanger'>[M] has attacked [name]!</span>")
else
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
"<span class='userdanger'>)[M] has wounded [name]!</span>")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>")
if ("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)
G.synch()
LAssailant = M
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='warning'> [M] has grabbed [name] passively!</span>")
if ("disarm")
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
var/damage = 5
attacked += 10
if(prob(95))
visible_message("<span class='danger'>[M] has tackled [name]!</span>", \
"<span class='userdanger'>[M] has tackled [name]!</span>")
if(Victim || Target)
Victim = null
Target = null
anchored = 0
if(prob(80) && !client)
Discipline++
if(!istype(src, /mob/living/carbon/slime))
if(Discipline == 1)
attacked = 0
spawn()
SStun = 1
sleep(rand(5,20))
SStun = 0
spawn(0)
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
else
drop_item()
visible_message("<span class='danger'>[M] has disarmed [name]!</span>",
"<span class='userdanger'>[M] has disarmed [name]!</span>")
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/slime/attackby(obj/item/W, mob/user)
if(W.force > 0)
attacked += 10
@@ -613,6 +531,11 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
++Discipline
return
/mob/living/carbon/slime/can_use_vents()
if(Victim)
return "You cannot ventcrawl while feeding."
..()
/obj/item/slime_extract
name = "slime extract"
desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"."
@@ -984,6 +907,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
if(A)
G << "Golem rune created in [A.name]."
/mob/living/carbon/slime/has_eyes()
return 0
//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them////////////////////////
/*
@@ -104,7 +104,7 @@
adjustBruteLoss(-10)
adjustFireLoss(-10)
adjustCloneLoss(-10)
updatehealth()
if(Victim)
Victim.updatehealth()
@@ -225,11 +225,4 @@
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()
src << "<i>I am not old enough to reproduce yet...</i>"
@@ -99,8 +99,8 @@
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
return
M.status_flags &= ~PASSEMOTES
/mob/living/carbon/monkey/diona/verb/fertilize_plant()
/*
/living/carbon/monkey/diona/verb/fertilize_plant()
set category = "Diona"
set name = "Fertilize plant"
@@ -137,7 +137,7 @@
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"
+9 -11
View File
@@ -23,16 +23,14 @@
environment = loc.return_air()
if (stat != DEAD)
if(!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)
//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()
@@ -489,7 +487,7 @@
silent = 0
else //ALIVE. LIGHTS ARE ON
updatehealth()
if(health < config.health_threshold_dead || brain_op_stage == 4.0)
if(health < config.health_threshold_dead || !has_brain())
death()
blinded = 1
stat = DEAD
@@ -42,6 +42,8 @@
reagents = R
R.my_atom = src
verbs += /mob/living/proc/ventcrawl
if(name == initial(name)) //To stop Pun-Pun becoming generic.
name = "[name] ([rand(1, 1000)])"
real_name = name
+33 -11
View File
@@ -626,7 +626,16 @@
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.
var/can_break_cuffs
if(HULK in usr.mutations)
can_break_cuffs = 1
else if(istype(CM,/mob/living/carbon/human))
var/mob/living/carbon/human/H = CM
if(H.species.can_shred(H))
can_break_cuffs = 1
if(can_break_cuffs) //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)
@@ -663,7 +672,16 @@
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.
var/can_break_cuffs
if(HULK in usr.mutations)
can_break_cuffs = 1
else if(istype(CM,/mob/living/carbon/human))
var/mob/living/carbon/human/H = CM
if(H.species.can_shred(H))
can_break_cuffs = 1
if(can_break_cuffs) //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)
@@ -714,6 +732,11 @@
src << "You can't vent crawl while you're stunned!"
return
var/special_fail_msg = can_use_vents()
if(special_fail_msg)
src << "\red [special_fail_msg]"
return
if(vent_found) // one was passed in, probably from vent/AltClick()
if(vent_found.welded)
src << "That vent is welded shut."
@@ -800,17 +823,16 @@
if(new_area)
new_area.Entered(src)
/mob/living/proc/can_use_vents()
return "You can't fit into that vent."
/mob/living/update_gravity(var/has_gravity)
if(!ticker)
return
float(!has_gravity)
/*
/mob/living/proc/float(on)
if(on && !floating)
animate(src, pixel_y = 2, time = 10, loop = -1)
floating = 1
else if(!on && floating)
animate(src, pixel_y = initial(pixel_y), time = 10)
floating = 0
*/
/mob/living/proc/has_brain()
return 1
/mob/living/proc/has_eyes()
return 1
@@ -55,6 +55,14 @@
src.visible_message("\red [src] triggers their deadman's switch!")
signaler.signal()
//Stun Beams
if(istype(P, /obj/item/projectile/bullet/stunshot))
stun_effect_act(0, P.agony, def_zone, P)
src <<"\red You have been hit by [P]!"
del P
return
//Armor
var/absorb = run_armor_check(def_zone, P.flag)
var/proj_sharp = is_sharp(P)
var/proj_edge = has_edge(P)
@@ -42,3 +42,11 @@
var/on_fire = 0 //The "Are we on fire?" var
var/fire_stacks = 0 //Tracks how many stacks of fire we have on, max is usually 20
var/silent = null //Can't talk. Value goes down every life proc.
// Putting these here for attack_animal().
var/melee_damage_lower = 0
var/melee_damage_upper = 0
var/attacktext = "attacks"
var/attack_sound = null
var/friendly = "nuzzles"
var/wall_smash = 0
+18
View File
@@ -0,0 +1,18 @@
/mob/living/proc/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Abilities"
handle_ventcrawl()
return
/mob/living/proc/hide()
set name = "Hide"
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
set category = "Abilities"
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\blue You are now hiding.")
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
+1
View File
@@ -3,6 +3,7 @@ var/list/department_radio_keys = list(
":l" = "left ear", "#l" = "left ear", ".l" = "left ear",
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
":h" = "department", "#h" = "department", ".h" = "department",
":+" = "special", "#+" = "special", ".+" = "special", //activate radio-specific special functions
":c" = "Command", "#c" = "Command", ".c" = "Command",
":n" = "Science", "#n" = "Science", ".n" = "Science",
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
@@ -1,9 +1,3 @@
/mob/living/silicon/pai/proc/regular_hud_updates()
if(client)
for(var/image/hud in client.images)
if(copytext(hud.icon_state,1,4) == "hud")
client.images -= hud
/mob/living/silicon/pai/proc/securityHUD()
if(client)
var/image/holder
@@ -694,8 +694,12 @@
translator_on = 0
remove_language("Sinta'unathi")
remove_language("Siik'tajr")
// remove_language("Siik'tajr")
remove_language("Siik'Maas")
remove_language("Skrellian")
remove_language("Vox-pidgin")
remove_language("Rootspeak")
remove_language("Sign language")
src << "\blue Translator Module toggled OFF."
@@ -703,7 +707,11 @@
translator_on = 1
add_language("Sinta'unathi")
add_language("Siik'tajr")
// add_language("Siik'tajr")
add_language("Siik'Maas")
add_language("Skrellian")
add_language("Vox-pidgin")
add_language("Rootspeak")
add_language("Sign language")
src << "\blue Translator Module toggled ON."
@@ -29,6 +29,8 @@
/mob/living/silicon/robot/drone/New()
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
if(camera && "Robots" in camera.network)
camera.network.Add("Engineering")
@@ -21,18 +21,6 @@
return
/mob/living/silicon/robot/drone/verb/hide()
set name = "Hide"
set desc = "Allows you to hide beneath tables or certain items. Toggled on or off."
set category = "Drone"
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\blue You are now hiding.")
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
/mob/living/silicon/robot/drone/verb/light()
set name = "Light On/Off"
set desc = "Activate a low power omnidirectional LED. Toggled on or off."
@@ -0,0 +1,207 @@
/datum/game_mode/var/list/borers = list()
/mob/living/simple_animal/borer
name = "cortical borer"
real_name = "cortical borer"
desc = "A small, quivering sluglike creature."
speak_emote = list("chirrups")
emote_hear = list("chirrups")
response_help = "pokes"
response_disarm = "prods the"
response_harm = "stomps on the"
icon_state = "brainslug"
icon_living = "brainslug"
icon_dead = "brainslug_dead"
speed = 5
a_intent = "harm"
stop_automated_movement = 1
status_flags = CANPUSH
attacktext = "nips"
friendly = "prods"
wander = 0
pass_flags = PASSTABLE
universal_understand = 1
holder_type = /obj/item/weapon/holder/borer
var/used_dominate
var/chemicals = 10 // Chemicals used for reproduction and spitting neurotoxin.
var/mob/living/carbon/human/host // Human host for the brain worm.
var/truename // Name used for brainworm-speak.
var/mob/living/captive_brain/host_brain // Used for swapping control of the body back and forth.
var/controlling // Used in human death check.
var/docile = 0 // Sugar can stop borers from acting.
var/has_reproduced
var/roundstart
/mob/living/simple_animal/borer/roundstart
roundstart = 1
/mob/living/simple_animal/borer/New()
..()
add_language("Cortical Link")
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]"
if(!roundstart) request_player()
/mob/living/simple_animal/borer/Life()
..()
if(host)
if(!stat && !host.stat)
if(host.reagents.has_reagent("sugar"))
if(!docile)
if(controlling)
host << "\blue You feel the soporific flow of sugar in your host's blood, lulling you into docility."
else
src << "\blue You feel the soporific flow of sugar in your host's blood, lulling you into docility."
docile = 1
else
if(docile)
if(controlling)
host << "\blue You shake off your lethargy as the sugar leaves your host's blood."
else
src << "\blue You shake off your lethargy as the sugar leaves your host's blood."
docile = 0
if(chemicals < 250)
chemicals++
if(controlling)
if(docile)
host << "\blue You are feeling far too docile to continue controlling your host..."
host.release_control()
return
if(prob(5))
host.adjustBrainLoss(rand(1,2))
if(prob(host.brainloss/20))
host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_s","gasp"))]")
/mob/living/simple_animal/borer/Stat()
..()
statpanel("Status")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
stat(null, eta_status)
if (client.statpanel == "Status")
stat("Chemicals", chemicals)
/mob/living/simple_animal/borer/proc/detatch()
if(!host || !controlling) return
if(istype(host,/mob/living/carbon/human))
var/mob/living/carbon/human/H = host
var/datum/organ/external/head = H.get_organ("head")
head.implants -= src
controlling = 0
host.remove_language("Cortical Link")
host.verbs -= /mob/living/carbon/proc/release_control
host.verbs -= /mob/living/carbon/proc/punish_host
host.verbs -= /mob/living/carbon/proc/spawn_larvae
if(host_brain)
// these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed.
// computer_id and IP are not updated magically on their own in offline mobs -walter0o
// host -> self
var/h2s_id = host.computer_id
var/h2s_ip= host.lastKnownIP
host.computer_id = null
host.lastKnownIP = null
src.ckey = host.ckey
if(!src.computer_id)
src.computer_id = h2s_id
if(!host_brain.lastKnownIP)
src.lastKnownIP = h2s_ip
// brain -> host
var/b2h_id = host_brain.computer_id
var/b2h_ip= host_brain.lastKnownIP
host_brain.computer_id = null
host_brain.lastKnownIP = null
host.ckey = host_brain.ckey
if(!host.computer_id)
host.computer_id = b2h_id
if(!host.lastKnownIP)
host.lastKnownIP = b2h_ip
del(host_brain)
/mob/living/simple_animal/borer/proc/leave_host()
if(!host) return
if(host.mind)
//If they're not a proper traitor, reset their antag status.
if(host.mind.special_role == "Borer Thrall")
host << "<span class ='danger'>You are no longer an antagonist.</span>"
ticker.mode.borers -= host.mind
host.mind.special_role = null
src.loc = get_turf(host)
reset_view(null)
machine = null
host.reset_view(null)
host.machine = null
var/mob/living/H = host
H.status_flags &= ~PASSEMOTES
host = null
return
//Procs for grabbing players.
/mob/living/simple_animal/borer/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Syndicate"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_ALIEN)
question(O.client)
/mob/living/simple_animal/borer/proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "A cortical borer needs a player. Are you interested?", "Cortical borer request", "Yes", "No", "Never for this round")
if(!C || ckey)
return
if(response == "Yes")
transfer_personality(C)
else if (response == "Never for this round")
C.prefs.be_special ^= BE_ALIEN
/mob/living/simple_animal/borer/proc/transfer_personality(var/client/candidate)
if(!candidate)
return
src.mind = candidate.mob.mind
src.ckey = candidate.ckey
if(src.mind)
src.mind.assigned_role = "Cortical Borer"
src.mind.special_role = "Cortical Borer"
ticker.mode.borers |= src.mind
/mob/living/simple_animal/borer/can_use_vents()
return
@@ -0,0 +1,35 @@
/mob/living/captive_brain
name = "host brain"
real_name = "host brain"
universal_understand = 1
/mob/living/captive_brain/say(var/message)
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
if(istype(src.loc,/mob/living/simple_animal/borer))
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if (!message)
return
log_say("[key_name(src)] : [message]")
if (stat == 2)
return say_dead(message)
var/mob/living/simple_animal/borer/B = src.loc
src << "You whisper silently, \"[message]\""
B.host << "The captive mind of [src] whispers, \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
M << "The captive mind of [src] whispers, \"[message]\""
/mob/living/captive_brain/emote(var/message)
return
@@ -0,0 +1,351 @@
/mob/living/simple_animal/borer/verb/release_host()
set category = "Abilities"
set name = "Release Host"
set desc = "Slither out of your host."
if(!host)
src << "You are not inside a host body."
return
if(stat)
src << "You cannot leave your host in your current state."
if(docile)
src << "\blue You are feeling far too docile to do that."
return
if(!host || !src) return
src << "You begin disconnecting from [host]'s synapses and prodding at their internal ear canal."
if(!host.stat)
host << "An odd, uncomfortable pressure begins to build inside your skull, behind your ear..."
spawn(100)
if(!host || !src) return
if(src.stat)
src << "You cannot release your host in your current state."
return
src << "You wiggle out of [host]'s ear and plop to the ground."
if(host.mind)
if(!host.stat)
host << "<span class='danger'>Something slimy wiggles out of your ear and plops to the ground!</span>"
host << "<span class='danger'>As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again.</span>"
detatch()
leave_host()
/mob/living/simple_animal/borer/verb/infest()
set category = "Abilities"
set name = "Infest"
set desc = "Infest a suitable humanoid host."
if(host)
src << "You are already within a host."
return
if(stat)
src << "You cannot infest a target in your current state."
return
var/list/choices = list()
for(var/mob/living/carbon/C in view(1,src))
if(src.Adjacent(C))
choices += C
var/mob/living/carbon/M = input(src,"Who do you wish to infest?") in null|choices
if(!M || !src) return
if(!(src.Adjacent(M))) return
if(M.has_brain_worms())
src << "You cannot infest someone who is already infested!"
return
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(!H.species.has_organ["brain"])
src << "\The [H] does not seem to have an ear canal to breach."
return
if(H.check_head_coverage())
src << "You cannot get through that host's protective gear."
return
M << "Something slimy begins probing at the opening of your ear canal..."
src << "You slither up [M] and begin probing at their ear canal..."
if(!do_after(src,30))
src << "As [M] moves away, you are dislodged and fall to the ground."
return
if(!M || !src) return
if(src.stat)
src << "You cannot infest a target in your current state."
return
if(M in view(1, src))
src << "You wiggle into [M]'s ear."
if(!M.stat)
M << "Something disgusting and slimy wiggles into your ear!"
src.host = M
src.host.status_flags |= PASSEMOTES
src.loc = M
//Update their traitor status.
if(host.mind)
if(!host.mind.special_role)
ticker.mode.borers |= host.mind
host.mind.special_role = "Borer Thrall"
host << "<span class='danger'>A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine.</span>"
host << "<span class = 'danger'>You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head.</span>"
show_generic_antag_text(host.mind)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/datum/organ/internal/I = H.internal_organs_by_name["brain"]
if(!I) // No brain organ, so the borer moves in and replaces it permanently.
replace_brain()
else
// If they're in normally, implant removal can get them out.
var/datum/organ/external/head = H.get_organ("head")
head.implants += src
return
else
src << "They are no longer in range!"
return
/mob/living/simple_animal/borer/verb/devour_brain()
set category = "Abilities"
set name = "Devour Brain"
set desc = "Take permanent control of a dead host."
if(!host)
src << "You are not inside a host body."
return
if(host.stat != 2)
src << "Your host is still alive."
return
if(stat)
src << "You cannot do that in your current state."
if(docile)
src << "\blue You are feeling far too docile to do that."
return
src << "<span class = 'danger'>It only takes a few moments to render the dead host brain down into a nutrient-rich slurry...</span>"
replace_brain()
// BRAIN WORM ZOMBIES AAAAH.
/mob/living/simple_animal/borer/proc/replace_brain()
var/mob/living/carbon/human/H = host
if(!istype(host))
src << "This host does not have a suitable brain."
return
src << "<span class = 'danger'>You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H].</span>"
H.add_language("Cortical Link")
if(host.stat == 2)
H.verbs |= /mob/living/carbon/human/proc/jumpstart
H.verbs |= /mob/living/carbon/human/proc/psychic_whisper
H.verbs |= /mob/living/carbon/human/proc/tackle
H.verbs |= /mob/living/carbon/proc/spawn_larvae
if(H.client)
H.ghostize(0)
if(src.mind)
src.mind.special_role = "Borer Husk"
src.mind.transfer_to(host)
H.ChangeToHusk()
var/datum/organ/internal/borer/B = new(H)
H.internal_organs_by_name["brain"] = B
H.internal_organs |= B
var/datum/organ/external/affecting = H.get_organ("head")
affecting.implants -= src
var/s2h_id = src.computer_id
var/s2h_ip= src.lastKnownIP
src.computer_id = null
src.lastKnownIP = null
if(!H.computer_id)
H.computer_id = s2h_id
if(!H.lastKnownIP)
H.lastKnownIP = s2h_ip
/mob/living/simple_animal/borer/verb/secrete_chemicals()
set category = "Abilities"
set name = "Secrete Chemicals"
set desc = "Push some chemicals into your host's bloodstream."
if(!host)
src << "You are not inside a host body."
return
if(stat)
src << "You cannot secrete chemicals in your current state."
if(docile)
src << "\blue You are feeling far too docile to do that."
return
if(chemicals < 50)
src << "You don't have enough chemicals!"
var/chem = input("Select a chemical to secrete.", "Chemicals") in list("bicaridine","tramadol","hyperzine","alkysine")
if(chemicals < 50 || !host || controlling || !src || stat) //Sanity check.
return
src << "\red <B>You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream.</B>"
host.reagents.add_reagent(chem, 10)
chemicals -= 50
/mob/living/simple_animal/borer/verb/dominate_victim()
set category = "Abilities"
set name = "Paralyze Victim"
set desc = "Freeze the limbs of a potential host with supernatural fear."
if(world.time - used_dominate < 150)
src << "You cannot use that ability again so soon."
return
if(host)
src << "You cannot do that from within a host body."
return
if(src.stat)
src << "You cannot do that in your current state."
return
var/list/choices = list()
for(var/mob/living/carbon/C in view(3,src))
if(C.stat != 2)
choices += C
if(world.time - used_dominate < 150)
src << "You cannot use that ability again so soon."
return
var/mob/living/carbon/M = input(src,"Who do you wish to dominate?") in null|choices
if(!M || !src) return
if(M.has_brain_worms())
src << "You cannot infest someone who is already infested!"
return
src << "\red You focus your psychic lance on [M] and freeze their limbs with a wave of terrible dread."
M << "\red You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing."
M.Weaken(10)
used_dominate = world.time
/mob/living/simple_animal/borer/verb/bond_brain()
set category = "Abilities"
set name = "Assume Control"
set desc = "Fully connect to the brain of your host."
if(!host)
src << "You are not inside a host body."
return
if(src.stat)
src << "You cannot do that in your current state."
return
if(docile)
src << "\blue You are feeling far too docile to do that."
return
src << "You begin delicately adjusting your connection to the host brain..."
spawn(100+(host.brainloss*5))
if(!host || !src || controlling)
return
else
src << "\red <B>You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.</B>"
host << "\red <B>You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours.</B>"
host.add_language("Cortical Link")
// host -> brain
var/h2b_id = host.computer_id
var/h2b_ip= host.lastKnownIP
host.computer_id = null
host.lastKnownIP = null
del(host_brain)
host_brain = new(src)
host_brain.ckey = host.ckey
host_brain.name = host.name
if(!host_brain.computer_id)
host_brain.computer_id = h2b_id
if(!host_brain.lastKnownIP)
host_brain.lastKnownIP = h2b_ip
// self -> host
var/s2h_id = src.computer_id
var/s2h_ip= src.lastKnownIP
src.computer_id = null
src.lastKnownIP = null
host.ckey = src.ckey
if(!host.computer_id)
host.computer_id = s2h_id
if(!host.lastKnownIP)
host.lastKnownIP = s2h_ip
controlling = 1
host.verbs += /mob/living/carbon/proc/release_control
host.verbs += /mob/living/carbon/proc/punish_host
host.verbs += /mob/living/carbon/proc/spawn_larvae
return
/mob/living/carbon/human/proc/jumpstart()
set category = "Abilities"
set name = "Revive Host"
set desc = "Send a jolt of electricity through your host, reviving them."
if(stat != 2)
usr << "Your host is already alive."
return
verbs -= /mob/living/carbon/human/proc/jumpstart
visible_message("<span class='warning'>With a hideous, rattling moan, [src] shudders back to life!</span>")
rejuvenate()
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
update_canmove()
@@ -0,0 +1,42 @@
/mob/living/simple_animal/borer/say(var/message)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = capitalize(message)
if(!message)
return
if (stat == 2)
return say_dead(message)
if (stat)
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
if (copytext(message, 1, 2) == "*")
return emote(copytext(message, 2))
var/datum/language/L = parse_language(message)
if(L && L.flags & HIVEMIND)
L.broadcast(src,trim(copytext(message,3)),src.truename)
return
if(!host)
//TODO: have this pick a random mob within 3 tiles to speak for the borer.
src << "You have no host to speak to."
return //No host, no audible speech.
src << "You drop words into [host]'s mind: \"[message]\""
host << "Your own thoughts speak: \"[message]\""
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
M << "[src.truename] whispers to [host], \"[message]\""
@@ -76,6 +76,15 @@
//RUNTIME IS ALIVE! SQUEEEEEEEE~
/mob/living/simple_animal/cat/Runtime
name = "Runtime"
desc = "Its fur has the look and feel of velvet, and its tail quivers occasionally."
desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally."
icon_state = "cat"
icon_living = "cat"
icon_dead = "cat_dead"
/mob/living/simple_animal/cat/kitten
name = "kitten"
desc = "D'aaawwww"
icon_state = "kitten"
icon_living = "kitten"
icon_dead = "kitten_dead"
gender = NEUTER
@@ -51,6 +51,10 @@
/mob/living/simple_animal/mouse/New()
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
name = "[name] ([rand(1, 1000)])"
if(!body_color)
body_color = pick( list("brown","gray","white") )
@@ -59,7 +63,6 @@
icon_dead = "mouse_[body_color]_dead"
desc = "It's a small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
/mob/living/simple_animal/mouse/proc/splat()
src.health = 0
src.stat = DEAD
@@ -69,59 +72,6 @@
if(client)
client.time_died_as_mouse = world.time
/mob/living/simple_animal/mouse/verb/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Mouse"
handle_ventcrawl()
return
//copy paste from alien/larva, if that func is updated please update this one alsoghost
/mob/living/simple_animal/mouse/verb/hide()
set name = "Hide"
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
set category = "Mouse"
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\blue 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("\blue 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)
*/
//make mice fit under tables etc? this was hacky, and not working
/*
/mob/living/simple_animal/mouse/Move(var/dir)
var/turf/target_turf = get_step(src,dir)
//CanReachThrough(src.loc, target_turf, src)
var/can_fit_under = 0
if(target_turf.ZCanPass(get_turf(src),1))
can_fit_under = 1
..(dir)
if(can_fit_under)
src.loc = target_turf
for(var/d in cardinal)
var/turf/O = get_step(T,d)
//Simple pass check.
if(O.ZCanPass(T, 1) && !(O in open) && !(O in closed) && O in possibles)
open += O
*/
///mob/living/simple_animal/mouse/restrained() //Hotfix to stop mice from doing things with MouseDrop
// return 1
/mob/living/simple_animal/mouse/start_pulling(var/atom/movable/AM)//Prevents mouse from pulling things
src << "<span class='warning'>You are too small to pull anything.</span>"
return
@@ -163,3 +113,6 @@
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "splats"
/mob/living/simple_animal/mouse/can_use_vents()
return
@@ -200,6 +200,9 @@
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
/mob/living/simple_animal/spiderbot/death()
living_mob_list -= src
@@ -215,65 +218,6 @@
src.Del()
return
//copy paste from alien/larva, if that func is updated please update this one also
/mob/living/simple_animal/spiderbot/verb/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Spiderbot"
// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent))
// return
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
var/welded = 0
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
vent_found = v
break
else
welded = 1
if(vent_found)
if(vent_found.network&&vent_found.network.normal_members.len)
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
if(temp_vent.loc == loc)
continue
vents.Add(temp_vent)
var/list/choices = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
if(vent.loc.z != loc.z)
continue
var/atom/a = get_turf(vent)
choices.Add(a.loc)
var/turf/startloc = loc
var/obj/selection = input("Select a destination.", "Duct System") in choices
var/selection_position = choices.Find(selection)
if(loc==startloc)
var/obj/target_vent = vents[selection_position]
if(target_vent)
loc = target_vent.loc
else
src << "\blue You need to remain still while entering a vent."
else
src << "\blue This vent is not connected to anything."
else if(welded)
src << "\red That vent is welded."
else
src << "\blue You must be standing on or beside an air vent to enter it."
return
//copy paste from alien/larva, if that func is updated please update this one alsoghost
/mob/living/simple_animal/spiderbot/verb/hide()
set name = "Hide"
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
set category = "Spiderbot"
if (layer != TURF_LAYER+0.2)
layer = TURF_LAYER+0.2
src << text("\blue You are now hiding.")
else
layer = MOB_LAYER
src << text("\blue You have stopped hiding.")
//Cannibalized from the parrot mob. ~Zuhayr
/mob/living/simple_animal/spiderbot/verb/drop_held_item()
@@ -47,12 +47,12 @@
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
var/melee_damage_lower = 0
var/melee_damage_upper = 0
var/attacktext = "attacks"
var/attack_sound = null
var/friendly = "nuzzles" //If the mob does no damage with it's attack
var/wall_smash = 0 //if they can smash walls
melee_damage_lower = 0
melee_damage_upper = 0
attacktext = "attacks"
attack_sound = null
friendly = "nuzzles" //If the mob does no damage with it's attack
wall_smash = 0 //if they can smash walls
var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
@@ -228,7 +228,7 @@
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
if(!Proj || Proj.nodamage)
return
adjustBruteLoss(Proj.damage)
return 0
+31
View File
@@ -728,6 +728,28 @@ note dizziness decrements automatically in the mob's Life() proc.
stat(null,"MasterController-ERROR")
if(delta_level:active)
stat(null,"Delta Countdown-[delta_level.timeleft()]")
if(!ooc_allowed)
stat(null,"OOC is globaly muted")
if(!looc_allowed)
stat(null,"LOOC is globaly muted")
if(client.holder.rights & (R_ADMIN|R_MOD))
var/players = 0
var/ghosts = 0
var/lobby = 0
var/total = 0
var/staff = 0
for(var/client/C in clients)
if(C.holder.rights & R_ADMIN || C.holder.rights & R_MOD)
staff++
if(istype(C.mob, /mob/living))
players++
if(istype(C.mob, /mob/dead))
ghosts++
if(istype(C.mob, /mob/new_player))
lobby++
total++
stat(null, "Players: [total]\tModeration Staff: [staff]")
stat(null, "Living: [players]\tGhosts: [ghosts]\tLobby: [lobby]")
if(listed_turf && client)
if(!TurfAdjacent(listed_turf))
@@ -1063,3 +1085,12 @@ mob/proc/yank_out_object()
if(paralysis)
AdjustParalysis(-1)
return paralysis
//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
+14 -2
View File
@@ -191,10 +191,22 @@
return
if(M == assailant && state >= GRAB_AGGRESSIVE)
if( (ishuman(user) && (FAT in user.mutations) && ismonkey(affecting) ) || ( isalien(user) && iscarbon(affecting) ) )
var/can_eat
if((FAT in user.mutations) && ismonkey(affecting))
can_eat = 1
else
var/mob/living/carbon/human/H = user
if(istype(H) && iscarbon(affecting) && H.species.gluttonous)
if(H.species.gluttonous == 2)
can_eat = 2
else if(!ishuman(affecting))
can_eat = 1
if(can_eat)
var/mob/living/carbon/attacker = user
user.visible_message("<span class='danger'>[user] is attempting to devour [affecting]!</span>")
if(istype(user, /mob/living/carbon/alien/humanoid/hunter))
if(can_eat == 2)
if(!do_mob(user, affecting)||!do_after(user, 30)) return
else
if(!do_mob(user, affecting)||!do_after(user, 100)) return
+24
View File
@@ -115,6 +115,17 @@ proc/isorgan(A)
return 1
return 0
proc/isdeaf(A)
if(istype(A, /mob))
var/mob/M = A
return (M.sdisabilities & DEAF) || M.ear_deaf
return 0
proc/isnewplayer(A)
if(istype(A, /mob/new_player))
return 1
return 0
proc/hasorgans(A)
return ishuman(A)
@@ -412,3 +423,16 @@ var/list/intents = list("help","disarm","grab","hurt")
hud_used.action_intent.icon_state = "harm"
else
hud_used.action_intent.icon_state = "help"
/proc/broadcast_security_hud_message(var/message, var/broadcast_source)
broadcast_hud_message(message, broadcast_source, sec_hud_users, /obj/item/clothing/glasses/hud/security)
/proc/broadcast_medical_hud_message(var/message, var/broadcast_source)
broadcast_hud_message(message, broadcast_source, med_hud_users, /obj/item/clothing/glasses/hud/health)
/proc/broadcast_hud_message(var/message, var/broadcast_source, var/list/targets, var/icon)
var/turf/sourceturf = get_turf(broadcast_source)
for(var/mob/M in targets)
var/turf/targetturf = get_turf(M)
if((targetturf.z == sourceturf.z))
M.show_message("<span class='info'>\icon[icon] [message]</span>", 1)
@@ -2,7 +2,7 @@
//This proc is the most basic of the procs. All it does is make a new mob on the same tile and transfer over a few variables.
//Returns the new mob
//Note that this proc does NOT do MMI related stuff!
/mob/proc/change_mob_type(var/new_type = null, var/turf/location = null, var/new_name = null as text, var/delete_old_mob = 0 as num)
/mob/proc/change_mob_type(var/new_type = null, var/turf/location = null, var/new_name = null as text, var/delete_old_mob = 0 as num, var/subspecies)
if(istype(src,/mob/new_player))
usr << "\red cannot convert players who have not entered yet."
@@ -48,6 +48,10 @@
else
M.key = key
if(subspecies && istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
H.set_species(subspecies)
if(delete_old_mob)
spawn(1)
del(src)
+22 -5
View File
@@ -284,7 +284,7 @@
return 1
proc/AttemptLateSpawn(rank)
proc/AttemptLateSpawn(rank,var/spawning_at)
if (src != usr)
return 0
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
@@ -306,7 +306,21 @@
job_master.EquipRank(character, rank, 1) //equips the human
UpdateFactionList(character)
EquipCustomItems(character)
character.loc = pick(latejoin)
//Find our spawning point.
var/join_message
var/datum/spawnpoint/S
if(spawning_at)
S = spawntypes[spawning_at]
if(S && istype(S))
character.loc = pick(S.turfs)
join_message = S.msg
else
character.loc = pick(latejoin)
join_message = "has arrived on the station"
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/stool/bed/chair/wheelchair))
@@ -320,18 +334,21 @@
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
AnnounceArrival(character, rank)
//Grab some data from the character prefs for use in random news procs.
AnnounceArrival(character, rank, join_message)
else
character.Robotize()
del(src)
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI.
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] has arrived on the station.", "Arrivals Announcement Computer")
a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
del(a)
proc/LateChoices()
@@ -208,7 +208,7 @@ datum/preferences
preview_icon.Blend(temp, ICON_OVERLAY)
//Tail
if(current_species && (current_species.flags & HAS_TAIL))
if(current_species && (current_species.tail))
var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
preview_icon.Blend(temp, ICON_OVERLAY)
@@ -239,11 +239,11 @@ datum/preferences
eyes_s.Blend(facial_s, ICON_OVERLAY)
var/icon/underwear_s = null
if(underwear > 0 && underwear < 7 && current_species.flags & HAS_UNDERWEAR)
if(underwear > 0 && underwear < 7 && (current_species && (current_species.flags & HAS_UNDERWEAR)))
underwear_s = new/icon("icon" = 'icons/mob/human.dmi', "icon_state" = "underwear[underwear]_[g]_s")
var/icon/undershirt_s = null
if(undershirt > 0 && undershirt < 16 && current_species.flags & HAS_UNDERWEAR)
if(undershirt > 0 && undershirt < 16 && (current_species && (current_species.flags & HAS_UNDERWEAR)))
undershirt_s = new/icon("icon" = 'icons/mob/human.dmi', "icon_state" = "undershirt[undershirt]_s")
var/icon/clothes_s = null
@@ -451,6 +451,19 @@ datum/preferences
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-tox"), ICON_OVERLAY)
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
if(XENOBIOLOGIST)
clothes_s = new /icon('icons/mob/uniform.dmi', "sciencewhite_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_tox_open"), ICON_OVERLAY)
if(prob(1))
clothes_s.Blend(new /icon('icons/mob/head.dmi', "metroid"), ICON_OVERLAY)
switch(backbag)
if(2)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY)
if(3)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel-tox"), ICON_OVERLAY)
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
if(CHEMIST)
clothes_s = new /icon('icons/mob/uniform.dmi', "chemistrywhite_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "white"), ICON_UNDERLAY)
+1 -8
View File
@@ -198,14 +198,7 @@
del(t)
var/alien_caste = pick("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)
var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc)
new_xeno.a_intent = "hurt"
new_xeno.key = key
+99 -40
View File
@@ -30,8 +30,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
/mob/living/carbon/human/proc/fixblood()
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.id == "blood")
B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type, \
B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.blood_color,"blood_type"=dna.b_type, \
"resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = null)
B.color = B.data["blood_colour"]
// Takes care blood loss and regeneration
/mob/living/carbon/human/proc/handle_blood()
@@ -63,14 +64,17 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"]
if(species && species.has_organ["heart"])
var/datum/organ/internal/heart/heart = internal_organs_by_name["heart"]
if(heart.damage > 1 && heart.damage < heart.min_bruised_damage)
blood_volume *= 0.8
else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage)
blood_volume *= 0.6
else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY)
blood_volume *= 0.3
if(!heart)
blood_volume = 0
else if(heart.damage > 1 && heart.damage < heart.min_bruised_damage)
blood_volume *= 0.8
else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage)
blood_volume *= 0.6
else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY)
blood_volume *= 0.3
//Effects of bloodloss
switch(blood_volume)
@@ -141,31 +145,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if(!amt)
return
var/turf/T = get_turf(src)
var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
var/list/iconL = list("1","2","3","4","5")
vessel.remove_reagent("blood",amt)
for(var/obj/effect/decal/cleanable/blood/drip/G in T)
nums += G
iconL.Remove(G.icon_state)
if (nums.len < 5)
var/obj/effect/decal/cleanable/blood/drip/this = new(T)
this.icon_state = pick(iconL)
this.blood_DNA = list()
this.blood_DNA[dna.unique_enzymes] = dna.b_type
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
this.virus2[ID] = V.getcopy()
if (species) this.basecolor = species.blood_color
this.update_icon()
else
for(var/obj/effect/decal/cleanable/blood/drip/G in nums)
del G
T.add_blood(src)
blood_splatter(src,src)
/****************************************************
BLOOD TRANSFERS
@@ -193,6 +174,12 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
B.data["resistances"] = src.resistances.Copy()
B.data["blood_type"] = copytext(src.dna.b_type,1,0)
// Putting this here due to return shenanigans.
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src
B.data["blood_colour"] = H.species.blood_color
B.color = B.data["blood_colour"]
var/list/temp_chem = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
temp_chem += R.id
@@ -245,7 +232,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if (!injected || !our)
return
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"]) )
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]) )
reagents.add_reagent("toxin",amount * 0.5)
reagents.update_total()
else
@@ -263,13 +250,18 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
return D
return res
proc/blood_incompatible(donor,receiver)
proc/blood_incompatible(donor,receiver,donor_species,receiver_species)
if(!donor || !receiver) return 0
var
donor_antigen = copytext(donor,1,lentext(donor))
receiver_antigen = copytext(receiver,1,lentext(receiver))
donor_rh = (findtext(donor,"+")>0)
receiver_rh = (findtext(receiver,"+")>0)
if(donor_species && receiver_species)
if(donor_species != receiver_species)
return 1
var/donor_antigen = copytext(donor,1,lentext(donor))
var/receiver_antigen = copytext(receiver,1,lentext(receiver))
var/donor_rh = (findtext(donor,"+")>0)
var/receiver_rh = (findtext(receiver,"+")>0)
if(donor_rh && !receiver_rh) return 1
switch(receiver_antigen)
if("A")
@@ -279,4 +271,71 @@ proc/blood_incompatible(donor,receiver)
if("O")
if(donor_antigen != "O") return 1
//AB is a universal receiver.
return 0
return 0
proc/blood_splatter(var/target,var/datum/reagent/blood/source,var/large)
var/obj/effect/decal/cleanable/blood/B
var/decal_type = /obj/effect/decal/cleanable/blood/splatter
var/turf/T = get_turf(target)
if(istype(source,/mob/living/carbon/human))
var/mob/living/carbon/human/M = source
source = M.get_blood(M.vessel)
else if(istype(source,/mob/living/carbon/monkey))
var/mob/living/carbon/monkey/donor = source
if(donor.dna)
source = new()
source.data["blood_DNA"] = donor.dna.unique_enzymes
source.data["blood_type"] = donor.dna.b_type
// Are we dripping or splattering?
if(!large)
// Only a certain number of drips can be on a given turf.
var/list/drips = list()
var/list/drip_icons = list("1","2","3","4","5")
for(var/obj/effect/decal/cleanable/blood/drip/drop in T)
drips += drop
drip_icons.Remove(drop.icon_state)
// If we have too many drips, remove them and spawn a proper blood splatter.
if(drips.len >= 5)
//TODO: copy all virus data from drips to new splatter?
for(var/obj/effect/decal/cleanable/blood/drip/drop in drips)
del drop
else
decal_type = /obj/effect/decal/cleanable/blood/drip
// Find a blood decal or create a new one.
B = locate(decal_type) in T
if(!B)
B = new decal_type(T)
// If there's no data to copy, call it quits here.
if(!source)
return B
// Update appearance.
if(source.data["blood_colour"])
B.basecolor = source.data["blood_colour"]
B.update_icon()
// Update blood information.
if(source.data["blood_DNA"])
B.blood_DNA = list()
if(source.data["blood_type"])
B.blood_DNA[source.data["blood_DNA"]] = source.data["blood_type"]
else
B.blood_DNA[source.data["blood_DNA"]] = "O+"
// Update virus information. //Looks like this is out of date.
//for(var/datum/disease/D in source.data["viruses"])
// var/datum/disease/new_virus = D.Copy(1)
// source.viruses += new_virus
// new_virus.holder = B
if(source.data["virus2"])
B.virus2 = virus_copylist(source.data["virus2"])
return B

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