diff --git a/baystation12.dme b/baystation12.dme
index 1c200c9afc..037531f6fd 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -40,7 +40,6 @@
#include "code\_onclick\other_mobs.dm"
#include "code\_onclick\telekinesis.dm"
#include "code\_onclick\hud\_defines.dm"
-#include "code\_onclick\hud\alien.dm"
#include "code\_onclick\hud\alien_larva.dm"
#include "code\_onclick\hud\hud.dm"
#include "code\_onclick\hud\human.dm"
@@ -897,7 +896,6 @@
#include "code\modules\mining\drilling\distribution.dm"
#include "code\modules\mining\drilling\drill.dm"
#include "code\modules\mining\drilling\scanner.dm"
-#include "code\modules\mob\abilities.dm"
#include "code\modules\mob\death.dm"
#include "code\modules\mob\emote.dm"
#include "code\modules\mob\hear_say.dm"
@@ -925,42 +923,33 @@
#include "code\modules\mob\living\living.dm"
#include "code\modules\mob\living\living_defense.dm"
#include "code\modules\mob\living\living_defines.dm"
+#include "code\modules\mob\living\living_powers.dm"
#include "code\modules\mob\living\login.dm"
#include "code\modules\mob\living\logout.dm"
#include "code\modules\mob\living\say.dm"
#include "code\modules\mob\living\blob\blob.dm"
#include "code\modules\mob\living\carbon\carbon.dm"
#include "code\modules\mob\living\carbon\carbon_defines.dm"
+#include "code\modules\mob\living\carbon\carbon_powers.dm"
#include "code\modules\mob\living\carbon\give.dm"
#include "code\modules\mob\living\carbon\shock.dm"
-#include "code\modules\mob\living\carbon\species.dm"
#include "code\modules\mob\living\carbon\alien\alien.dm"
+#include "code\modules\mob\living\carbon\alien\alien_attacks.dm"
+#include "code\modules\mob\living\carbon\alien\alien_damage.dm"
#include "code\modules\mob\living\carbon\alien\death.dm"
-#include "code\modules\mob\living\carbon\alien\login.dm"
-#include "code\modules\mob\living\carbon\alien\logout.dm"
-#include "code\modules\mob\living\carbon\alien\powers.dm"
+#include "code\modules\mob\living\carbon\alien\emote.dm"
+#include "code\modules\mob\living\carbon\alien\life.dm"
+#include "code\modules\mob\living\carbon\alien\progression.dm"
#include "code\modules\mob\living\carbon\alien\say.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\alien_powers.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\death.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\emote.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\humanoid.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\inventory.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\life.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\login.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\queen.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\update_icons.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\caste\drone.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\caste\hunter.dm"
-#include "code\modules\mob\living\carbon\alien\humanoid\caste\sentinel.dm"
-#include "code\modules\mob\living\carbon\alien\larva\death.dm"
-#include "code\modules\mob\living\carbon\alien\larva\emote.dm"
-#include "code\modules\mob\living\carbon\alien\larva\inventory.dm"
+#include "code\modules\mob\living\carbon\alien\update_icons.dm"
+#include "code\modules\mob\living\carbon\alien\diona\diona.dm"
+#include "code\modules\mob\living\carbon\alien\diona\diona_attacks.dm"
+#include "code\modules\mob\living\carbon\alien\diona\diona_powers.dm"
+#include "code\modules\mob\living\carbon\alien\diona\life.dm"
+#include "code\modules\mob\living\carbon\alien\diona\progression.dm"
+#include "code\modules\mob\living\carbon\alien\diona\say_understands.dm"
#include "code\modules\mob\living\carbon\alien\larva\larva.dm"
-#include "code\modules\mob\living\carbon\alien\larva\life.dm"
-#include "code\modules\mob\living\carbon\alien\larva\powers.dm"
-#include "code\modules\mob\living\carbon\alien\larva\update_icons.dm"
-#include "code\modules\mob\living\carbon\alien\special\alien_embryo.dm"
-#include "code\modules\mob\living\carbon\alien\special\facehugger.dm"
+#include "code\modules\mob\living\carbon\alien\larva\progression.dm"
#include "code\modules\mob\living\carbon\brain\brain.dm"
#include "code\modules\mob\living\carbon\brain\brain_item.dm"
#include "code\modules\mob\living\carbon\brain\death.dm"
@@ -974,19 +963,27 @@
#include "code\modules\mob\living\carbon\human\emote.dm"
#include "code\modules\mob\living\carbon\human\examine.dm"
#include "code\modules\mob\living\carbon\human\human.dm"
-#include "code\modules\mob\living\carbon\human\human_attackalien.dm"
#include "code\modules\mob\living\carbon\human\human_attackhand.dm"
#include "code\modules\mob\living\carbon\human\human_attackpaw.dm"
#include "code\modules\mob\living\carbon\human\human_damage.dm"
#include "code\modules\mob\living\carbon\human\human_defense.dm"
#include "code\modules\mob\living\carbon\human\human_defines.dm"
#include "code\modules\mob\living\carbon\human\human_movement.dm"
+#include "code\modules\mob\living\carbon\human\human_powers.dm"
+#include "code\modules\mob\living\carbon\human\human_species.dm"
#include "code\modules\mob\living\carbon\human\inventory.dm"
#include "code\modules\mob\living\carbon\human\life.dm"
#include "code\modules\mob\living\carbon\human\login.dm"
+#include "code\modules\mob\living\carbon\human\logout.dm"
#include "code\modules\mob\living\carbon\human\say.dm"
+#include "code\modules\mob\living\carbon\human\species.dm"
#include "code\modules\mob\living\carbon\human\update_icons.dm"
#include "code\modules\mob\living\carbon\human\whisper.dm"
+#include "code\modules\mob\living\carbon\human\alien\alien.dm"
+#include "code\modules\mob\living\carbon\human\alien\alien_embryo.dm"
+#include "code\modules\mob\living\carbon\human\alien\alien_facehugger.dm"
+#include "code\modules\mob\living\carbon\human\alien\alien_powers.dm"
+#include "code\modules\mob\living\carbon\human\alien\alien_species.dm"
#include "code\modules\mob\living\carbon\metroid\death.dm"
#include "code\modules\mob\living\carbon\metroid\emote.dm"
#include "code\modules\mob\living\carbon\metroid\examine.dm"
@@ -999,14 +996,12 @@
#include "code\modules\mob\living\carbon\metroid\subtypes.dm"
#include "code\modules\mob\living\carbon\metroid\update_icons.dm"
#include "code\modules\mob\living\carbon\monkey\death.dm"
-#include "code\modules\mob\living\carbon\monkey\diona.dm"
#include "code\modules\mob\living\carbon\monkey\emote.dm"
#include "code\modules\mob\living\carbon\monkey\examine.dm"
#include "code\modules\mob\living\carbon\monkey\inventory.dm"
#include "code\modules\mob\living\carbon\monkey\life.dm"
#include "code\modules\mob\living\carbon\monkey\login.dm"
#include "code\modules\mob\living\carbon\monkey\monkey.dm"
-#include "code\modules\mob\living\carbon\monkey\powers.dm"
#include "code\modules\mob\living\carbon\monkey\update_icons.dm"
#include "code\modules\mob\living\silicon\alarm.dm"
#include "code\modules\mob\living\silicon\death.dm"
@@ -1052,6 +1047,7 @@
#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
+#include "code\modules\mob\living\silicon\robot\robot_powers.dm"
#include "code\modules\mob\living\silicon\robot\wires.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"
@@ -1060,13 +1056,16 @@
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
#include "code\modules\mob\living\simple_animal\bees.dm"
-#include "code\modules\mob\living\simple_animal\borer.dm"
#include "code\modules\mob\living\simple_animal\constructs.dm"
#include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_animal\parrot.dm"
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
#include "code\modules\mob\living\simple_animal\worm.dm"
+#include "code\modules\mob\living\simple_animal\borer\borer.dm"
+#include "code\modules\mob\living\simple_animal\borer\borer_captive.dm"
+#include "code\modules\mob\living\simple_animal\borer\borer_powers.dm"
+#include "code\modules\mob\living\simple_animal\borer\say.dm"
#include "code\modules\mob\living\simple_animal\friendly\cat.dm"
#include "code\modules\mob\living\simple_animal\friendly\corgi.dm"
#include "code\modules\mob\living\simple_animal\friendly\crab.dm"
@@ -1109,6 +1108,7 @@
#include "code\modules\nano\nanoui.dm"
#include "code\modules\organs\blood.dm"
#include "code\modules\organs\organ.dm"
+#include "code\modules\organs\organ_alien.dm"
#include "code\modules\organs\organ_external.dm"
#include "code\modules\organs\organ_internal.dm"
#include "code\modules\organs\organ_objects.dm"
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index 80b168aabd..925994546e 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -425,14 +425,16 @@
return
/*
- Alt-click to ventcrawl - Monkeys, aliens, slimes and mice.
+ Alt-click to vent crawl - Monkeys, aliens, slimes and mice.
This is a little buggy but somehow that just seems to plague ventcrawl.
I am sorry, I don't know why.
*/
-/obj/machinery/atmospherics/unary/vent_pump/AltClick(var/mob/living/ML)
+// Commenting this out for now, it's not critical, stated to be buggy, and seems like
+// a really clumsy way of doing this. ~Z
+/*/obj/machinery/atmospherics/unary/vent_pump/AltClick(var/mob/living/ML)
if(istype(ML))
var/list/ventcrawl_verbs = list(/mob/living/carbon/monkey/verb/ventcrawl, /mob/living/carbon/alien/verb/ventcrawl, /mob/living/carbon/slime/verb/ventcrawl,/mob/living/simple_animal/mouse/verb/ventcrawl)
if(length(ML.verbs & ventcrawl_verbs)) // alien queens have this removed, an istype would be complicated
ML.handle_ventcrawl(src)
return
- ..()
+ ..()*/
\ No newline at end of file
diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm
deleted file mode 100644
index 01b1058527..0000000000
--- a/code/_onclick/hud/alien.dm
+++ /dev/null
@@ -1,241 +0,0 @@
-/datum/hud/proc/alien_hud()
-
- src.adding = list( )
- src.other = list( )
-
- var/obj/screen/using
- var/obj/screen/inventory/inv_box
-
- using = new /obj/screen()
- using.name = "act_intent"
- using.dir = SOUTHWEST
- using.icon = 'icons/mob/screen1_alien.dmi'
- using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent)
- using.screen_loc = ui_acti
- using.layer = 20
- src.adding += using
- action_intent = using
-
-//intent small hud objects
- var/icon/ico
-
- ico = new('icons/mob/screen1_alien.dmi', "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
- using = new /obj/screen( src )
- using.name = "help"
- using.icon = ico
- using.screen_loc = ui_acti
- using.layer = 21
- src.adding += using
- help_intent = using
-
- ico = new('icons/mob/screen1_alien.dmi', "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
- using = new /obj/screen( src )
- using.name = "disarm"
- using.icon = ico
- using.screen_loc = ui_acti
- using.layer = 21
- src.adding += using
- disarm_intent = using
-
- ico = new('icons/mob/screen1_alien.dmi', "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
- using = new /obj/screen( src )
- using.name = "grab"
- using.icon = ico
- using.screen_loc = ui_acti
- using.layer = 21
- src.adding += using
- grab_intent = using
-
- ico = new('icons/mob/screen1_alien.dmi', "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
- using = new /obj/screen( src )
- using.name = "harm"
- using.icon = ico
- using.screen_loc = ui_acti
- using.layer = 21
- src.adding += using
- hurt_intent = using
-
-//end intent small hud objects
-
- using = new /obj/screen()
- using.name = "mov_intent"
- using.dir = SOUTHWEST
- using.icon = 'icons/mob/screen1_alien.dmi'
- using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
- using.screen_loc = ui_movi
- using.layer = 20
- src.adding += using
- move_intent = using
-
- using = new /obj/screen()
- using.name = "drop"
- using.icon = 'icons/mob/screen1_alien.dmi'
- using.icon_state = "act_drop"
- using.screen_loc = ui_drop_throw
- using.layer = 19
- src.adding += using
-
-//equippable shit
- //suit
- inv_box = new /obj/screen/inventory()
- inv_box.name = "o_clothing"
- inv_box.dir = SOUTH
- inv_box.icon = 'icons/mob/screen1_alien.dmi'
- inv_box.icon_state = "equip"
- inv_box.screen_loc = ui_alien_oclothing
- inv_box.slot_id = slot_wear_suit
- inv_box.layer = 19
- src.adding += inv_box
-
- inv_box = new /obj/screen/inventory()
- inv_box.name = "r_hand"
- inv_box.dir = WEST
- inv_box.icon = 'icons/mob/screen1_alien.dmi'
- inv_box.icon_state = "hand_inactive"
- if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
- using.icon_state = "hand_active"
- inv_box.screen_loc = ui_rhand
- inv_box.layer = 19
- src.r_hand_hud_object = inv_box
- inv_box.slot_id = slot_r_hand
- src.adding += inv_box
-
- inv_box = new /obj/screen/inventory()
- inv_box.name = "l_hand"
- inv_box.dir = EAST
- inv_box.icon = 'icons/mob/screen1_alien.dmi'
- inv_box.icon_state = "hand_inactive"
- if(mymob && mymob.hand) //This being 1 means the left hand is in use
- inv_box.icon_state = "hand_active"
- inv_box.screen_loc = ui_lhand
- inv_box.layer = 19
- inv_box.slot_id = slot_l_hand
- src.l_hand_hud_object = inv_box
- src.adding += inv_box
-
- using = new /obj/screen/inventory()
- using.name = "hand"
- using.dir = SOUTH
- using.icon = 'icons/mob/screen1_alien.dmi'
- using.icon_state = "hand1"
- using.screen_loc = ui_swaphand1
- using.layer = 19
- src.adding += using
-
- using = new /obj/screen/inventory()
- using.name = "hand"
- using.dir = SOUTH
- using.icon = 'icons/mob/screen1_alien.dmi'
- using.icon_state = "hand2"
- using.screen_loc = ui_swaphand2
- using.layer = 19
- src.adding += using
-
- //pocket 1
- inv_box = new /obj/screen/inventory()
- inv_box.name = "storage1"
- inv_box.icon = 'icons/mob/screen1_alien.dmi'
- inv_box.icon_state = "pocket"
- inv_box.screen_loc = ui_storage1
- inv_box.slot_id = slot_l_store
- inv_box.layer = 19
- src.adding += inv_box
-
- //pocket 2
- inv_box = new /obj/screen/inventory()
- inv_box.name = "storage2"
- inv_box.icon = 'icons/mob/screen1_alien.dmi'
- inv_box.icon_state = "pocket"
- inv_box.screen_loc = ui_storage2
- inv_box.slot_id = slot_r_store
- inv_box.layer = 19
- src.adding += inv_box
-
- //head
- inv_box = new /obj/screen/inventory()
- inv_box.name = "head"
- inv_box.icon = 'icons/mob/screen1_alien.dmi'
- inv_box.icon_state = "hair"
- inv_box.screen_loc = ui_alien_head
- inv_box.slot_id = slot_head
- inv_box.layer = 19
- src.adding += inv_box
-//end of equippable shit
-
-/*
- using = new /obj/screen()
- using.name = "resist"
- using.icon = 'icons/mob/screen1_alien.dmi'
- using.icon_state = "act_resist"
- using.screen_loc = ui_resist
- using.layer = 19
- src.adding += using
-*/
-
- mymob.throw_icon = new /obj/screen()
- mymob.throw_icon.icon = 'icons/mob/screen1_alien.dmi'
- mymob.throw_icon.icon_state = "act_throw_off"
- mymob.throw_icon.name = "throw"
- mymob.throw_icon.screen_loc = ui_drop_throw
-
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = 'icons/mob/screen1_alien.dmi'
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_alien_oxygen
-
- mymob.toxin = new /obj/screen()
- mymob.toxin.icon = 'icons/mob/screen1_alien.dmi'
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_alien_toxin
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = 'icons/mob/screen1_alien.dmi'
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_alien_fire
-
- mymob.healths = new /obj/screen()
- mymob.healths.icon = 'icons/mob/screen1_alien.dmi'
- mymob.healths.icon_state = "health0"
- mymob.healths.name = "health"
- mymob.healths.screen_loc = ui_alien_health
-
- mymob.pullin = new /obj/screen()
- mymob.pullin.icon = 'icons/mob/screen1_alien.dmi'
- mymob.pullin.icon_state = "pull0"
- mymob.pullin.name = "pull"
- mymob.pullin.screen_loc = ui_pull_resist
-
- mymob.blind = new /obj/screen()
- mymob.blind.icon = 'icons/mob/screen1_full.dmi'
- mymob.blind.icon_state = "blackimageoverlay"
- mymob.blind.name = " "
- mymob.blind.screen_loc = "1,1"
- mymob.blind.layer = 0
-
- mymob.flash = new /obj/screen()
- mymob.flash.icon = 'icons/mob/screen1_alien.dmi'
- mymob.flash.icon_state = "blank"
- mymob.flash.name = "flash"
- mymob.flash.screen_loc = "1,1 to 15,15"
- mymob.flash.layer = 17
-
- mymob.zone_sel = new /obj/screen/zone_sel()
- mymob.zone_sel.icon = 'icons/mob/screen1_alien.dmi'
- mymob.zone_sel.overlays.Cut()
- mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")
-
- mymob.client.screen = null
-
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.toxin, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach )
- mymob.client.screen += src.adding + src.other
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 221eef2a1d..9ea0cb2bff 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -194,15 +194,13 @@ datum/hud/New(mob/owner)
var/ui_alpha = mymob.client.prefs.UI_style_alpha
if(ishuman(mymob))
- human_hud(ui_style, ui_color, ui_alpha) // Pass the player the UI style chosen in preferences
+ human_hud(ui_style, ui_color, ui_alpha, mymob) // Pass the player the UI style chosen in preferences
else if(ismonkey(mymob))
monkey_hud(ui_style)
else if(isbrain(mymob))
brain_hud(ui_style)
- else if(islarva(mymob))
- larva_hud()
else if(isalien(mymob))
- alien_hud()
+ larva_hud()
else if(isAI(mymob))
ai_hud()
else if(isrobot(mymob))
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 82a9d79c47..7425716cd9 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -1,416 +1,305 @@
-/datum/hud/proc/human_hud(var/ui_style='icons/mob/screen1_White.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255)
+/datum/hud/proc/human_hud(var/ui_style='icons/mob/screen1_White.dmi', var/ui_color = "#ffffff", var/ui_alpha = 255, var/mob/living/carbon/human/target)
+
+ var/datum/hud_data/hud_data
+ if(!istype(target))
+ hud_data = new()
+ else
+ hud_data = target.species.hud
+
+ if(hud_data.icon)
+ ui_style = hud_data.icon
src.adding = list()
src.other = list()
src.hotkeybuttons = list() //These can be disabled for hotkey usersx
+ var/list/hud_elements = list()
var/obj/screen/using
var/obj/screen/inventory/inv_box
- using = new /obj/screen()
- using.name = "act_intent"
- using.dir = SOUTHWEST
- using.icon = ui_style
- using.icon_state = "intent_"+mymob.a_intent
- using.screen_loc = ui_acti
- using.color = ui_color
- using.alpha = ui_alpha
- using.layer = 20
- src.adding += using
- action_intent = using
+ // Draw the various inventory equipment slots.
+ var/has_hidden_gear
+ for(var/gear_slot in hud_data.gear)
-//intent small hud objects
- var/icon/ico
+ inv_box = new /obj/screen/inventory()
+ inv_box.icon = ui_style
+ inv_box.layer = 19
+ inv_box.color = ui_color
+ inv_box.alpha = ui_alpha
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
- using = new /obj/screen( src )
- using.name = "help"
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = 21
- src.adding += using
- help_intent = using
+ var/list/slot_data = hud_data.gear[gear_slot]
+ inv_box.name = gear_slot
+ inv_box.screen_loc = slot_data["loc"]
+ inv_box.slot_id = slot_data["slot"]
+ inv_box.icon_state = slot_data["state"]
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
- using = new /obj/screen( src )
- using.name = "disarm"
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = 21
- src.adding += using
- disarm_intent = using
+ if(slot_data["dir"])
+ inv_box.dir = slot_data["dir"]
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
- using = new /obj/screen( src )
- using.name = "grab"
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = 21
- src.adding += using
- grab_intent = using
+ if(slot_data["toggle"])
+ src.other += inv_box
+ has_hidden_gear = 1
+ else
+ src.adding += inv_box
- ico = new(ui_style, "black")
- ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
- ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
- using = new /obj/screen( src )
- using.name = "harm"
- using.icon = ico
- using.screen_loc = ui_acti
- using.alpha = ui_alpha
- using.layer = 21
- src.adding += using
- hurt_intent = using
+ if(has_hidden_gear)
+ using = new /obj/screen()
+ using.name = "toggle"
+ using.icon = ui_style
+ using.icon_state = "other"
+ using.screen_loc = ui_inventory
+ using.layer = 20
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.adding += using
-//end intent small hud objects
+ // Draw the attack intent dialogue.
+ if(hud_data.has_a_intent)
- using = new /obj/screen()
- using.name = "mov_intent"
- using.dir = SOUTHWEST
- using.icon = ui_style
- using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
- using.screen_loc = ui_movi
- using.layer = 20
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
- move_intent = using
+ using = new /obj/screen()
+ using.name = "act_intent"
+ using.dir = SOUTHWEST
+ using.icon = ui_style
+ using.icon_state = "intent_"+mymob.a_intent
+ using.screen_loc = ui_acti
+ using.color = ui_color
+ using.alpha = ui_alpha
+ using.layer = 20
+ src.adding += using
+ action_intent = using
- using = new /obj/screen()
- using.name = "drop"
- using.icon = ui_style
- using.icon_state = "act_drop"
- using.screen_loc = ui_drop_throw
- using.layer = 19
- using.color = ui_color
- using.alpha = ui_alpha
- src.hotkeybuttons += using
+ hud_elements |= using
- inv_box = new /obj/screen/inventory()
- inv_box.name = "i_clothing"
- inv_box.dir = SOUTH
- inv_box.icon = ui_style
- inv_box.slot_id = slot_w_uniform
- inv_box.icon_state = "center"
- inv_box.screen_loc = ui_iclothing
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ //intent small hud objects
+ var/icon/ico
- inv_box = new /obj/screen/inventory()
- inv_box.name = "o_clothing"
- inv_box.dir = SOUTH
- inv_box.icon = ui_style
- inv_box.slot_id = slot_wear_suit
- inv_box.icon_state = "equip"
- inv_box.screen_loc = ui_oclothing
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ ico = new(ui_style, "black")
+ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
+ ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height())
+ using = new /obj/screen( src )
+ using.name = "help"
+ using.icon = ico
+ using.screen_loc = ui_acti
+ using.alpha = ui_alpha
+ using.layer = 21
+ src.adding += using
+ help_intent = using
- inv_box = new /obj/screen/inventory()
- inv_box.name = "r_hand"
- inv_box.dir = WEST
- inv_box.icon = ui_style
- inv_box.icon_state = "hand_inactive"
- if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
- inv_box.icon_state = "hand_active"
- inv_box.screen_loc = ui_rhand
- inv_box.slot_id = slot_r_hand
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
+ ico = new(ui_style, "black")
+ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
+ ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height())
+ using = new /obj/screen( src )
+ using.name = "disarm"
+ using.icon = ico
+ using.screen_loc = ui_acti
+ using.alpha = ui_alpha
+ using.layer = 21
+ src.adding += using
+ disarm_intent = using
- src.r_hand_hud_object = inv_box
- src.adding += inv_box
+ ico = new(ui_style, "black")
+ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
+ ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2)
+ using = new /obj/screen( src )
+ using.name = "grab"
+ using.icon = ico
+ using.screen_loc = ui_acti
+ using.alpha = ui_alpha
+ using.layer = 21
+ src.adding += using
+ grab_intent = using
- inv_box = new /obj/screen/inventory()
- inv_box.name = "l_hand"
- inv_box.dir = EAST
- inv_box.icon = ui_style
- inv_box.icon_state = "hand_inactive"
- if(mymob && mymob.hand) //This being 1 means the left hand is in use
- inv_box.icon_state = "hand_active"
- inv_box.screen_loc = ui_lhand
- inv_box.slot_id = slot_l_hand
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.l_hand_hud_object = inv_box
- src.adding += inv_box
+ ico = new(ui_style, "black")
+ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1)
+ ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2)
+ using = new /obj/screen( src )
+ using.name = "harm"
+ using.icon = ico
+ using.screen_loc = ui_acti
+ using.alpha = ui_alpha
+ using.layer = 21
+ src.adding += using
+ hurt_intent = using
+ //end intent small hud objects
- using = new /obj/screen/inventory()
- using.name = "hand"
- using.dir = SOUTH
- using.icon = ui_style
- using.icon_state = "hand1"
- using.screen_loc = ui_swaphand1
- using.layer = 19
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
+ if(hud_data.has_m_intent)
+ using = new /obj/screen()
+ using.name = "mov_intent"
+ using.dir = SOUTHWEST
+ using.icon = ui_style
+ using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
+ using.screen_loc = ui_movi
+ using.layer = 20
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.adding += using
+ move_intent = using
- using = new /obj/screen/inventory()
- using.name = "hand"
- using.dir = SOUTH
- using.icon = ui_style
- using.icon_state = "hand2"
- using.screen_loc = ui_swaphand2
- using.layer = 19
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
+ if(hud_data.has_drop)
+ using = new /obj/screen()
+ using.name = "drop"
+ using.icon = ui_style
+ using.icon_state = "act_drop"
+ using.screen_loc = ui_drop_throw
+ using.layer = 19
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.hotkeybuttons += using
- inv_box = new /obj/screen/inventory()
- inv_box.name = "id"
- inv_box.dir = NORTH
- inv_box.icon = ui_style
- inv_box.icon_state = "id"
- inv_box.screen_loc = ui_id
- inv_box.slot_id = slot_wear_id
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.adding += inv_box
+ if(hud_data.has_hands)
- inv_box = new /obj/screen/inventory()
- inv_box.name = "mask"
- inv_box.dir = NORTH
- inv_box.icon = ui_style
- inv_box.icon_state = "equip"
- inv_box.screen_loc = ui_mask
- inv_box.slot_id = slot_wear_mask
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ using = new /obj/screen()
+ using.name = "equip"
+ using.icon = ui_style
+ using.icon_state = "act_equip"
+ using.screen_loc = ui_equip
+ using.layer = 20
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.adding += using
- inv_box = new /obj/screen/inventory()
- inv_box.name = "back"
- inv_box.dir = NORTH
- inv_box.icon = ui_style
- inv_box.icon_state = "back"
- inv_box.screen_loc = ui_back
- inv_box.slot_id = slot_back
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.adding += inv_box
+ inv_box = new /obj/screen/inventory()
+ inv_box.name = "r_hand"
+ inv_box.dir = WEST
+ inv_box.icon = ui_style
+ inv_box.icon_state = "hand_inactive"
+ if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
+ inv_box.icon_state = "hand_active"
+ inv_box.screen_loc = ui_rhand
+ inv_box.slot_id = slot_r_hand
+ inv_box.layer = 19
+ inv_box.color = ui_color
+ inv_box.alpha = ui_alpha
- inv_box = new /obj/screen/inventory()
- inv_box.name = "storage1"
- inv_box.icon = ui_style
- inv_box.icon_state = "pocket"
- inv_box.screen_loc = ui_storage1
- inv_box.slot_id = slot_l_store
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.adding += inv_box
+ src.r_hand_hud_object = inv_box
+ src.adding += inv_box
- inv_box = new /obj/screen/inventory()
- inv_box.name = "storage2"
- inv_box.icon = ui_style
- inv_box.icon_state = "pocket"
- inv_box.screen_loc = ui_storage2
- inv_box.slot_id = slot_r_store
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.adding += inv_box
+ inv_box = new /obj/screen/inventory()
+ inv_box.name = "l_hand"
+ inv_box.dir = EAST
+ inv_box.icon = ui_style
+ inv_box.icon_state = "hand_inactive"
+ if(mymob && mymob.hand) //This being 1 means the left hand is in use
+ inv_box.icon_state = "hand_active"
+ inv_box.screen_loc = ui_lhand
+ inv_box.slot_id = slot_l_hand
+ inv_box.layer = 19
+ inv_box.color = ui_color
+ inv_box.alpha = ui_alpha
+ src.l_hand_hud_object = inv_box
+ src.adding += inv_box
- inv_box = new /obj/screen/inventory()
- inv_box.name = "suit storage"
- inv_box.icon = ui_style
- inv_box.dir = 8 //The sprite at dir=8 has the background whereas the others don't.
- inv_box.icon_state = "belt"
- inv_box.screen_loc = ui_sstore1
- inv_box.slot_id = slot_s_store
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.adding += inv_box
+ using = new /obj/screen/inventory()
+ using.name = "hand"
+ using.dir = SOUTH
+ using.icon = ui_style
+ using.icon_state = "hand1"
+ using.screen_loc = ui_swaphand1
+ using.layer = 19
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.adding += using
- using = new /obj/screen()
- using.name = "resist"
- using.icon = ui_style
- using.icon_state = "act_resist"
- using.screen_loc = ui_pull_resist
- using.layer = 19
- using.color = ui_color
- using.alpha = ui_alpha
- src.hotkeybuttons += using
+ using = new /obj/screen/inventory()
+ using.name = "hand"
+ using.dir = SOUTH
+ using.icon = ui_style
+ using.icon_state = "hand2"
+ using.screen_loc = ui_swaphand2
+ using.layer = 19
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.adding += using
- using = new /obj/screen()
- using.name = "toggle"
- using.icon = ui_style
- using.icon_state = "other"
- using.screen_loc = ui_inventory
- using.layer = 20
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
+ if(hud_data.has_resist)
+ using = new /obj/screen()
+ using.name = "resist"
+ using.icon = ui_style
+ using.icon_state = "act_resist"
+ using.screen_loc = ui_pull_resist
+ using.layer = 19
+ using.color = ui_color
+ using.alpha = ui_alpha
+ src.hotkeybuttons += using
- using = new /obj/screen()
- using.name = "equip"
- using.icon = ui_style
- using.icon_state = "act_equip"
- using.screen_loc = ui_equip
- using.layer = 20
- using.color = ui_color
- using.alpha = ui_alpha
- src.adding += using
+ if(hud_data.has_throw)
+ mymob.throw_icon = new /obj/screen()
+ mymob.throw_icon.icon = ui_style
+ mymob.throw_icon.icon_state = "act_throw_off"
+ mymob.throw_icon.name = "throw"
+ mymob.throw_icon.screen_loc = ui_drop_throw
+ mymob.throw_icon.color = ui_color
+ mymob.throw_icon.alpha = ui_alpha
+ src.hotkeybuttons += mymob.throw_icon
+ hud_elements |= mymob.throw_icon
- inv_box = new /obj/screen/inventory()
- inv_box.name = "gloves"
- inv_box.icon = ui_style
- inv_box.icon_state = "gloves"
- inv_box.screen_loc = ui_gloves
- inv_box.slot_id = slot_gloves
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ mymob.pullin = new /obj/screen()
+ mymob.pullin.icon = ui_style
+ mymob.pullin.icon_state = "pull0"
+ mymob.pullin.name = "pull"
+ mymob.pullin.screen_loc = ui_pull_resist
+ src.hotkeybuttons += mymob.pullin
+ hud_elements |= mymob.pullin
- inv_box = new /obj/screen/inventory()
- inv_box.name = "eyes"
- inv_box.icon = ui_style
- inv_box.icon_state = "glasses"
- inv_box.screen_loc = ui_glasses
- inv_box.slot_id = slot_glasses
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ if(hud_data.has_internals)
+ mymob.internals = new /obj/screen()
+ mymob.internals.icon = ui_style
+ mymob.internals.icon_state = "internal0"
+ mymob.internals.name = "internal"
+ mymob.internals.screen_loc = ui_internal
- inv_box = new /obj/screen/inventory()
- inv_box.name = "l_ear"
- inv_box.icon = ui_style
- inv_box.icon_state = "ears"
- inv_box.screen_loc = ui_l_ear
- inv_box.slot_id = slot_l_ear
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ if(hud_data.has_warnings)
+ mymob.oxygen = new /obj/screen()
+ mymob.oxygen.icon = ui_style
+ mymob.oxygen.icon_state = "oxy0"
+ mymob.oxygen.name = "oxygen"
+ mymob.oxygen.screen_loc = ui_oxygen
+ hud_elements |= mymob.oxygen
- inv_box = new /obj/screen/inventory()
- inv_box.name = "r_ear"
- inv_box.icon = ui_style
- inv_box.icon_state = "ears"
- inv_box.screen_loc = ui_r_ear
- inv_box.slot_id = slot_r_ear
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ mymob.toxin = new /obj/screen()
+ mymob.toxin.icon = ui_style
+ mymob.toxin.icon_state = "tox0"
+ mymob.toxin.name = "toxin"
+ mymob.toxin.screen_loc = ui_toxin
+ hud_elements |= mymob.toxin
- inv_box = new /obj/screen/inventory()
- inv_box.name = "head"
- inv_box.icon = ui_style
- inv_box.icon_state = "hair"
- inv_box.screen_loc = ui_head
- inv_box.slot_id = slot_head
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ mymob.fire = new /obj/screen()
+ mymob.fire.icon = ui_style
+ mymob.fire.icon_state = "fire0"
+ mymob.fire.name = "fire"
+ mymob.fire.screen_loc = ui_fire
+ hud_elements |= mymob.fire
- inv_box = new /obj/screen/inventory()
- inv_box.name = "shoes"
- inv_box.icon = ui_style
- inv_box.icon_state = "shoes"
- inv_box.screen_loc = ui_shoes
- inv_box.slot_id = slot_shoes
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.other += inv_box
+ mymob.healths = new /obj/screen()
+ mymob.healths.icon = ui_style
+ mymob.healths.icon_state = "health0"
+ mymob.healths.name = "health"
+ mymob.healths.screen_loc = ui_health
+ hud_elements |= mymob.healths
- inv_box = new /obj/screen/inventory()
- inv_box.name = "belt"
- inv_box.icon = ui_style
- inv_box.icon_state = "belt"
- inv_box.screen_loc = ui_belt
- inv_box.slot_id = slot_belt
- inv_box.layer = 19
- inv_box.color = ui_color
- inv_box.alpha = ui_alpha
- src.adding += inv_box
+ if(hud_data.has_pressure)
+ mymob.pressure = new /obj/screen()
+ mymob.pressure.icon = ui_style
+ mymob.pressure.icon_state = "pressure0"
+ mymob.pressure.name = "pressure"
+ mymob.pressure.screen_loc = ui_pressure
+ hud_elements |= mymob.pressure
- mymob.throw_icon = new /obj/screen()
- mymob.throw_icon.icon = ui_style
- mymob.throw_icon.icon_state = "act_throw_off"
- mymob.throw_icon.name = "throw"
- mymob.throw_icon.screen_loc = ui_drop_throw
- mymob.throw_icon.color = ui_color
- mymob.throw_icon.alpha = ui_alpha
- src.hotkeybuttons += mymob.throw_icon
+ if(hud_data.has_bodytemp)
+ mymob.bodytemp = new /obj/screen()
+ mymob.bodytemp.icon = ui_style
+ mymob.bodytemp.icon_state = "temp1"
+ mymob.bodytemp.name = "body temperature"
+ mymob.bodytemp.screen_loc = ui_temp
+ hud_elements |= mymob.bodytemp
- mymob.oxygen = new /obj/screen()
- mymob.oxygen.icon = ui_style
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
-
- mymob.pressure = new /obj/screen()
- mymob.pressure.icon = ui_style
- mymob.pressure.icon_state = "pressure0"
- mymob.pressure.name = "pressure"
- mymob.pressure.screen_loc = ui_pressure
-
- mymob.toxin = new /obj/screen()
- mymob.toxin.icon = ui_style
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_toxin
-
- mymob.internals = new /obj/screen()
- mymob.internals.icon = ui_style
- mymob.internals.icon_state = "internal0"
- mymob.internals.name = "internal"
- mymob.internals.screen_loc = ui_internal
-
- mymob.fire = new /obj/screen()
- mymob.fire.icon = ui_style
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
-
- mymob.bodytemp = new /obj/screen()
- mymob.bodytemp.icon = ui_style
- mymob.bodytemp.icon_state = "temp1"
- mymob.bodytemp.name = "body temperature"
- mymob.bodytemp.screen_loc = ui_temp
-
- mymob.healths = new /obj/screen()
- mymob.healths.icon = ui_style
- mymob.healths.icon_state = "health0"
- mymob.healths.name = "health"
- mymob.healths.screen_loc = ui_health
-
- mymob.nutrition_icon = new /obj/screen()
- mymob.nutrition_icon.icon = ui_style
- mymob.nutrition_icon.icon_state = "nutrition0"
- mymob.nutrition_icon.name = "nutrition"
- mymob.nutrition_icon.screen_loc = ui_nutrition
-
- mymob.pullin = new /obj/screen()
- mymob.pullin.icon = ui_style
- mymob.pullin.icon_state = "pull0"
- mymob.pullin.name = "pull"
- mymob.pullin.screen_loc = ui_pull_resist
- src.hotkeybuttons += mymob.pullin
+ if(hud_data.has_nutrition)
+ mymob.nutrition_icon = new /obj/screen()
+ mymob.nutrition_icon.icon = ui_style
+ mymob.nutrition_icon.icon_state = "nutrition0"
+ mymob.nutrition_icon.name = "nutrition"
+ mymob.nutrition_icon.screen_loc = ui_nutrition
+ hud_elements |= mymob.nutrition_icon
mymob.blind = new /obj/screen()
mymob.blind.icon = 'icons/mob/screen1_full.dmi'
@@ -419,6 +308,7 @@
mymob.blind.screen_loc = "1,1"
mymob.blind.mouse_opacity = 0
mymob.blind.layer = 0
+ hud_elements |= mymob.blind
mymob.damageoverlay = new /obj/screen()
mymob.damageoverlay.icon = 'icons/mob/screen1_full.dmi'
@@ -427,6 +317,7 @@
mymob.damageoverlay.screen_loc = "1,1"
mymob.damageoverlay.mouse_opacity = 0
mymob.damageoverlay.layer = 18.1 //The black screen overlay sets layer to 18 to display it, this one has to be just on top.
+ hud_elements |= mymob.damageoverlay
mymob.flash = new /obj/screen()
mymob.flash.icon = ui_style
@@ -434,6 +325,7 @@
mymob.flash.name = "flash"
mymob.flash.screen_loc = "1,1 to 15,15"
mymob.flash.layer = 17
+ hud_elements |= mymob.flash
mymob.pain = new /obj/screen( null )
@@ -443,11 +335,13 @@
mymob.zone_sel.alpha = ui_alpha
mymob.zone_sel.overlays.Cut()
mymob.zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[mymob.zone_sel.selecting]")
+ hud_elements |= mymob.zone_sel
//Handle the gun settings buttons
mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
//mymob.gun_setting_icon.color = ui_color
mymob.gun_setting_icon.alpha = ui_alpha
+ hud_elements |= mymob.gun_setting_icon
mymob.item_use_icon = new /obj/screen/gun/item(null)
//mymob.item_use_icon.color = ui_color
@@ -468,7 +362,7 @@
mymob.client.screen = null
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
+ mymob.client.screen += hud_elements
mymob.client.screen += src.adding + src.hotkeybuttons
inventory_shown = 0;
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 079c551ebf..8a10310b3d 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -235,8 +235,6 @@
if("walk")
usr.m_intent = "run"
usr.hud_used.move_intent.icon_state = "running"
- if(istype(usr,/mob/living/carbon/alien/humanoid))
- usr.update_icons()
if("m_intent")
if(!usr.m_int)
switch(usr.m_intent)
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index b84b9f467c..3c1cb43727 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -90,21 +90,10 @@
Aliens
Defaults to same as monkey in most places
*/
-/mob/living/carbon/alien/UnarmedAttack(var/atom/A)
- A.attack_alien(src)
-/atom/proc/attack_alien(mob/user as mob)
- attack_paw(user)
- return
+
/mob/living/carbon/alien/RestrainedClickOn(var/atom/A)
return
-// Babby aliens
-/mob/living/carbon/alien/larva/UnarmedAttack(var/atom/A)
- A.attack_larva(src)
-/atom/proc/attack_larva(mob/user as mob)
- return
-
-
/*
Slimes
Nothing happening here
diff --git a/code/controllers/hooks-defs.dm b/code/controllers/hooks-defs.dm
index d36fc7a7c7..001372b4e3 100644
--- a/code/controllers/hooks-defs.dm
+++ b/code/controllers/hooks-defs.dm
@@ -47,7 +47,7 @@
/**
* Podman hook.
* Called in podmen.dm when someone is brought back as a Diona.
- * Parameters: var/mob/living/carbon/monkey/diona
+ * Parameters: var/mob/living/carbon/alien/diona
*/
/hook/harvest_podman
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 4c01933dbe..4777f061d6 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -495,7 +495,7 @@ client
src.give_disease(M)
href_list["datumrefresh"] = href_list["give_spell"]
-
+
else if(href_list["give_disease2"])
if(!check_rights(R_ADMIN|R_FUN)) return
@@ -777,6 +777,9 @@ client
usr << "Mob doesn't exist anymore"
return
+ // Clear out their species abilities.
+ H.species.remove_inherent_verbs(H)
+
if(H.set_species(new_species))
usr << "Set species of [H] to [H.species]."
H.regenerate_icons()
@@ -827,9 +830,9 @@ client
else if(href_list["addverb"])
if(!check_rights(R_DEBUG)) return
-
+
var/mob/living/H = locate(href_list["addverb"])
-
+
if(!istype(H))
usr << "This can only be done to instances of type /mob/living"
return
@@ -845,7 +848,7 @@ client
possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb)
possibleverbs -= H.verbs
possibleverbs += "Cancel" // ...And one for the bottom
-
+
var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs
if(!H)
usr << "Mob doesn't exist anymore"
@@ -854,7 +857,7 @@ client
return
else
H.verbs += verb
-
+
else if(href_list["remverb"])
if(!check_rights(R_DEBUG)) return
@@ -872,7 +875,7 @@ client
else
H.verbs -= verb
-
+
else if(href_list["fix_nano"])
if(!check_rights(R_DEBUG)) return
@@ -881,11 +884,11 @@ client
if(!istype(H) || !H.client)
usr << "This can only be done on mobs with clients"
return
-
-
+
+
nanomanager.send_resources(H.client)
-
+
usr << "Resource files sent"
H << "Your NanoUI Resource files have been refreshed"
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 34dc2e1344..cc22ce05d3 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1234,27 +1234,6 @@ datum/mind
..()
mind.assigned_role = "slime"
-//XENO
-/mob/living/carbon/alien/mind_initialize()
- ..()
- mind.assigned_role = "Alien"
- //XENO HUMANOID
-/mob/living/carbon/alien/humanoid/queen/mind_initialize()
- ..()
- mind.special_role = "Queen"
-
-/mob/living/carbon/alien/humanoid/hunter/mind_initialize()
- ..()
- mind.special_role = "Hunter"
-
-/mob/living/carbon/alien/humanoid/drone/mind_initialize()
- ..()
- mind.special_role = "Drone"
-
-/mob/living/carbon/alien/humanoid/sentinel/mind_initialize()
- ..()
- mind.special_role = "Sentinel"
- //XENO LARVA
/mob/living/carbon/alien/larva/mind_initialize()
..()
mind.special_role = "Larva"
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index be2bb88a17..d08679bbc1 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -111,7 +111,7 @@
src.visible_message("[src] transforms!")
src.verbs -= /mob/proc/changeling_change_species
- H.set_species(S,null,1) //Until someone moves body colour into DNA, they're going to have to use the default.
+ H.set_species(S,1) //Until someone moves body colour into DNA, they're going to have to use the default.
spawn(10)
src.verbs += /mob/proc/changeling_change_species
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 590df9cd07..83ca646d89 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -690,21 +690,6 @@ var/list/sacrificed = list()
if(prob(20))
ticker.mode.grant_runeword(usr)
M.gib()
-/* for(var/mob/living/carbon/alien/A)
- for(var/mob/K in cultsinrange)
- K.say("Barhah hra zar'garis!")
- A.dust() /// A.gib() doesnt work for some reason, and dust() leaves that skull and bones thingy which we dont really need.
- if (ticker.mode.name == "cult")
- if(prob(75))
- usr << "\red The Geometer of Blood accepts your exotic sacrifice."
- ticker.mode:grant_runeword(usr)
- else
- usr << "\red The Geometer of Blood accepts your exotic sacrifice."
- usr << "\red However, this alien is not enough to gain His favor."
- else
- usr << "\red The Geometer of Blood accepts your exotic sacrifice."
- return
- return fizzle() */
/////////////////////////////////////////SIXTEENTH RUNE
diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm
index b36eb64d8b..ded12b2da8 100644
--- a/code/game/gamemodes/events/ninja_equipment.dm
+++ b/code/game/gamemodes/events/ninja_equipment.dm
@@ -1451,32 +1451,34 @@ It is possible to destroy the net by the occupant or someone else.
return
attack_hand()
+
if (HULK in usr.mutations)
usr << text("\blue You easily destroy the energy net.")
for(var/mob/O in oviewers(src))
O.show_message(text("\red [] rips the energy net apart!", usr), 1)
health-=50
+ else if(istype(usr,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = usr
+ if(H.species.can_shred(H))
+
+ H << text("\green You claw at the net.")
+ for(var/mob/O in oviewers(src))
+ O.show_message(text("\red [] claws at the energy net!", H), 1)
+
+ playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1)
+ health -= rand(10, 20)
+
+ if(health <= 0)
+ H << text("\green You slice the energy net to pieces.")
+ for(var/mob/O in oviewers(src))
+ O.show_message(text("\red [] slices the energy net apart!", H), 1)
+
healthcheck()
return
attack_paw()
return attack_hand()
- attack_alien()
- if (islarva(usr))
- return
- usr << text("\green You claw at the net.")
- for(var/mob/O in oviewers(src))
- O.show_message(text("\red [] claws at the energy net!", usr), 1)
- playsound(src.loc, 'sound/weapons/slash.ogg', 80, 1)
- health -= rand(10, 20)
- if(health <= 0)
- usr << text("\green You slice the energy net to pieces.")
- for(var/mob/O in oviewers(src))
- O.show_message(text("\red [] slices the energy net apart!", usr), 1)
- healthcheck()
- return
-
attackby(obj/item/weapon/W as obj, mob/user as mob)
var/aforce = W.force
health = max(0, health - aforce)
diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm
index c1fd9b219f..5dae9e6e4b 100644
--- a/code/game/gamemodes/events/space_ninja.dm
+++ b/code/game/gamemodes/events/space_ninja.dm
@@ -219,8 +219,8 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp
//Xenos and deathsquads take precedence over everything else.
//Unless the xenos are hiding in a locker somewhere, this'll find em.
- for(var/mob/living/carbon/alien/humanoid/xeno in player_list)
- if(istype(xeno))
+ for(var/mob/living/carbon/human/xeno in player_list)
+ if(istype(xeno.species,/datum/species/xenos))
xeno_list += xeno
if(assign_mission)
@@ -230,11 +230,11 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp
if(xeno_list.len>3)//If there are more than three humanoid xenos on the station, time to get dangerous.
//Here we want the ninja to murder all the queens. The other aliens don't really matter.
var/xeno_queen_list[] = list()
- for(var/mob/living/carbon/alien/humanoid/queen/xeno_queen in xeno_list)
- if(xeno_queen.mind&&xeno_queen.stat!=2)
+ for(var/mob/living/carbon/human/xeno_queen in xeno_list)
+ if(xeno_queen.species.name == "Xenomorph Queen" && xeno_queen.mind && xeno_queen.stat!=2)
xeno_queen_list += xeno_queen
if(xeno_queen_list.len&&side=="face")//If there are queen about and the probability is 50.
- for(var/mob/living/carbon/alien/humanoid/queen/xeno_queen in xeno_queen_list)
+ for(var/mob/living/carbon/human/xeno_queen in xeno_queen_list)
var/datum/objective/assassinate/ninja_objective = new
ninja_objective.owner = ninja_mind
//We'll do some manual overrides to properly set it up.
diff --git a/code/game/gamemodes/mutiny/mutiny_hooks.dm b/code/game/gamemodes/mutiny/mutiny_hooks.dm
index 5bcddade43..9e64bd2e70 100644
--- a/code/game/gamemodes/mutiny/mutiny_hooks.dm
+++ b/code/game/gamemodes/mutiny/mutiny_hooks.dm
@@ -12,7 +12,7 @@
mode.update_icon(H.mind)
return 1
-/hook/harvest_podman/proc/update_icon(mob/living/carbon/monkey/diona/D)
+/hook/harvest_podman/proc/update_icon(mob/living/carbon/alien/diona/D)
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode) return 1
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 9ff5608e2d..d01e0e3506 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -649,17 +649,6 @@ datum/objective/capture
captured_amount+=0.5
continue
captured_amount+=1
- for(var/mob/living/carbon/alien/humanoid/M in A)//Aliens are worth twice as much as humans.
- if(istype(M, /mob/living/carbon/alien/humanoid/queen))//Queens are worth three times as much as humans.
- if(M.stat==2)
- captured_amount+=1.5
- else
- captured_amount+=3
- continue
- if(M.stat==2)
- captured_amount+=1
- continue
- captured_amount+=2
if(captured_amount[src]'s parts look very loose!"
return
-/obj/machinery/bot/attack_alien(var/mob/living/carbon/alien/user as mob)
- src.health -= rand(15,30)*brute_dam_coeff
- src.visible_message("\red [user] has slashed [src]!")
- playsound(src.loc, 'sound/weapons/slice.ogg', 25, 1, -1)
- if(prob(10))
- new /obj/effect/decal/cleanable/blood/oil(src.loc)
- healthcheck()
-
-
/obj/machinery/bot/attack_animal(var/mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0) return
src.health -= M.melee_damage_upper
@@ -155,6 +146,19 @@
/obj/machinery/bot/attack_ai(mob/user as mob)
src.attack_hand(user)
+/obj/machinery/bot/attack_hand(var/mob/living/carbon/human/user)
+
+ if(!istype(user))
+ return ..()
+
+ if(user.species.can_shred(user))
+ src.health -= rand(15,30)*brute_dam_coeff
+ src.visible_message("\red [user] has slashed [src]!")
+ playsound(src.loc, 'sound/weapons/slice.ogg', 25, 1, -1)
+ if(prob(10))
+ new /obj/effect/decal/cleanable/blood/oil(src.loc)
+ healthcheck()
+
/******************************************************************/
// Navigation procs
// Used for A-star pathfinding
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index 094f3ff700..8868914872 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -787,12 +787,6 @@ Auto Patrol: []"},
if(prob(50))
new /obj/item/robot_parts/l_arm(Tsec)
-/obj/machinery/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
- ..()
- if(!isalien(target))
- src.target = user
- src.mode = SECBOT_HUNT
-
//Secbot Construction
/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 14f8f93e56..1c8298bd0b 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -88,15 +88,18 @@
src.view_range = num
cameranet.updateVisibility(src, 0)
-/obj/machinery/camera/attack_paw(mob/living/carbon/alien/humanoid/user as mob)
+/obj/machinery/camera/attack_hand(mob/living/carbon/human/user as mob)
+
if(!istype(user))
return
- status = 0
- visible_message("\The [user] slashes at [src]!")
- playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
- icon_state = "[initial(icon_state)]1"
- add_hiddenprint(user)
- deactivate(user,0)
+
+ if(user.species.can_shred(user))
+ status = 0
+ visible_message("\The [user] slashes at [src]!")
+ playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
+ icon_state = "[initial(icon_state)]1"
+ add_hiddenprint(user)
+ deactivate(user,0)
/obj/machinery/camera/attackby(W as obj, mob/living/user as mob)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 04f5efa518..8f1eff7d63 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -77,9 +77,10 @@
if ((M.stat != 2) || (!M.client))
continue
//They need a brain!
- if ((istype(M, /mob/living/carbon/human)) && (!M.has_brain()))
- continue
-
+ if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ if(H.species.has_organ["brain"] && !H.has_brain())
+ continue
if (M.ckey == find_key)
selected = M
break
diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm
index 5887e0bc32..65871a67b3 100644
--- a/code/game/machinery/computer/HolodeckControl.dm
+++ b/code/game/machinery/computer/HolodeckControl.dm
@@ -339,10 +339,7 @@ var/global/list/holodeck_programs = list(
/obj/structure/table/holotable/attack_paw(mob/user as mob)
return attack_hand(user)
-/obj/structure/table/holotable/attack_alien(mob/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
- return attack_hand(user)
-
-/obj/structure/table/holotable/attack_animal(mob/living/simple_animal/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
+/obj/structure/table/holotable/attack_animal(mob/living/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
return attack_hand(user)
/obj/structure/table/holotable/attack_hand(mob/user as mob)
@@ -594,9 +591,6 @@ var/global/list/holodeck_programs = list(
icon = 'icons/obj/objects.dmi'
icon_state = "rack"
-/obj/structure/rack/holorack/attack_alien(mob/user as mob) //Removed code for larva since it doesn't work. Previous code is now a larva ability. /N
- return attack_hand(user)
-
/obj/structure/rack/holorack/attack_hand(mob/user as mob)
return
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 47eb7ca558..3897ee1d08 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -338,7 +338,12 @@
scantemp = "Error: Unable to locate valid genetic data."
return
if (!subject.has_brain())
- scantemp = "Error: No signs of intelligence detected."
+ if(istype(subject, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = subject
+ if(H.species.has_organ["brain"])
+ scantemp = "Error: No signs of intelligence detected."
+ else
+ scantemp = "Error: No signs of intelligence detected."
return
if (subject.suiciding == 1)
scantemp = "Error: Subject's brain is not responding to scanning stimuli."
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 288465a160..473bd973ed 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -172,18 +172,15 @@
/obj/machinery/door/window/attack_ai(mob/user as mob)
return src.attack_hand(user)
-/obj/machinery/door/window/attack_paw(mob/user as mob)
- if(istype(user, /mob/living/carbon/alien/humanoid))
- if(src.operating)
- return
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
- visible_message("\red [user] smashes against the [src.name].", 1)
- take_damage(25)
- else
- return src.attack_hand(user)
-
-
/obj/machinery/door/window/attack_hand(mob/user as mob)
+
+ if(istype(user,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.species.can_shred(H))
+ playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ visible_message("\red [user] smashes against the [src.name].", 1)
+ take_damage(25)
+ return
return src.attackby(user, user)
/obj/machinery/door/window/attackby(obj/item/weapon/I as obj, mob/user as mob)
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index 5ad0ecae56..d3e9b81e15 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -71,6 +71,27 @@
var/targeting_active = 0
var/area/turret_protected/protected_area
+/obj/machinery/turret/proc/take_damage(damage)
+ src.health -= damage
+ if(src.health<=0)
+ del src
+ return
+
+/obj/machinery/turret/attack_hand(var/mob/living/carbon/human/user)
+
+ if(!istype(user))
+ return ..()
+
+ if(user.species.can_shred(user) && !(stat & BROKEN))
+ playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
+ visible_message("\red [] has slashed at []!", user, src)
+ src.take_damage(15)
+ return
+
+/obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj)
+ take_damage(Proj.damage)
+ ..()
+ return
/obj/machinery/turret/New()
spark_system = new /datum/effect/effect/system/spark_spread
@@ -80,6 +101,11 @@
..()
return
+/obj/machinery/turret/proc/update_health()
+ if(src.health<=0)
+ del src
+ return
+
/obj/machinery/turretcover
name = "pop-up turret cover"
icon = 'icons/obj/turrets.dmi'
@@ -407,7 +433,7 @@
onclose(user, "turretid")
-/obj/machinery/turret/attack_animal(mob/living/simple_animal/M as mob)
+/obj/machinery/turret/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0) return
if(!(stat & BROKEN))
visible_message("\red [M] [M.attacktext] [src]!")
@@ -420,22 +446,6 @@
M << "\red That object is useless to you."
return
-
-
-
-/obj/machinery/turret/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
- if(!(stat & BROKEN))
- playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
- visible_message("\red [] has slashed at []!", M, src)
- src.health -= 15
- if (src.health <= 0)
- src.die()
- else
- M << "\green That object is useless to you."
- return
-
-
-
/obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0)
if(..(href, href_list))
return
@@ -494,6 +504,18 @@
icon = 'icons/obj/turrets.dmi'
icon_state = "gun_turret"
+ proc/take_damage(damage)
+ src.health -= damage
+ if(src.health<=0)
+ del src
+ return
+
+
+ bullet_act(var/obj/item/projectile/Proj)
+ take_damage(Proj.damage)
+ ..()
+ return
+
ex_act()
del src
@@ -507,24 +529,6 @@
del src
return
- proc/update_health()
- if(src.health<=0)
- del src
- return
-
- proc/take_damage(damage)
- src.health -= damage
- if(src.health<=0)
- del src
- return
-
-
- bullet_act(var/obj/item/projectile/Proj)
- src.take_damage(Proj.damage)
- ..()
- return
-
-
attack_hand(mob/user as mob)
user.set_machine(src)
var/dat = {"
@@ -546,12 +550,6 @@
attack_ai(mob/user as mob)
return attack_hand(user)
-
- attack_alien(mob/user as mob)
- user.visible_message("[user] slashes at [src]", "You slash at [src]")
- src.take_damage(15)
- return
-
Topic(href, href_list)
if(href_list["power"])
src.on = !src.on
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 78ee794b53..decf7afb43 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -418,7 +418,26 @@
/obj/mecha/attack_hand(mob/user as mob)
src.log_message("Attack by hand/paw. Attacker - [user].",1)
- if ((HULK in user.mutations) && !prob(src.deflect_chance))
+ if(istype(user,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.species.can_shred(user))
+ if(!prob(src.deflect_chance))
+ src.take_damage(15)
+ src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
+ playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
+ user << "\red You slash at the armored suit!"
+ visible_message("\red The [user] slashes at [src.name]'s armor!")
+ else
+ src.log_append_to_last("Armor saved.")
+ playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
+ user << "\green Your claws had no effect!"
+ src.occupant_message("\blue The [user]'s claws are stopped by the armor.")
+ visible_message("\blue The [user] rebounds off [src.name]'s armor!")
+ else
+ user.visible_message("[user] hits [src.name]. Nothing happens","You hit [src.name] with no visible effect.")
+ src.log_append_to_last("Armor saved.")
+ return
+ else if ((HULK in user.mutations) && !prob(src.deflect_chance))
src.take_damage(15)
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
user.visible_message("[user] hits [src.name], doing some damage.", "You hit [src.name] with all your might. The metal creaks and bends.")
@@ -430,25 +449,7 @@
/obj/mecha/attack_paw(mob/user as mob)
return src.attack_hand(user)
-
-/obj/mecha/attack_alien(mob/user as mob)
- src.log_message("Attack by alien. Attacker - [user].",1)
- if(!prob(src.deflect_chance))
- src.take_damage(15)
- src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
- playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- user << "\red You slash at the armored suit!"
- visible_message("\red The [user] slashes at [src.name]'s armor!")
- else
- src.log_append_to_last("Armor saved.")
- playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- user << "\green Your claws had no effect!"
- src.occupant_message("\blue The [user]'s claws are stopped by the armor.")
- visible_message("\blue The [user] rebounds off [src.name]'s armor!")
- return
-
-
-/obj/mecha/attack_animal(mob/living/simple_animal/user as mob)
+/obj/mecha/attack_animal(mob/living/user as mob)
src.log_message("Attack by simple animal. Attacker - [user].",1)
if(user.melee_damage_upper == 0)
user.emote("[user.friendly] [src]")
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index 5e3ba542bf..9983eff1ac 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -14,8 +14,6 @@
name = "alien thing"
desc = "theres something alien about this"
icon = 'icons/mob/alien.dmi'
-// unacidable = 1 //Aliens won't ment their own.
-
/*
* Resin
@@ -31,17 +29,17 @@
var/health = 200
//var/mob/living/affecting = null
- wall
- name = "resin wall"
- desc = "Purple slime solidified into a wall."
- icon_state = "resinwall" //same as resin, but consistency ho!
+/obj/effect/alien/resin/wall
+ name = "resin wall"
+ desc = "Purple slime solidified into a wall."
+ icon_state = "resinwall" //same as resin, but consistency ho!
- membrane
- name = "resin membrane"
- desc = "Purple slime just thin enough to let light pass through."
- icon_state = "resinmembrane"
- opacity = 0
- health = 120
+/obj/effect/alien/resin/membrane
+ name = "resin membrane"
+ desc = "Purple slime just thin enough to let light pass through."
+ icon_state = "resinmembrane"
+ opacity = 0
+ health = 120
/obj/effect/alien/resin/New()
..()
@@ -121,42 +119,7 @@
/obj/effect/alien/resin/attack_paw()
return attack_hand()
-/obj/effect/alien/resin/attack_alien()
- if (islarva(usr))//Safety check for larva. /N
- return
- usr << "\green You claw at the [name]."
- for(var/mob/O in oviewers(src))
- O.show_message("\red [usr] claws at the resin!", 1)
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- health -= rand(40, 60)
- if(health <= 0)
- usr << "\green You slice the [name] to pieces."
- for(var/mob/O in oviewers(src))
- O.show_message("\red [usr] slices the [name] apart!", 1)
- healthcheck()
- return
-
/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob)
- /*if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
- var/obj/item/weapon/grab/G = W
- if(isalien(user)&&(ishuman(G.affecting)||ismonkey(G.affecting)))
- //Only aliens can stick humans and monkeys into resin walls. Also, the wall must not have a person inside already.
- if(!affecting)
- if(G.state<2)
- user << "\red You need a better grip to do that!"
- return
- G.affecting.loc = src
- G.affecting.paralysis = 10
- for(var/mob/O in viewers(world.view, src))
- if (O.client)
- O << text("\green [] places [] in the resin wall!", G.assailant, G.affecting)
- affecting=G.affecting
- del(W)
- spawn(0)
- process()
- else
- user << "\red This wall is already occupied."
- return */
var/aforce = W.force
health = max(0, health - aforce)
@@ -234,7 +197,7 @@ Alien plants should do something if theres a lot of poison
if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
return
-
+
direction_loop:
for(var/dirn in cardinal)
var/turf/T = get_step(src, dirn)
@@ -292,15 +255,6 @@ Alien plants should do something if theres a lot of poison
health -= 5
healthcheck()
-/*/obj/effect/alien/weeds/burn(fi_amount)
- if (fi_amount > 18000)
- spawn( 0 )
- del(src)
- return
- return 0
- return 1
-*/
-
#undef NODERANGE
@@ -382,61 +336,59 @@ Alien plants should do something if theres a lot of poison
var/health = 100
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
- New()
- if(aliens_allowed)
- ..()
- spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
- Grow()
- else
+/obj/effect/alien/egg/New()
+ if(aliens_allowed)
+ ..()
+ spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
+ Grow()
+ else
+ del(src)
+
+/obj/effect/alien/egg/attack_hand(user as mob)
+
+ var/mob/living/carbon/M = user
+ if(!istype(M) || !(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs))
+ return attack_hand(user)
+
+ switch(status)
+ if(BURST)
+ user << "\red You clear the hatched egg."
del(src)
+ return
+ if(GROWING)
+ user << "\red The child is not developed yet."
+ return
+ if(GROWN)
+ user << "\red You retrieve the child."
+ Burst(0)
+ return
- attack_paw(user as mob)
- if(isalien(user))
- switch(status)
- if(BURST)
- user << "\red You clear the hatched egg."
- del(src)
- return
- if(GROWING)
- user << "\red The child is not developed yet."
- return
- if(GROWN)
- user << "\red You retrieve the child."
- Burst(0)
- return
- else
- return attack_hand(user)
+/obj/effect/alien/egg/proc/GetFacehugger()
+ return locate(/obj/item/clothing/mask/facehugger) in contents
- attack_hand(user as mob)
- user << "It feels slimy."
- return
+/obj/effect/alien/egg/proc/Grow()
+ icon_state = "egg"
+ status = GROWN
+ new /obj/item/clothing/mask/facehugger(src)
+ return
- proc/GetFacehugger()
- return locate(/obj/item/clothing/mask/facehugger) in contents
-
- proc/Grow()
- icon_state = "egg"
- status = GROWN
- new /obj/item/clothing/mask/facehugger(src)
- return
-
- proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
- if(status == GROWN || status == GROWING)
- var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
- icon_state = "egg_hatched"
- flick("egg_opening", src)
- status = BURSTING
- spawn(15)
- status = BURST
- loc.contents += child//need to write the code for giving it to the alien later
- if(kill && istype(child))
- child.Die()
- else
- for(var/mob/M in range(1,src))
- if(CanHug(M))
- child.Attach(M)
- break
+/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
+ if(status == GROWN || status == GROWING)
+ var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
+ icon_state = "egg_hatched"
+ flick("egg_opening", src)
+ status = BURSTING
+ spawn(15)
+ status = BURST
+ child.loc = get_turf(src)
+ if(kill && istype(child))
+ child.Die()
+ else
+ for(var/mob/M in range(1,src))
+ if(CanHug(M))
+ child.Attach(M)
+ break
/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index be54a95ba1..682347669a 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -174,7 +174,7 @@
if(prob(25))
src.visible_message("\blue \the [src] skitters[pick(" away"," around","")].")
else if(prob(5))
- //ventcrawl!
+ //vent crawl!
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index b4155d6fca..c7f8fadfcb 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -155,15 +155,6 @@
/obj/item/attack_paw(mob/user as mob)
- if(isalien(user)) // -- TLE
- var/mob/living/carbon/alien/A = user
-
- if(!A.has_fine_manipulation || w_class >= 4)
- if(src in A.contents) // To stop Aliens having items stuck in their pockets
- A.drop_from_inventory(src)
- user << "Your claws aren't capable of such fine manipulation."
- return
-
if (istype(src.loc, /obj/item/weapon/storage))
for(var/mob/M in range(1, src.loc))
if (M.s_active == src.loc)
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index a30168479a..635093436f 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -32,9 +32,6 @@
..()
usr << text("The service panel is [src.open ? "open" : "closed"].")
- attack_alien(mob/user as mob)
- return attack_hand(user)
-
attack_paw(mob/user as mob)
return attack_hand(user)
diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm
index 3080c05f09..d9d7ec0126 100644
--- a/code/game/objects/items/weapons/surgery_tools.dm
+++ b/code/game/objects/items/weapons/surgery_tools.dm
@@ -21,106 +21,6 @@
w_class = 2.0
origin_tech = "materials=1;biotech=1"
-/*HAHA, SUCK IT, 2000 LINES OF SPAGHETTI CODE!
-
-NOW YOUR JOB IOS DONE BY ONLY 500 LINES OF SPAGHETTI CODE!
-
-LOOK FOR SURGERY.DM*/
-
-/*
-/obj/item/weapon/retractor/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M.eye_op_stage)
- if(1.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his eyes retracted by [user].", 1)
- M << "\red [user] begins to seperate your eyes with [src]!"
- user << "\red You seperate [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to have his eyes retracted.", \
- "\red You begin to pry open your eyes with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(15)
-
- M:eye_op_stage = 2.0
-
- else if(user.zone_sel.selecting == "chest")
- switch(M:alien_op_stage)
- if(3.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- var/obj/item/alien_embryo/A = locate() in M.contents
- if(!A)
- return ..()
- user.visible_message("\red [user] begins to pull something out of [M]'s chest.", "\red You begin to pull the alien organism out of [M]'s chest.")
-
- spawn(20 + rand(0,50))
- if(!A || A.loc != M)
- return
-
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(30))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(30)
-
- if(A.stage > 3)
- var/chance = 15 + max(0, A.stage - 3) * 10
- if(prob(chance))
- A.AttemptGrow(0)
- M:alien_op_stage = 4.0
-
- if(M)
- user.visible_message("\red [user] pulls an alien organism out of [M]'s chest.", "\red You pull the alien organism out of [M]'s chest.")
- A.loc = M.loc //alien embryo handles cleanup
-
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-
- return
-*/
-
/*
* Hemostat
*/
@@ -135,126 +35,6 @@ LOOK FOR SURGERY.DM*/
origin_tech = "materials=1;biotech=1"
attack_verb = list("attacked", "pinched")
-/*
-/obj/item/weapon/hemostat/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- if(user.zone_sel.selecting == "groin")
- if(istype(M, /mob/living/carbon/human))
- switch(M:appendix_op_stage)
- if(1.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [user] is beginning to clamp bleeders in [M]'s abdomen cut open with [src].", 1)
- M << "\red [user] begins to clamp bleeders in your abdomen with [src]!"
- user << "\red You clamp bleeders in [M]'s abdomen with [src]!"
- M:appendix_op_stage = 2.0
- if(4.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [user] is removing [M]'s appendix with [src].", 1)
- M << "\red [user] begins to remove your appendix with [src]!"
- user << "\red You remove [M]'s appendix with [src]!"
- for(var/datum/disease/D in M.viruses)
- if(istype(D, /datum/disease/appendicitis))
- new /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed(get_turf(M))
- M:appendix_op_stage = 5.0
- return
- new /obj/item/weapon/reagent_containers/food/snacks/appendix(get_turf(M))
- M:appendix_op_stage = 5.0
- return
-
- if (user.zone_sel.selecting == "eyes")
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M.eye_op_stage)
- if(2.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his eyes mended by [user].", 1)
- M << "\red [user] begins to mend your eyes with [src]!"
- user << "\red You mend [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to have his eyes mended.", \
- "\red You begin to mend your eyes with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(15)
- M:eye_op_stage = 3.0
-
- else if(user.zone_sel.selecting == "chest")
- if(M:alien_op_stage == 2.0 || M:alien_op_stage == 3.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- user.visible_message("\red [user] begins to dig around in [M]'s chest.", "\red You begin to dig around in [M]'s chest.")
-
- spawn(20 + (M:alien_op_stage == 3 ? 0 : rand(0,50)))
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(30))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(30)
-
- var/obj/item/alien_embryo/A = locate() in M.contents
- if(A)
- var/dat = "\blue You found an unknown alien organism in [M]'s chest!"
- if(A.stage < 4)
- dat += " It's small and weak, barely the size of a foetus."
- if(A.stage > 3)
- dat += " It's grown quite large, and writhes slightly as you look at it."
- if(prob(10))
- A.AttemptGrow()
- user << dat
- M:alien_op_stage = 3.0
- else
- user << "\blue You find nothing of interest."
-
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-
- return
-*/
-
/*
* Cautery
*/
@@ -269,81 +49,6 @@ LOOK FOR SURGERY.DM*/
origin_tech = "materials=1;biotech=1"
attack_verb = list("burnt")
-/*
-/obj/item/weapon/cautery/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- if(user.zone_sel.selecting == "groin")
- if(istype(M, /mob/living/carbon/human))
- switch(M:appendix_op_stage)
- if(5.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [user] is beginning to cauterize the incision in [M]'s abdomen with [src].", 1)
- M << "\red [user] begins to cauterize the incision in your abdomen with [src]!"
- user << "\red You cauterize the incision in [M]'s abdomen with [src]!"
- M:appendix_op_stage = 6.0
- for(var/datum/disease/appendicitis in M.viruses)
- appendicitis.cure()
- return
-
- if (user.zone_sel.selecting == "eyes")
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M.eye_op_stage)
- if(3.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his eyes cauterized by [user].", 1)
- M << "\red [user] begins to cauterize your eyes!"
- user << "\red You cauterize [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to have his eyes cauterized.", \
- "\red You begin to cauterize your eyes!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(15)
- M.sdisabilities &= ~BLIND
- M.eye_stat = 0
- M:eye_op_stage = 0.0
-
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-
- return
-*/
-
/*
* Surgical Drill
*/
@@ -391,232 +96,6 @@ LOOK FOR SURGERY.DM*/
"\red [user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.")
return (BRUTELOSS)
-/*
-/obj/item/weapon/scalpel/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return ..()
-
- //if(M.mutations & HUSK) return ..()
-
- if((CLUMSY in user.mutations) && prob(50))
- M = user
- return eyestab(M,user)
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- src.add_fingerprint(user)
-
- if(user.zone_sel.selecting == "groin")
- if(istype(M, /mob/living/carbon/human))
- switch(M:appendix_op_stage)
- if(0.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his abdomen cut open with [src] by [user].", 1)
- M << "\red [user] begins to cut open your abdomen with [src]!"
- user << "\red You cut [M]'s abdomen open with [src]!"
- M:appendix_op_stage = 1.0
- if(3.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his appendix seperated with [src] by [user].", 1)
- M << "\red [user] begins to seperate your appendix with [src]!"
- user << "\red You seperate [M]'s appendix with [src]!"
- M:appendix_op_stage = 4.0
- return
-
- if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/slime))
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- switch(M:brain_op_stage)
- if(0.0)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M.name] is beginning to have its flesh cut open with [src] by [user].", 1)
- M << "\red [user] begins to cut open your flesh with [src]!"
- user << "\red You cut [M]'s flesh open with [src]!"
- M:brain_op_stage = 1.0
-
- return
-
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his head cut open with [src] by [user].", 1)
- M << "\red [user] begins to cut open your head with [src]!"
- user << "\red You cut [M]'s head open with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to cut open his skull with [src]!", \
- "\red You begin to cut open your head with [src]!" \
- )
-
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- affecting.take_damage(7)
- else
- M.take_organ_damage(7)
-
- M.updatehealth()
- M:brain_op_stage = 1.0
-
- if(1)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M.name] is having its silky innards cut apart with [src] by [user].", 1)
- M << "\red [user] begins to cut apart your innards with [src]!"
- user << "\red You cut [M]'s silky innards apart with [src]!"
- M:brain_op_stage = 2.0
- return
- if(2.0)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- var/mob/living/carbon/slime/slime = M
- if(slime.cores > 0)
- if(istype(M, /mob/living/carbon/slime))
- user << "\red You attempt to remove [M]'s core, but [src] is ineffective!"
- return
-
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is having his connections to the brain delicately severed with [src] by [user].", 1)
- M << "\red [user] begins to cut open your head with [src]!"
- user << "\red You cut [M]'s head open with [src]!"
- else
- user.visible_message( \
- "\red [user] begin to delicately remove the connections to his brain with [src]!", \
- "\red You begin to cut open your head with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You nick an artery!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(75))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(75)
-
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- affecting.take_damage(7)
- else
- M.take_organ_damage(7)
-
- M.updatehealth()
- M:brain_op_stage = 3.0
- else
- ..()
- return
-
- else if(user.zone_sel.selecting == "eyes")
- user << "\blue So far so good."
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- if(istype(M, /mob/living/carbon/alien) || istype(M, /mob/living/carbon/slime))//Aliens don't have eyes./N
- user << "\red You cannot locate any eyes on this creature!"
- return
-
- switch(M:eye_op_stage)
- if(0.0)
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] is beginning to have his eyes incised with [src] by [user].", 1)
- M << "\red [user] begins to cut open your eyes with [src]!"
- user << "\red You make an incision around [M]'s eyes with [src]!"
- else
- user.visible_message( \
- "\red [user] begins to cut around his eyes with [src]!", \
- "\red You begin to cut open your eyes with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- user << "\blue So far so good before."
- M.updatehealth()
- M:eye_op_stage = 1.0
- user << "\blue So far so good after."
-
- else if(user.zone_sel.selecting == "chest")
- switch(M:alien_op_stage)
- if(0.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- user.visible_message("\red [user] begins to slice open [M]'s chest.", "\red You begin to slice open [M]'s chest.")
-
- spawn(rand(20,50))
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- M:alien_op_stage = 1.0
- user << "\blue So far so good."
-
- else
- return ..()
-/* wat
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()*/
- return
-*/
-
/*
* Researchable Scalpels
*/
@@ -667,157 +146,6 @@ LOOK FOR SURGERY.DM*/
sharp = 1
edge = 1
-/*
-/obj/item/weapon/circular_saw/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return ..()
-
- if((CLUMSY in user.mutations) && prob(50))
- M = user
- return eyestab(M,user)
-
- if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/table/, M.loc) && M.lying && prob(50))))
- return ..()
-
- src.add_fingerprint(user)
-
- if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/slime))
-
- var/mob/living/carbon/human/H = M
- if(istype(H) && ( \
- (H.head && H.head.flags & HEADCOVERSEYES) || \
- (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || \
- (H.glasses && H.glasses.flags & GLASSESCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- var/mob/living/carbon/monkey/Mo = M
- if(istype(Mo) && ( \
- (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \
- ))
- user << "\red You're going to need to remove that mask/helmet/glasses first."
- return
-
- switch(M:brain_op_stage)
- if(1.0)
- if(istype(M, /mob/living/carbon/slime))
- return
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] has his skull sawed open with [src] by [user].", 1)
- M << "\red [user] begins to saw open your head with [src]!"
- user << "\red You saw [M]'s head open with [src]!"
- else
- user.visible_message( \
- "\red [user] saws open his skull with [src]!", \
- "\red You begin to saw open your head with [src]!" \
- )
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- if(affecting.take_damage(40))
- M:UpdateDamageIcon()
- M.updatehealth()
- else
- M.take_organ_damage(40)
-
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("head")
- affecting.take_damage(7)
- else
- M.take_organ_damage(7)
-
- M.updatehealth()
- M:brain_op_stage = 2.0
-
- if(2.0)
- if(istype(M, /mob/living/carbon/slime))
- if(M.stat == 2)
- var/mob/living/carbon/slime/slime = M
- if(slime.cores > 0)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M.name] is having one of its cores sawed out with [src] by [user].", 1)
-
- slime.cores--
- M << "\red [user] begins to remove one of your cores with [src]! ([slime.cores] cores remaining)"
- user << "\red You cut one of [M]'s cores out with [src]! ([slime.cores] cores remaining)"
-
- new slime.coretype(M.loc)
-
- if(slime.cores <= 0)
- M.icon_state = "[slime.colour] baby slime dead-nocore"
-
- return
-
- if(3.0)
- /*if(M.mind && M.mind.changeling)
- user << "\red The neural tissue regrows before your eyes as you cut it."
- return*/
-
- if(M != user)
- for(var/mob/O in (viewers(M) - user - M))
- O.show_message("\red [M] has his spine's connection to the brain severed with [src] by [user].", 1)
- M << "\red [user] severs your brain's connection to the spine with [src]!"
- user << "\red You sever [M]'s brain's connection to the spine with [src]!"
- else
- user.visible_message( \
- "\red [user] severs his brain's connection to the spine with [src]!", \
- "\red You sever your brain's connection to the spine with [src]!" \
- )
-
- user.attack_log += "\[[time_stamp()]\] Debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- M.attack_log += "\[[time_stamp()]\] Debrained by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
-
- log_attack("[user.name] ([user.ckey]) debrained [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])")
-
-
- var/obj/item/organ/brain/B = new(M.loc)
- B.transfer_identity(M)
-
- M:brain_op_stage = 4.0
- M.death()//You want them to die after the brain was transferred, so not to trigger client death() twice.
-
- else
- ..()
- return
-
- else if(user.zone_sel.selecting == "chest")
- switch(M:alien_op_stage)
- if(1.0)
- var/mob/living/carbon/human/H = M
- if(!istype(H))
- return ..()
-
- if(H.wear_suit || H.w_uniform)
- user << "\red You're going to need to remove that suit/jumpsuit first."
- return
-
- user.visible_message("\red [user] begins to slice through the bone of [M]'s chest.", "\red You begin to slice through the bone of [M]'s chest.")
-
- spawn(20 + rand(0,50))
- if(M == user && prob(25))
- user << "\red You mess up!"
- if(istype(M, /mob/living/carbon/human))
- var/datum/organ/external/affecting = M:get_organ("chest")
- if(affecting.take_damage(15))
- M:UpdateDamageIcon()
- else
- M.take_organ_damage(15)
-
- M:alien_op_stage = 2.0
- user << "\blue So far so good."
-
- else
- return ..()
-/*
- else if((!(user.zone_sel.selecting == "head")) || (!(user.zone_sel.selecting == "groin")) || (!(istype(M, /mob/living/carbon/human))))
- return ..()
-*/
- return
-*/
-
//misc, formerly from code/defines/weapons.dm
/obj/item/weapon/bonegel
name = "bone gel"
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index af06f192bc..a79860522d 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -1,11 +1,46 @@
/obj/structure
icon = 'icons/obj/structures.dmi'
var/climbable
+ var/breakable
+ var/parts
+
+/obj/structure/proc/destroy()
+ if(parts)
+ new parts(loc)
+ density = 0
+ del(src)
+
+/obj/structure/attack_hand(mob/user)
+ if(breakable)
+ if(HULK in user.mutations)
+ user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
+ visible_message("[user] smashes the [src] apart!")
+ destroy()
+ else if(istype(user,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.species.can_shred(user))
+ visible_message("[H] slices [src] apart!")
+ destroy()
+
+/obj/structure/attack_animal(mob/living/user)
+ if(breakable)
+ if(user.wall_smash)
+ visible_message("[user] smashes [src] apart!")
+ destroy()
+
+/obj/structure/attack_paw(mob/user)
+ if(breakable) attack_hand(user)
/obj/structure/blob_act()
if(prob(50))
del(src)
+/obj/structure/meteorhit(obj/O as obj)
+ destroy(src)
+
+/obj/structure/attack_tk()
+ return
+
/obj/structure/ex_act(severity)
switch(severity)
if(1.0)
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 0a30218400..637b762706 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -172,7 +172,7 @@
return
-/obj/structure/closet/attack_animal(mob/living/simple_animal/user as mob)
+/obj/structure/closet/attack_animal(mob/living/user as mob)
if(user.wall_smash)
visible_message("\red [user] destroys the [src]. ")
for(var/atom/movable/A as mob|obj in src)
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index cfcc3c1176..3ba3c79a37 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -10,7 +10,7 @@
/obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user)
- if(isrobot(user) || isalien(user))
+ if(isrobot(user))
return
if(istype(O, /obj/item/weapon/extinguisher))
if(!has_extinguisher && opened)
@@ -26,7 +26,7 @@
/obj/structure/extinguisher_cabinet/attack_hand(mob/user)
- if(isrobot(user) || isalien(user))
+ if(isrobot(user))
return
if (hasorgans(user))
var/datum/organ/external/temp = user:organs_by_name["r_hand"]
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 630ed6687c..e1f0804c0e 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -31,32 +31,34 @@
attack_hand(user)
/obj/structure/grille/attack_hand(mob/user as mob)
+
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
- user.visible_message("[user] kicks [src].", \
+
+ var/damage_dealt
+ if(istype(user,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.species.can_shred(H))
+ damage_dealt = 5
+ user.visible_message("[user] mangles [src].", \
+ "You mangle [src].", \
+ "You hear twisting metal.")
+
+ if(!damage_dealt)
+ user.visible_message("[user] kicks [src].", \
"You kick [src].", \
"You hear twisting metal.")
if(shock(user, 70))
return
+
if(HULK in user.mutations)
- health -= 5
+ damage_dealt += 5
else
- health -= 1
+ damage_dealt += 1
+
+ health -= damage_dealt
healthcheck()
-/obj/structure/grille/attack_alien(mob/user as mob)
- if(istype(user, /mob/living/carbon/alien/larva)) return
-
- playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
- user.visible_message("[user] mangles [src].", \
- "You mangle [src].", \
- "You hear twisting metal.")
-
- if(!shock(user, 70))
- health -= 5
- healthcheck()
- return
-
/obj/structure/grille/attack_slime(mob/user as mob)
var/mob/living/carbon/slime/S = user
if (!S.is_adult)
@@ -199,6 +201,7 @@
// returns 1 if shocked, 0 otherwise
/obj/structure/grille/proc/shock(mob/user as mob, prb)
+
if(!anchored || destroyed) // anchored/destroyed grilles are never connected
return 0
if(!prob(prb))
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index cd9dfd3e8a..8b586c9461 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -83,7 +83,7 @@
return
- proc/attack_generic(mob/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime
+ proc/attack_generic(mob/user as mob, damage = 0) //used by attack_animal and attack_slime
health -= damage
if(health <= 0)
user.visible_message("[user] tears open [src]!")
@@ -91,10 +91,6 @@
else //for nicer text~
user.visible_message("[user] tears at [src]!")
- attack_alien(mob/user as mob)
- if(islarva(user)) return
- attack_generic(user, 15)
-
attack_animal(mob/user as mob)
if(!isanimal(user)) return
var/mob/living/simple_animal/M = user
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 4902b6a631..aa07d1621a 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -256,7 +256,9 @@
var/close_delay = 100
TryToSwitchState(atom/user)
- if(isalien(user))
+
+ var/mob/living/carbon/M = user
+ if(istype(M) && locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs)
return ..()
Open()
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 5977121973..f9b45a6075 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -10,11 +10,23 @@
/obj/structure/mirror/attack_hand(mob/user as mob)
+
if(shattered) return
if(ishuman(user))
var/mob/living/carbon/human/H = user
+ if(H.a_intent == "hurt")
+ if(shattered)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
+ return
+ if(prob(30) || H.species.can_shred(H))
+ user.visible_message("[user] smashes [src]!")
+ shatter()
+ else
+ user.visible_message("[user] hits [src] and bounces off!")
+ return
+
var/userloc = H.loc
//see code/modules/mob/new_player/preferences.dm at approx line 545 for comments!
@@ -83,16 +95,6 @@
visible_message("[user] hits [src] with [I]!")
playsound(src.loc, 'sound/effects/Glasshit.ogg', 70, 1)
-
-/obj/structure/mirror/attack_alien(mob/user as mob)
- if(islarva(user)) return
- if(shattered)
- playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
- return
- user.visible_message("[user] smashes [src]!")
- shatter()
-
-
/obj/structure/mirror/attack_animal(mob/user as mob)
if(!isanimal(user)) return
var/mob/living/simple_animal/M = user
diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
index a45e2436b8..76ac4b18ac 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
@@ -30,15 +30,20 @@
return
/obj/structure/stool/bed/nest/buckle_mob(mob/M as mob, mob/user as mob)
+
if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) )
return
- if(istype(M,/mob/living/carbon/alien))
- return
- if(!istype(user,/mob/living/carbon/alien/humanoid))
+ unbuckle()
+
+ var/mob/living/carbon/xenos = user
+ var/mob/living/carbon/victim = M
+
+ if(istype(victim) && locate(/datum/organ/internal/xenos/hivenode) in victim.internal_organs)
return
- unbuckle()
+ if(istype(xenos) && !(locate(/datum/organ/internal/xenos/hivenode) in xenos.internal_organs))
+ return
if(M == usr)
return
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 2bda55b93f..d6e461b4c1 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -20,8 +20,9 @@
layer = 2.8
throwpass = 1 //You can throw objects over this, despite it's density.")
climbable = 1
+ breakable = 1
+ parts = /obj/item/weapon/table_parts
- var/parts = /obj/item/weapon/table_parts
var/flipped = 0
var/health = 100
@@ -43,16 +44,6 @@
update_adjacent()
..()
-/obj/structure/table/proc/destroy()
- new parts(loc)
- density = 0
- del(src)
-
-/obj/structure/rack/proc/destroy()
- new parts(loc)
- density = 0
- del(src)
-
/obj/structure/table/update_icon()
spawn(2) //So it properly updates when deleting
@@ -247,49 +238,6 @@
else
dir = 2
-/obj/structure/table/ex_act(severity)
- switch(severity)
- if(1.0)
- del(src)
- return
- if(2.0)
- if (prob(50))
- del(src)
- return
- if(3.0)
- if (prob(25))
- destroy()
- else
- return
-
-
-/obj/structure/table/blob_act()
- if(prob(75))
- destroy()
-
-/obj/structure/table/attack_paw(mob/user)
- if(HULK in user.mutations)
- user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- visible_message("[user] smashes the [src] apart!")
- destroy()
-
-
-/obj/structure/table/attack_alien(mob/user)
- visible_message("[user] slices [src] apart!")
-
-/obj/structure/table/attack_animal(mob/living/simple_animal/user)
- if(user.wall_smash)
- visible_message("[user] smashes [src] apart!")
- destroy()
-
-
-
-/obj/structure/table/attack_hand(mob/user)
- if(HULK in user.mutations)
- visible_message("[user] smashes [src] apart!")
- user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- destroy()
-
/obj/structure/table/attack_tk() // no telehulk sorry
return
@@ -576,29 +524,9 @@
flags = FPRINT
anchored = 1.0
throwpass = 1 //You can throw objects over this, despite it's density.
- var/parts = /obj/item/weapon/rack_parts
-
-/obj/structure/rack/ex_act(severity)
- switch(severity)
- if(1.0)
- del(src)
- if(2.0)
- del(src)
- if(prob(50))
- new /obj/item/weapon/rack_parts(src.loc)
- if(3.0)
- if(prob(25))
- del(src)
- new /obj/item/weapon/rack_parts(src.loc)
-
-/obj/structure/rack/blob_act()
- if(prob(75))
- del(src)
- return
- else if(prob(50))
- new /obj/item/weapon/rack_parts(src.loc)
- del(src)
- return
+ breakable = 1
+ climbable = 1
+ parts = /obj/item/weapon/rack_parts
/obj/structure/rack/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
@@ -629,32 +557,4 @@
return
user.drop_item()
if(W && W.loc) W.loc = src.loc
- return
-
-/obj/structure/rack/meteorhit(obj/O as obj)
- del(src)
-
-
-/obj/structure/table/attack_hand(mob/user)
- if(HULK in user.mutations)
- visible_message("[user] smashes [src] apart!")
- user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- destroy()
-
-/obj/structure/rack/attack_paw(mob/user)
- if(HULK in user.mutations)
- user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- visible_message("[user] smashes [src] apart!")
- destroy()
-
-/obj/structure/rack/attack_alien(mob/user)
- visible_message("[user] slices [src] apart!")
- destroy()
-
-/obj/structure/rack/attack_animal(mob/living/simple_animal/user)
- if(user.wall_smash)
- visible_message("[user] smashes [src] apart!")
- destroy()
-
-/obj/structure/rack/attack_tk() // no telehulk sorry
return
\ No newline at end of file
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 7052bf5a98..cad2907ac7 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -114,6 +114,14 @@
new /obj/item/weapon/shard(loc)
if(reinf) new /obj/item/stack/rods(loc)
del(src)
+ else if (istype(usr,/mob/living/carbon/human))
+
+ var/mob/living/carbon/human/H = usr
+
+ if(H.species.can_shred(H))
+ attack_generic(H,25)
+ return
+
else if (usr.a_intent == "hurt")
playsound(src.loc, 'sound/effects/glassknock.ogg', 80, 1)
usr.visible_message("\red [usr.name] bangs against the [src.name]!", \
@@ -131,7 +139,7 @@
return attack_hand(user)
-/obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_alien, attack_animal, and attack_slime
+/obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_animal and attack_slime
health -= damage
if(health <= 0)
user.visible_message("[user] smashes through [src]!")
@@ -142,11 +150,6 @@
user.visible_message("[user] smashes into [src]!")
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
-
-/obj/structure/window/attack_alien(mob/user as mob)
- if(islarva(user)) return
- attack_generic(user, 15)
-
/obj/structure/window/attack_animal(mob/user as mob)
if(!isanimal(user)) return
var/mob/living/simple_animal/M = user
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index d264f8375d..b654aeadaf 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -242,7 +242,7 @@
return src.attack_hand(user)
-/turf/simulated/wall/attack_animal(mob/living/simple_animal/M as mob)
+/turf/simulated/wall/attack_animal(mob/living/M as mob)
if(M.wall_smash)
if (istype(src, /turf/simulated/wall/r_wall) && !rotting)
M << text("\blue This wall is far too strong for you to destroy.")
diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm
index ee37b5eb9c..82a81e5af7 100644
--- a/code/game/verbs/suicide.dm
+++ b/code/game/verbs/suicide.dm
@@ -191,27 +191,6 @@
else
src << "Aborting suicide attempt."
-/mob/living/carbon/alien/humanoid/verb/suicide()
- set hidden = 1
-
- if (stat == 2)
- src << "You're already dead!"
- return
-
- if (suiciding)
- src << "You're already committing suicide! Be patient!"
- return
-
- var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
-
- if(confirm == "Yes")
- suiciding = 1
- viewers(src) << "\red [src] is thrashing wildly! It looks like \he's trying to commit suicide."
- //put em at -175
- adjustOxyLoss(max(175 - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- updatehealth()
-
-
/mob/living/carbon/slime/verb/suicide()
set hidden = 1
if (stat == 2)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 12b5bf7789..46b1beef78 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -141,10 +141,6 @@ var/global/floorIsLava = 0
body += {"
Rudimentary transformation:
These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.
Observer |
- \[ Alien: Drone,
- Hunter,
- Queen,
- Sentinel,
Larva \]
Human
\[ slime: Baby,
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 0a83ce4903..a5ccbb9100 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -233,11 +233,8 @@
M_job = "slime"
else if(ismonkey(M))
M_job = "Monkey"
- else if(isalien(M)) //aliens
- if(islarva(M))
- M_job = "Alien larva"
- else
- M_job = "Alien"
+ else if(isalien(M))
+ M_job = "Alien"
else
M_job = "Carbon-based"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 1493751ab1..d0cc41da62 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -284,10 +284,6 @@
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("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 )
@@ -2205,11 +2201,6 @@
if(aliens_allowed)
new /datum/event/alien_infestation
message_admins("[key_name_admin(usr)] has spawned aliens", 1)
- if("alien_silent") //replaces the spawn_xeno verb
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","ALS")
- if(aliens_allowed)
- create_xeno()
if("spiders")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SL")
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index ce2a2800bb..a0e9fd9878 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -225,38 +225,6 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
IonStorm(0)
feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-//I use this proc for respawn character too. /N
-/proc/create_xeno(ckey)
- if(!ckey)
- var/list/candidates = list()
- for(var/mob/M in player_list)
- if(M.stat != DEAD) continue //we are not dead!
- if(!M.client.prefs.be_special & BE_ALIEN) continue //we don't want to be an alium
- if(M.client.is_afk()) continue //we are afk
- if(M.mind && M.mind.current && M.mind.current.stat != DEAD) continue //we have a live body we are tied to
- candidates += M.ckey
- if(candidates.len)
- ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
- else
- usr << "Error: create_xeno(): no suitable candidates."
- if(!istext(ckey)) return 0
-
- var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva")
- var/obj/effect/landmark/spawn_here = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin)
- var/mob/living/carbon/alien/new_xeno
- switch(alien_caste)
- if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen(spawn_here)
- if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
- if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
- if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
- if("Larva") new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
- else return 0
-
- new_xeno.ckey = ckey
- message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
- return 1
-
/*
Allow admins to set players to be able to respawn/bypass 30 min wait, without the admin having to edit variables directly
Ccomp's first proc.
@@ -376,9 +344,6 @@ Ccomp's first proc.
log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD")
message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1)
-
-
-
/*
If a guy was gibbed and you want to revive him, this is a good way to do so.
Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
@@ -406,32 +371,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
- //Check if they were an alien
- if(G_found.mind.assigned_role=="Alien")
- if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes")
- var/turf/T
- if(xeno_spawn.len) T = pick(xeno_spawn)
- else T = pick(latejoin)
-
- var/mob/living/carbon/alien/new_xeno
- switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
- if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
- if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
- if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
- if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen(T)
- else//If we don't know what special role they have, for whatever reason, or they're a larva.
- create_xeno(G_found.ckey)
- return
-
- //Now to give them their mind back.
- G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_xeno.key = G_found.key
- new_xeno << "You have been fully respawned. Enjoy the game."
- message_admins("\blue [key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.", 1)
- return //all done. The ghost is auto-deleted
//check if they were a monkey
- else if(findtext(G_found.real_name,"monkey"))
+ if(findtext(G_found.real_name,"monkey"))
if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")
var/mob/living/carbon/monkey/new_monkey = new(pick(latejoin))
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
@@ -440,8 +382,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("\blue [key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.", 1)
return //all done. The ghost is auto-deleted
-
- //Ok, it's not a xeno or a monkey. So, spawn a human.
+ //Ok, it's not a monkey. So, spawn a human.
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 193d63f96c..119076e6a8 100755
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -1580,6 +1580,9 @@ datum/preferences
var/datum/organ/internal/I = character.internal_organs_by_name[name]
var/status = organ_data[name]
+ if(!I || !O)
+ continue
+
if(status == "amputated")
O.amputated = 1
O.status |= ORGAN_DESTROYED
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index 51a8fb499e..7b6710f6c4 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -1499,7 +1499,7 @@ proc/populate_seed_list()
seed_noun = "nodes"
display_name = "replicant pods"
packet_icon = "seed-replicapod"
- products = list(/mob/living/carbon/monkey/diona)
+ products = list(/mob/living/carbon/alien/diona)
plant_icon = "replicapod"
product_requires_player = 1
immutable = 1
diff --git a/code/modules/hydroponics/seed_mobs.dm b/code/modules/hydroponics/seed_mobs.dm
index 0bb301298a..d80247abd6 100644
--- a/code/modules/hydroponics/seed_mobs.dm
+++ b/code/modules/hydroponics/seed_mobs.dm
@@ -69,7 +69,7 @@
host << "\green You awaken slowly, stirring into sluggish motion as the air caresses you."
// This is a hack, replace with some kind of species blurb proc.
- if(istype(host,/mob/living/carbon/monkey/diona))
+ if(istype(host,/mob/living/carbon/alien/diona))
host << "You are [host], one of a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders."
host << "Too much darkness will send you into shock and starve you, but light will help you heal."
diff --git a/code/modules/mob/abilities.dm b/code/modules/mob/abilities.dm
deleted file mode 100644
index e5e2be9af0..0000000000
--- a/code/modules/mob/abilities.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-Creature-level abilities.
-*/
-
-/var/global/list/ability_verbs = list( )
-
-/*
-
- Example ability:
-
-/client/proc/test_ability()
-
- set category = "Ability"
- set name = "Test ability"
- set desc = "An ability for testing."
-
- // Check if the client has a mob and if the mob is valid and alive.
- if(!mob || !istype(mob,/mob/living) || mob.stat)
- src << "\red You must be corporeal and alive to do that."
- return 0
-
- //Handcuff check.
- if(mob.restrained())
- src << "\red You cannot do this while restrained."
- return 0
-
- if(istype(mob,/mob/living/carbon))
- var/mob/living/carbon/M = mob
- if(M.handcuffed)
- src << "\red You cannot do this while cuffed."
- return 0
-
- src << "\blue You perform an ability."
-
-*/
\ No newline at end of file
diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm
index 797715c33e..dc1ca25727 100644
--- a/code/modules/mob/death.dm
+++ b/code/modules/mob/death.dm
@@ -56,6 +56,8 @@
timeofdeath = world.time
+ var/tod = worldtime2text() //weasellos time of death patch
+ if(mind) mind.store_memory("Time of death: [tod]", 0)
living_mob_list -= src
dead_mob_list += src
return ..(gibbed)
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index d54e1a90e7..b0ffe74fe6 100755
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -12,6 +12,23 @@
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)
+ understood = 1
+
+ if(understood)
+ if(!speaker_mask) speaker_mask = speaker.name
+ player << "[name], [speaker_mask] [speech_verb], \"[message]\""
+
/datum/language/unathi
name = "Sinta'unathi"
desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi."
@@ -74,6 +91,105 @@
colour = "rough"
key = "3"
+/datum/language/xenos
+ name = "Hivemind"
+ desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
+ speech_verb = "hisses"
+ colour = "alien"
+ key = "a"
+ flags = RESTRICTED | HIVEMIND
+
+/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 between their tiny minds."
+ speech_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."
+ speech_verb = "transmits"
+ colour = "say_quote"
+ 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 = "[name], [speaker.name]"
+ var/message_body = "[speaker.say_quote(message)], \"[message]\""
+
+ 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)
+
+ world << "Got through checks, transmitting."
+
+ 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 = "[name], [speaker.name]"
+ 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("synthesised voice beeps, \"beep beep beep\"",2)
+
+/datum/language/binary/drone
+ name = "Drone Talk"
+ desc = "A heavily encoded damage control coordination stream."
+ speech_verb = "transmits"
+ colour = "say_quote"
+ key = "d"
+ flags = RESTRICTED | HIVEMIND
+ drone_only = 1
+
// Language handling.
/mob/proc/add_language(var/language)
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 214c091c3e..0cb28d1086 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -1,210 +1,90 @@
-#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
+
+ var/adult_form
+ var/dead_icon
+ var/amount_grown = 0
+ var/max_grown = 10
+ var/time_of_birth
+ var/co2overloadtime = null
+ var/temperature_resistance = T0C+75
+ var/language
+
+/mob/living/carbon/alien/New()
+
+ 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/phoron_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/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
+//This is fine, works the same as a human
+/mob/living/carbon/alien/Bump(atom/movable/AM as mob|obj, yes)
-/mob/living/carbon/alien/setDNA()
+ 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 You fail to push [tmob]'s fat ass out of the way."
+ 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
-/*----------------------------------------
-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/Stat()
+ ..()
+ stat(null, "Progress: [amount_grown]/[max_grown]")
-
-/*----------------------------------------
-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
-
-/mob/living/carbon/alien/has_eyes()
+/mob/living/carbon/alien/restrained()
return 0
-#undef HEAT_DAMAGE_LEVEL_1
-#undef HEAT_DAMAGE_LEVEL_2
-#undef HEAT_DAMAGE_LEVEL_3
+/mob/living/carbon/alien/show_inv(mob/user as mob)
+ return //Consider adding cuffs and hats to this, for the sake of fun.
+
+/mob/living/carbon/alien/can_use_vents()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/alien_attacks.dm b/code/modules/mob/living/carbon/alien/alien_attacks.dm
new file mode 100644
index 0000000000..45a486adf7
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/alien_attacks.dm
@@ -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 [S] [S.attacktext] [src]!", 1)
+ var/damage = rand(S.melee_damage_lower, S.melee_damage_upper)
+ adjustBruteLoss(damage)
+ S.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])")
+ src.attack_log += text("\[[time_stamp()]\] was attacked by [S.name] ([S.ckey])")
+ 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 [M.name] has bit [src]!"), 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 The [M.name] glomps []!", 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 [src] has been touched with the stun gloves by [M]!", 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 Remove that mask!"
+ 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 [] has punched []!", 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 [] has weakened []!", 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 [] has attempted to punch []!", M, src), 1)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/alien_damage.dm b/code/modules/mob/living/carbon/alien/alien_damage.dm
new file mode 100644
index 0000000000..1483559120
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/alien_damage.dm
@@ -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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm
index 0a060dd1f7..7dfd2cc0eb 100644
--- a/code/modules/mob/living/carbon/alien/death.dm
+++ b/code/modules/mob/living/carbon/alien/death.dm
@@ -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)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/diona/diona.dm b/code/modules/mob/living/carbon/alien/diona/diona.dm
new file mode 100644
index 0000000000..3f4bc2105d
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/diona/diona.dm
@@ -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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
new file mode 100644
index 0000000000..108333bf86
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm
@@ -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)
+
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/diona/diona_powers.dm b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm
new file mode 100644
index 0000000000..b8a47501a8
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/diona/diona_powers.dm
@@ -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()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/diona/life.dm b/code/modules/mob/living/carbon/alien/diona/life.dm
new file mode 100644
index 0000000000..26d236bcaa
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/diona/life.dm
@@ -0,0 +1,20 @@
+/* TODO
+ if(alien) //Diona nymphs are the only alien monkey currently.
+ var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
+ if(isturf(loc)) //else, there's considered to be no light
+ var/turf/T = loc
+ var/area/A = T.loc
+ if(A)
+ if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
+ else light_amount = 5
+
+ nutrition += light_amount
+ traumatic_shock -= light_amount
+
+ if(nutrition > 500)
+ nutrition = 500
+ if(light_amount > 2) //if there's enough light, heal
+ adjustBruteLoss(-1)
+ adjustToxLoss(-1)
+ adjustOxyLoss(-1)
+*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/diona/progression.dm b/code/modules/mob/living/carbon/alien/diona/progression.dm
new file mode 100644
index 0000000000..b99f593a10
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/diona/progression.dm
@@ -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."
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/diona/say_understands.dm b/code/modules/mob/living/carbon/alien/diona/say_understands.dm
new file mode 100644
index 0000000000..3f68a44cff
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/diona/say_understands.dm
@@ -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 ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/emote.dm b/code/modules/mob/living/carbon/alien/emote.dm
similarity index 86%
rename from code/modules/mob/living/carbon/alien/larva/emote.dm
rename to code/modules/mob/living/carbon/alien/emote.dm
index 375c5c6b0c..0efcae7c91 100644
--- a/code/modules/mob/living/carbon/alien/larva/emote.dm
+++ b/code/modules/mob/living/carbon/alien/emote.dm
@@ -1,127 +1,127 @@
-/mob/living/carbon/alien/larva/emote(var/act,var/m_type=1,var/message = null)
-
- var/param = null
- if (findtext(act, "-", 1, null))
- var/t1 = findtext(act, "-", 1, null)
- param = copytext(act, t1 + 1, length(act) + 1)
- act = copytext(act, 1, t1)
-
- if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
- act = copytext(act,1,length(act))
- var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
-
- switch(act)
- if ("me")
- if(silent)
- return
- if (src.client)
- if (client.prefs.muted & MUTE_IC)
- src << "\red You cannot send IC messages (muted)."
- return
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return
- if (stat)
- return
- if(!(message))
- return
- return custom_emote(m_type, message)
-
- if ("custom")
- return custom_emote(m_type, message)
- if("sign")
- if (!src.restrained())
- message = text("The alien signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
- m_type = 1
- if ("burp")
- if (!muzzled)
- message = "[src] burps."
- m_type = 2
- if("scratch")
- if (!src.restrained())
- message = "The [src.name] scratches."
- m_type = 1
- if("whimper")
- if (!muzzled)
- message = "The [src.name] whimpers."
- m_type = 2
-// if("roar")
-// if (!muzzled)
-// message = "The [src.name] roars." Commenting out since larva shouldn't roar /N
-// m_type = 2
- if("tail")
- message = "The [src.name] waves its tail."
- m_type = 1
- if("gasp")
- message = "The [src.name] gasps."
- m_type = 2
- if("shiver")
- message = "The [src.name] shivers."
- m_type = 2
- if("drool")
- message = "The [src.name] drools."
- m_type = 1
- if("scretch")
- if (!muzzled)
- message = "The [src.name] scretches."
- m_type = 2
- if("choke")
- message = "The [src.name] chokes."
- m_type = 2
- if("moan")
- message = "The [src.name] moans!"
- m_type = 2
- if("nod")
- message = "The [src.name] nods its head."
- m_type = 1
-// if("sit")
-// message = "The [src.name] sits down." //Larvan can't sit down, /N
-// m_type = 1
- if("sway")
- message = "The [src.name] sways around dizzily."
- m_type = 1
- if("sulk")
- message = "The [src.name] sulks down sadly."
- m_type = 1
- if("twitch")
- message = "The [src.name] twitches violently."
- m_type = 1
- if("dance")
- if (!src.restrained())
- message = "The [src.name] dances around happily."
- m_type = 1
- if("roll")
- if (!src.restrained())
- message = "The [src.name] rolls."
- m_type = 1
- if("shake")
- message = "The [src.name] shakes its head."
- m_type = 1
- if("gnarl")
- if (!muzzled)
- message = "The [src.name] gnarls and shows its teeth.."
- m_type = 2
- if("jump")
- message = "The [src.name] jumps!"
- m_type = 1
- if("hiss_")
- message = "The [src.name] hisses softly."
- m_type = 1
- if("collapse")
- Paralyse(2)
- message = text("[] collapses!", src)
- m_type = 2
- if("help")
- src << "burp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper"
- else
- src << text("Invalid Emote: []", act)
- if ((message && src.stat == 0))
- log_emote("[name]/[key] : [message]")
- if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
- else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
+/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("The alien signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
+ m_type = 1
+ if ("burp")
+ if (!muzzled)
+ message = "[src] burps."
+ m_type = 2
+ if("scratch")
+ if (!src.restrained())
+ message = "The [src.name] scratches."
+ m_type = 1
+ if("whimper")
+ if (!muzzled)
+ message = "The [src.name] whimpers."
+ m_type = 2
+ if("tail")
+ message = "The [src.name] waves its tail."
+ m_type = 1
+ if("gasp")
+ message = "The [src.name] gasps."
+ m_type = 2
+ if("shiver")
+ message = "The [src.name] shivers."
+ m_type = 2
+ if("drool")
+ message = "The [src.name] drools."
+ m_type = 1
+ if("scretch")
+ if (!muzzled)
+ message = "The [src.name] scretches."
+ m_type = 2
+ if("choke")
+ message = "The [src.name] chokes."
+ m_type = 2
+ if("moan")
+ message = "The [src.name] moans!"
+ m_type = 2
+ if("nod")
+ message = "The [src.name] nods its head."
+ m_type = 1
+// if("sit")
+// message = "The [src.name] sits down." //Larvan can't sit down, /N
+// m_type = 1
+ if("sway")
+ message = "The [src.name] sways around dizzily."
+ m_type = 1
+ if("sulk")
+ message = "The [src.name] sulks down sadly."
+ m_type = 1
+ if("twitch")
+ message = "The [src.name] twitches violently."
+ m_type = 1
+ if("dance")
+ if (!src.restrained())
+ message = "The [src.name] dances around happily."
+ m_type = 1
+ if("roll")
+ if (!src.restrained())
+ message = "The [src.name] rolls."
+ m_type = 1
+ if("shake")
+ message = "The [src.name] shakes its head."
+ m_type = 1
+ if("gnarl")
+ if (!muzzled)
+ message = "The [src.name] gnarls and shows its teeth.."
+ m_type = 2
+ if("jump")
+ message = "The [src.name] jumps!"
+ m_type = 1
+ if("hiss_")
+ message = "The [src.name] hisses softly."
+ m_type = 1
+ if("collapse")
+ Paralyse(2)
+ message = text("[] collapses!", src)
+ m_type = 2
+ if("chirp")
+ message = "The [src.name] 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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
deleted file mode 100644
index 92426808b6..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ /dev/null
@@ -1,188 +0,0 @@
-/*NOTES:
-These are general powers. Specific powers are stored under the appropriate alien creature type.
-*/
-
-/*Alien spit now works like a taser shot. It won't home in on the target but will act the same once it does hit.
-Doesn't work on other aliens/AI.*/
-
-
-/mob/living/carbon/alien/proc/powerc(X, Y)//Y is optional, checks for weed planting. X can be null.
- if(stat)
- src << "\green You must be conscious to do this."
- return 0
- else if(X && getPlasma() < X)
- src << "\green Not enough plasma stored."
- return 0
- else if(Y && (!isturf(src.loc) || istype(src.loc, /turf/space)))
- src << "\green Bad place for a garden!"
- return 0
- else return 1
-
-/mob/living/carbon/alien/humanoid/verb/plant()
- set name = "Plant Weeds (50)"
- set desc = "Plants some alien weeds"
- set category = "Alien"
-
- if(powerc(50,1))
- adjustToxLoss(-50)
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\green [src] has planted some alien weeds!"), 1)
- new /obj/effect/alien/weeds/node(loc)
- return
-
-/*
-/mob/living/carbon/alien/humanoid/verb/ActivateHuggers()
- set name = "Activate facehuggers (5)"
- set desc = "Makes all nearby facehuggers activate"
- set category = "Alien"
-
- if(powerc(5))
- adjustToxLoss(-5)
- for(var/obj/item/clothing/mask/facehugger/F in range(8,src))
- F.GoActive()
- emote("roar")
- return
-*/
-/mob/living/carbon/alien/humanoid/verb/whisp(mob/M as mob in oview())
- set name = "Whisper (10)"
- set desc = "Whisper to someone"
- set category = "Alien"
-
- if(powerc(10))
- adjustToxLoss(-10)
- var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
- if(msg)
- log_say("AlienWhisper: [key_name(src)]->[M.key] : [msg]")
- M << "\green You hear a strange, alien voice in your head... \italic [msg]"
- src << {"\green You said: "[msg]" to [M]"}
- return
-
-/mob/living/carbon/alien/humanoid/verb/transfer_plasma(mob/living/carbon/alien/M as mob in oview())
- set name = "Transfer Plasma"
- set desc = "Transfer Plasma to another alien"
- set category = "Alien"
-
- if(isalien(M))
- var/amount = input("Amount:", "Transfer Plasma to [M]") as num
- if (amount)
- amount = abs(round(amount))
- if(powerc(amount))
- if (get_dist(src,M) <= 1)
- M.adjustToxLoss(amount)
- adjustToxLoss(-amount)
- M << "\green [src] has transfered [amount] plasma to you."
- src << {"\green You have trasferred [amount] plasma to [M]"}
- else
- src << "\green You need to be closer."
- return
-
-
-/mob/living/carbon/alien/humanoid/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N
- set name = "Corrossive Acid (200)"
- set desc = "Drench an object in acid, destroying it over time."
- set category = "Alien"
-
- if(powerc(200))
- if(O in oview(1))
- // OBJ CHECK
- if(isobj(O))
- var/obj/I = O
- if(I.unacidable) //So the aliens don't destroy energy fields/singularies/other aliens/etc with their acid.
- src << "\green You cannot dissolve this object."
- return
- // TURF CHECK
- else if(istype(O, /turf/simulated))
- var/turf/T = O
- // R WALL
- if(istype(T, /turf/simulated/wall/r_wall))
- src << "\green You cannot dissolve this object."
- return
- // R FLOOR
- if(istype(T, /turf/simulated/floor/engine))
- src << "\green You cannot dissolve this object."
- return
- else// Not a type we can acid.
- return
-
- adjustToxLoss(-200)
- new /obj/effect/alien/acid(get_turf(O), O)
- visible_message("\green [src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!")
- else
- src << "\green Target is too far away."
- return
-
-
-/mob/living/carbon/alien/humanoid/proc/neurotoxin(mob/target as mob in oview())
- set name = "Spit Neurotoxin (50)"
- set desc = "Spits neurotoxin at someone, paralyzing them for a short time if they are not wearing protective gear."
- set category = "Alien"
-
- if(powerc(50))
- if(isalien(target))
- src << "\green Your allies are not a valid target."
- return
- adjustToxLoss(-50)
- src << "\green You spit neurotoxin at [target]."
- for(var/mob/O in oviewers())
- if ((O.client && !( O.blinded )))
- O << "\red [src] spits neurotoxin at [target]!"
- //I'm not motivated enough to revise this. Prjectile code in general needs update.
- var/turf/T = loc
- var/turf/U = (istype(target, /atom/movable) ? target.loc : target)
-
- if(!U || !T)
- return
- while(U && !istype(U,/turf))
- U = U.loc
- if(!istype(T, /turf))
- return
- if (U == T)
- usr.bullet_act(new /obj/item/projectile/energy/neurotoxin(usr.loc), get_organ_target())
- return
- if(!istype(U, /turf))
- return
-
- var/obj/item/projectile/energy/neurotoxin/A = new /obj/item/projectile/energy/neurotoxin(usr.loc)
- A.current = U
- A.yo = U.y - T.y
- A.xo = U.x - T.x
- A.process()
- return
-
-/mob/living/carbon/alien/humanoid/proc/resin() // -- TLE
- set name = "Secrete Resin (75)"
- set desc = "Secrete tough malleable resin."
- set category = "Alien"
-
- if(powerc(75))
- var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
- if(!choice || !powerc(75)) return
- adjustToxLoss(-75)
- src << "\green You shape a [choice]."
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\red [src] vomits up a thick purple substance and begins to shape it!"), 1)
- switch(choice)
- if("resin door")
- new /obj/structure/mineral_door/resin(loc)
- if("resin wall")
- new /obj/effect/alien/resin/wall(loc)
- if("resin membrane")
- new /obj/effect/alien/resin/membrane(loc)
- if("resin nest")
- new /obj/structure/stool/bed/nest(loc)
- return
-
-/mob/living/carbon/alien/humanoid/verb/regurgitate()
- set name = "Regurgitate"
- set desc = "Empties the contents of your stomach"
- set category = "Alien"
-
- if(powerc())
- if(stomach_contents.len)
- for(var/mob/M in src)
- if(M in stomach_contents)
- stomach_contents.Remove(M)
- M.loc = loc
- //Paralyse(10)
- src.visible_message("\green [src] hurls out the contents of their stomach!")
- return
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
deleted file mode 100644
index 6b7752f813..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
+++ /dev/null
@@ -1,48 +0,0 @@
-/mob/living/carbon/alien/humanoid/drone
- name = "alien drone"
- caste = "d"
- maxHealth = 100
- health = 100
- icon_state = "aliend_s"
- plasma_rate = 15
-
-/mob/living/carbon/alien/humanoid/drone/New()
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
- if(src.name == "alien drone")
- src.name = text("alien drone ([rand(1, 1000)])")
- src.real_name = src.name
- verbs.Add(/mob/living/carbon/alien/humanoid/proc/resin,/mob/living/carbon/alien/humanoid/proc/corrosive_acid)
- ..()
-//Drones use the same base as generic humanoids.
-//Drone verbs
-
-/mob/living/carbon/alien/humanoid/drone/verb/evolve() // -- TLE
- set name = "Evolve (500)"
- set desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
- set category = "Alien"
-
- if(powerc(500))
- // Queen check
- var/no_queen = 1
- for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
- if(!Q.key && Q.has_brain())
- continue
- no_queen = 0
-
- if(src.has_brain_worms())
- src << "We cannot perform this ability at the present time!"
- return
-
- if(no_queen)
- adjustToxLoss(-500)
- src << "\green You begin to evolve!"
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\green [src] begins to twist and contort!"), 1)
- var/mob/living/carbon/alien/humanoid/queen/new_xeno = new (loc)
- mind.transfer_to(new_xeno)
- del(src)
- else
- src << "We already have an alive queen."
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
deleted file mode 100644
index 3a15f620b2..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ /dev/null
@@ -1,76 +0,0 @@
-/mob/living/carbon/alien/humanoid/hunter
- name = "alien hunter"
- caste = "h"
- maxHealth = 150
- health = 150
- storedPlasma = 100
- max_plasma = 150
- icon_state = "alienh_s"
- plasma_rate = 5
-
-/mob/living/carbon/alien/humanoid/hunter/New()
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
- if(name == "alien hunter")
- name = text("alien hunter ([rand(1, 1000)])")
- real_name = name
- ..()
-
-/mob/living/carbon/alien/humanoid/hunter
-
-
- handle_regular_hud_updates()
-
- ..() //-Yvarov
-
- if (healths)
- if (stat != 2)
- switch(health)
- if(150 to INFINITY)
- healths.icon_state = "health0"
- if(100 to 150)
- healths.icon_state = "health1"
- if(50 to 100)
- healths.icon_state = "health2"
- if(25 to 50)
- healths.icon_state = "health3"
- if(0 to 25)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
-
-
- handle_environment()
- if(m_intent == "run" || resting)
- ..()
- else
- adjustToxLoss(-heal_rate)
-
-
-//Hunter verbs
-/*
-/mob/living/carbon/alien/humanoid/hunter/verb/invis()
- set name = "Invisibility (50)"
- set desc = "Makes you invisible for 15 seconds"
- set category = "Alien"
-
- if(alien_invis)
- update_icons()
- else
- if(powerc(50))
- adjustToxLoss(-50)
- alien_invis = 1.0
- update_icons()
- src << "\green You are now invisible."
- for(var/mob/O in oviewers(src, null))
- O.show_message(text("\red [src] fades into the surroundings!"), 1)
- spawn(250)
- if(!isnull(src))//Don't want the game to runtime error when the mob no-longer exists.
- alien_invis = 0.0
- update_icons()
- src << "\green You are no longer invisible."
- return
-*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
deleted file mode 100644
index 226824c6ab..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ /dev/null
@@ -1,44 +0,0 @@
-/mob/living/carbon/alien/humanoid/sentinel
- name = "alien sentinel"
- caste = "s"
- maxHealth = 125
- health = 125
- storedPlasma = 100
- max_plasma = 250
- icon_state = "aliens_s"
- plasma_rate = 10
-
-/mob/living/carbon/alien/humanoid/sentinel/New()
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
- if(name == "alien sentinel")
- name = text("alien sentinel ([rand(1, 1000)])")
- real_name = name
- verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin)
- ..()
-
-/mob/living/carbon/alien/humanoid/sentinel
-
-
- handle_regular_hud_updates()
-
- ..() //-Yvarov
-
- if (healths)
- if (stat != 2)
- switch(health)
- if(125 to INFINITY)
- healths.icon_state = "health0"
- if(100 to 125)
- healths.icon_state = "health1"
- if(75 to 100)
- healths.icon_state = "health2"
- if(25 to 75)
- healths.icon_state = "health3"
- if(0 to 25)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/death.dm b/code/modules/mob/living/carbon/alien/humanoid/death.dm
deleted file mode 100644
index 91138a4309..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/death.dm
+++ /dev/null
@@ -1,17 +0,0 @@
-/mob/living/carbon/alien/humanoid/death(gibbed)
- if(stat == DEAD) return
- if(healths) healths.icon_state = "health6"
- stat = DEAD
-
- if(!gibbed)
- playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
- for(var/mob/O in viewers(src, null))
- O.show_message("[src] lets out a waning guttural screech, green blood bubbling from its maw...", 1)
- update_canmove()
- if(client) blind.layer = 0
- update_icons()
-
- tod = worldtime2text() //weasellos time of death patch
- if(mind) mind.store_memory("Time of death: [tod]", 0)
-
- return ..(gibbed)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/emote.dm b/code/modules/mob/living/carbon/alien/humanoid/emote.dm
deleted file mode 100644
index 71dc56ef40..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/emote.dm
+++ /dev/null
@@ -1,135 +0,0 @@
-/mob/living/carbon/alien/humanoid/emote(var/act,var/m_type=1,var/message = null)
-
- var/param = null
- if (findtext(act, "-", 1, null))
- var/t1 = findtext(act, "-", 1, null)
- param = copytext(act, t1 + 1, length(act) + 1)
- act = copytext(act, 1, t1)
-
- if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
- act = copytext(act,1,length(act))
- var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle)
-
- switch(act)
- if ("me")
- if(silent)
- return
- if (src.client)
- if (client.prefs.muted & MUTE_IC)
- src << "\red You cannot send IC messages (muted)."
- return
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return
- if (stat)
- return
- if(!(message))
- return
- return custom_emote(m_type, message)
-
- if ("custom")
- return custom_emote(m_type, message)
- if("sign")
- if (!src.restrained())
- message = text("The alien signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
- m_type = 1
- if ("burp")
- if (!muzzled)
- message = "[src] burps."
- m_type = 2
- if ("deathgasp")
- message = "[src] lets out a waning guttural screech, green blood bubbling from its maw..."
- m_type = 2
- if("scratch")
- if (!src.restrained())
- message = "The [src.name] scratches."
- m_type = 1
- if("whimper")
- if (!muzzled)
- message = "The [src.name] whimpers."
- m_type = 2
- if("roar")
- if (!muzzled)
- message = "The [src.name] roars."
- m_type = 2
- if("hiss")
- if(!muzzled)
- message = "The [src.name] hisses."
- m_type = 2
- if("tail")
- message = "The [src.name] waves its tail."
- m_type = 1
- if("gasp")
- message = "The [src.name] gasps."
- m_type = 2
- if("shiver")
- message = "The [src.name] shivers."
- m_type = 2
- if("drool")
- message = "The [src.name] drools."
- m_type = 1
- if("scretch")
- if (!muzzled)
- message = "The [src.name] scretches."
- m_type = 2
- if("choke")
- message = "The [src.name] chokes."
- m_type = 2
- if("moan")
- message = "The [src.name] moans!"
- m_type = 2
- if("nod")
- message = "The [src.name] nods its head."
- m_type = 1
- if("sit")
- message = "The [src.name] sits down."
- m_type = 1
- if("sway")
- message = "The [src.name] sways around dizzily."
- m_type = 1
- if("sulk")
- message = "The [src.name] sulks down sadly."
- m_type = 1
- if("twitch")
- message = "The [src.name] twitches violently."
- m_type = 1
- if("dance")
- if (!src.restrained())
- message = "The [src.name] dances around happily."
- m_type = 1
- if("roll")
- if (!src.restrained())
- message = "The [src.name] rolls."
- m_type = 1
- if("shake")
- message = "The [src.name] shakes its head."
- m_type = 1
- if("gnarl")
- if (!muzzled)
- message = "The [src.name] gnarls and shows its teeth.."
- m_type = 2
- if("jump")
- message = "The [src.name] jumps!"
- m_type = 1
- if("collapse")
- Paralyse(2)
- message = text("[] collapses!", src)
- m_type = 2
- if("help")
- src << "burp, deathgasp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
- else
- src << text("Invalid Emote: []", act)
- if ((message && src.stat == 0))
- log_emote("[name]/[key] : [message]")
- if (act == "roar")
- playsound(src.loc, 'sound/voice/hiss5.ogg', 40, 1, 1)
- if (act == "deathgasp")
- playsound(src.loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
- if (m_type & 1)
- for(var/mob/O in viewers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(703)
- else
- for(var/mob/O in hearers(src, null))
- O.show_message(message, m_type)
- //Foreach goto(746)
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
deleted file mode 100644
index 03e590f036..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ /dev/null
@@ -1,423 +0,0 @@
-/mob/living/carbon/alien/humanoid
- name = "alien"
- icon_state = "alien_s"
-
- var/obj/item/clothing/suit/wear_suit = null //TODO: necessary? Are they even used? ~Carn
- var/obj/item/clothing/head/head = null //
- var/obj/item/weapon/r_store = null
- var/obj/item/weapon/l_store = null
- var/caste = ""
- update_icon = 1
-
-//This is fine right now, if we're adding organ specific damage this needs to be updated
-/mob/living/carbon/alien/humanoid/New()
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
- if(name == "alien")
- name = text("alien ([rand(1, 1000)])")
- real_name = name
- ..()
-
-//This is fine, works the same as a human
-/mob/living/carbon/alien/humanoid/Bump(atom/movable/AM as mob|obj, yes)
- spawn( 0 )
- if ((!( yes ) || now_pushing))
- return
- now_pushing = 0
- ..()
- if (!istype(AM, /atom/movable))
- return
-
- if (ismob(AM))
- var/mob/tmob = AM
- tmob.LAssailant = src
-
- if (!now_pushing)
- now_pushing = 1
- if (!AM.anchored)
- var/t = get_dir(src, AM)
- if (istype(AM, /obj/structure/window))
- if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
- for(var/obj/structure/window/win in get_step(AM,t))
- now_pushing = 0
- return
- step(AM, t)
- now_pushing = null
- return
- return
-
-/mob/living/carbon/alien/humanoid/movement_delay()
- var/tally = 0
- if (istype(src, /mob/living/carbon/alien/humanoid/queen))
- tally += 5
- if (istype(src, /mob/living/carbon/alien/humanoid/drone))
- tally += 2
- if (istype(src, /mob/living/carbon/alien/humanoid/sentinel))
- tally += 1
- if (istype(src, /mob/living/carbon/alien/humanoid/hunter))
- tally = -1 // hunters go supersuperfast
- return (tally + move_delay_add + config.alien_delay)
-
-///mob/living/carbon/alien/humanoid/bullet_act(var/obj/item/projectile/Proj) taken care of in living
-
-/mob/living/carbon/alien/humanoid/emp_act(severity)
- if(wear_suit) wear_suit.emp_act(severity)
- if(head) head.emp_act(severity)
- if(r_store) r_store.emp_act(severity)
- if(l_store) l_store.emp_act(severity)
- ..()
-
-/mob/living/carbon/alien/humanoid/ex_act(severity)
- if(!blinded)
- flick("flash", flash)
-
- var/shielded = 0
-
- var/b_loss = null
- var/f_loss = null
- switch (severity)
- if (1.0)
- b_loss += 500
- gib()
- return
-
- if (2.0)
- if (!shielded)
- b_loss += 60
-
- f_loss += 60
-
- ear_damage += 30
- ear_deaf += 120
-
- if(3.0)
- b_loss += 30
- if (prob(50) && !shielded)
- Paralyse(1)
- ear_damage += 15
- ear_deaf += 60
-
- adjustBruteLoss(b_loss)
- adjustFireLoss(f_loss)
-
- updatehealth()
-
-/mob/living/carbon/alien/humanoid/blob_act()
- if (stat == 2)
- return
- var/shielded = 0
- var/damage = null
- if (stat != 2)
- damage = rand(30,40)
-
- if(shielded)
- damage /= 4
-
-
- show_message("\red The blob attacks!")
-
- adjustFireLoss(damage)
-
- return
-
-
-/mob/living/carbon/alien/humanoid/meteorhit(O as obj)
- for(var/mob/M in viewers(src, null))
- if ((M.client && !( M.blinded )))
- M.show_message(text("\red [] has been hit by []", src, O), 1)
- if (health > 0)
- adjustFireLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25))
- adjustFireLoss(30)
-
- updatehealth()
- return
-
-/mob/living/carbon/alien/humanoid/attack_paw(mob/living/carbon/monkey/M as mob)
- if(!ismonkey(M)) return//Fix for aliens receiving double messages when attacking other aliens.
-
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if (istype(loc, /turf) && istype(loc.loc, /area/start))
- M << "No attacking people at spawn, you jackass."
- return
- ..()
-
- switch(M.a_intent)
-
- if ("help")
- help_shake_act(M)
- else
- if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
- return
- if (health > 0)
- playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [M.name] has bit [src]!"), 1)
- adjustBruteLoss(rand(1, 3))
- updatehealth()
- return
-
-
-/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if(M.Victim) return // can't attack while eating!
-
- if (health > -100)
-
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red The [M.name] glomps []!", src), 1)
-
- var/damage = rand(1, 3)
-
- if(M.is_adult)
- damage = rand(10, 40)
- else
- damage = rand(5, 35)
-
- adjustBruteLoss(damage)
-
- if(M.powerlevel > 0)
- var/stunprob = 10
- var/power = M.powerlevel + rand(0,3)
-
- switch(M.powerlevel)
- if(1 to 2) stunprob = 20
- if(3 to 4) stunprob = 30
- if(5 to 6) stunprob = 40
- if(7 to 8) stunprob = 60
- if(9) stunprob = 70
- if(10) stunprob = 95
-
- if(prob(stunprob))
- M.powerlevel -= 3
- if(M.powerlevel < 0)
- M.powerlevel = 0
-
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red The [M.name] has shocked []!", src), 1)
-
- Weaken(power)
- if (stuttering < power)
- stuttering = power
- Stun(power)
-
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
-
- if (prob(stunprob) && M.powerlevel >= 8)
- adjustFireLoss(M.powerlevel * rand(6,10))
-
-
- updatehealth()
-
- return
-
-/mob/living/carbon/alien/humanoid/attack_animal(mob/living/simple_animal/M as mob)
- if(M.melee_damage_upper == 0)
- M.emote("[M.friendly] [src]")
- else
- if(M.attack_sound)
- playsound(loc, M.attack_sound, 50, 1, 1)
- for(var/mob/O in viewers(src, null))
- O.show_message("\red [M] [M.attacktext] [src]!", 1)
- var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
- adjustBruteLoss(damage)
- updatehealth()
-
-/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if (istype(loc, /turf) && istype(loc.loc, /area/start))
- M << "No attacking people at spawn, you jackass."
- return
-
- ..()
-
- if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
- var/obj/item/clothing/gloves/G = M.gloves
- if(G.cell)
- if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
- if(G.cell.charge >= 2500)
- G.cell.use(2500)
-
- Weaken(5)
- if (stuttering < 5)
- stuttering = 5
- Stun(5)
-
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message("\red [src] has been touched with the stun gloves by [M]!", 1, "\red You hear someone fall.", 2)
- return
- else
- M << "\red Not enough charge! "
- return
-
- switch(M.a_intent)
-
- if ("help")
- if (health > 0)
- help_shake_act(M)
- else
- if (M.health >= -75.0)
- if (((M.head && M.head.flags & 4) || ((M.wear_mask && !( M.wear_mask.flags & 32 )) || ((head && head.flags & 4) || (wear_mask && !( wear_mask.flags & 32 ))))))
- M << "\blue Remove that mask!"
- return
- var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
- O.source = M
- O.target = src
- O.s_loc = M.loc
- O.t_loc = loc
- O.place = "CPR"
- requests += O
- spawn( 0 )
- O.process()
- return
-
- if ("grab")
- if (M == src || anchored)
- return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
-
- M.put_in_active_hand(G)
-
- grabbed_by += G
- G.synch()
-
- LAssailant = M
-
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
-
- if ("hurt")
- var/damage = rand(1, 9)
- if (prob(90))
- if (HULK in M.mutations)//HULK SMASH
- damage += 14
- spawn(0)
- Weaken(damage) // Why can a hulk knock an alien out but not knock out a human? Damage is robust enough.
- step_away(src,M,15)
- sleep(3)
- step_away(src,M,15)
- playsound(loc, "punch", 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has punched []!", M, src), 1)
- if (damage > 9||prob(5))//Regular humans have a very small chance of weakening an alien.
- Weaken(1,5)
- for(var/mob/O in viewers(M, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has weakened []!", 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 [] has attempted to punch []!", M, src), 1)
-
- if ("disarm")
- if (!lying)
- if (prob(5))//Very small chance to push an alien down.
- Weaken(2)
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has pushed down []!", M, src), 1)
- else
- if (prob(50))
- drop_item()
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has disarmed []!", M, src), 1)
- else
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attempted to disarm []!", M, src), 1)
- return
-
-/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
-As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
-In all, this is a lot like the monkey code. /N
-*/
-
-/mob/living/carbon/alien/humanoid/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if (istype(loc, /turf) && istype(loc.loc, /area/start))
- M << "No attacking people at spawn, you jackass."
- return
-
- ..()
-
- switch(M.a_intent)
-
- if ("help")
- sleeping = max(0,sleeping-5)
- resting = 0
- AdjustParalysis(-3)
- AdjustStunned(-3)
- AdjustWeakened(-3)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M.name] nuzzles [] trying to wake it up!", src), 1)
-
- else
- if (health > 0)
- playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- var/damage = rand(1, 3)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [M.name] has bit []!", src), 1)
- adjustBruteLoss(damage)
- updatehealth()
- else
- M << "\green [name] is too injured for that."
- return
-
-
-/mob/living/carbon/alien/humanoid/restrained()
- if (handcuffed)
- return 1
- return 0
-
-
-/mob/living/carbon/alien/humanoid/var/co2overloadtime = null
-/mob/living/carbon/alien/humanoid/var/temperature_resistance = T0C+75
-
-/mob/living/carbon/alien/humanoid/show_inv(mob/user as mob)
-
- user.set_machine(src)
- var/dat = {"
-
[name]
-
-
Left Hand: [(l_hand ? text("[]", l_hand) : "Nothing")]
-
Right Hand: [(r_hand ? text("[]", r_hand) : "Nothing")]
-
Head: [(head ? text("[]", head) : "Nothing")]
-
(Exo)Suit: [(wear_suit ? text("[]", wear_suit) : "Nothing")]
-
Empty Pouches
-
Close
-
"}
- user << browse(dat, text("window=mob[name];size=340x480"))
- onclose(user, "mob[name]")
- return
-
-
diff --git a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm b/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
deleted file mode 100644
index 0e03bf6892..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/inventory.dm
+++ /dev/null
@@ -1,54 +0,0 @@
-//unequip
-/mob/living/carbon/alien/humanoid/u_equip(obj/item/W as obj)
- if (W == wear_suit)
- wear_suit = null
- update_inv_wear_suit(0)
- else if (W == head)
- head = null
- update_inv_head(0)
- else if (W == r_store)
- r_store = null
- update_inv_pockets(0)
- else if (W == l_store)
- l_store = null
- update_inv_pockets(0)
- else if (W == r_hand)
- r_hand = null
- update_inv_r_hand(0)
- else if (W == l_hand)
- l_hand = null
- update_inv_l_hand(0)
-
-/mob/living/carbon/alien/humanoid/attack_ui(slot_id)
- var/obj/item/W = get_active_hand()
- if(W)
- if(!istype(W)) return
- switch(slot_id)
-// if("o_clothing")
-// if("head")
- if(slot_l_store)
- if(l_store)
- return
- if(W.w_class > 3)
- return
- u_equip(W)
- l_store = W
- update_inv_pockets()
- if(slot_r_store)
- if(r_store)
- return
- if(W.w_class > 3)
- return
- u_equip(W)
- r_store = W
- update_inv_pockets()
- else
- switch(slot_id)
- if(slot_wear_suit)
- if(wear_suit) wear_suit.attack_alien(src)
- if(slot_head)
- if(head) head.attack_alien(src)
- if(slot_l_store)
- if(l_store) l_store.attack_alien(src)
- if(slot_r_store)
- if(r_store) r_store.attack_alien(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm
deleted file mode 100644
index f1910fcfe3..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/life.dm
+++ /dev/null
@@ -1,453 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/mob/living/carbon/alien/humanoid
- oxygen_alert = 0
- phoron_alert = 0
- fire_alert = 0
-
- var/temperature_alert = 0
-
-
-/mob/living/carbon/alien/humanoid/Life()
- set invisibility = 0
- set background = 1
-
- if (monkeyizing)
- return
-
- ..()
-
- var/datum/gas_mixture/environment = loc.return_air()
-
- if (stat != DEAD) //still breathing
-
- //First, resolve location and get a breath
-
- if(air_master.current_cycle%4==2)
- //Only try to take a breath every 4 seconds, unless suffocating
- spawn(0) breathe()
-
- else //Still give containing object the chance to interact
- if(istype(loc, /obj/))
- var/obj/location_as_object = loc
- location_as_object.handle_internal_lifeform(src, 0)
-
- //Mutations and radiation
- handle_mutations_and_radiation()
-
- //Chemicals in the body
- handle_chemicals_in_body()
-
- //Disabilities
- handle_disabilities()
-
- //Apparently, the person who wrote this code designed it so that
- //blinded get reset each cycle and then get activated later in the
- //code. Very ugly. I dont care. Moving this stuff here so its easy
- //to find it.
- blinded = null
-
- //Handle temperature/pressure differences between body and environment
- handle_environment(environment)
-
- //stuff in the stomach
- handle_stomach()
-
-
- //Status updates, death etc.
- handle_regular_status_updates()
- update_canmove()
-
- // Grabbing
- for(var/obj/item/weapon/grab/G in src)
- G.process()
-
- if(client)
- handle_regular_hud_updates()
-
-
-/mob/living/carbon/alien/humanoid
- proc/handle_disabilities()
- if (disabilities & EPILEPSY)
- if ((prob(1) && paralysis < 10))
- src << "\red You have a seizure!"
- Paralyse(10)
- if (disabilities & COUGHING)
- if ((prob(5) && paralysis <= 1))
- drop_item()
- spawn( 0 )
- emote("cough")
- return
- if (disabilities & TOURETTES)
- if ((prob(10) && paralysis <= 1))
- Stun(10)
- spawn( 0 )
- emote("twitch")
- return
- if (disabilities & NERVOUS)
- if (prob(10))
- stuttering = max(10, stuttering)
-
-
- proc/breathe()
- if(reagents)
- if(reagents.has_reagent("lexorin")) return
- if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
-
- var/datum/gas_mixture/environment = loc.return_air()
- var/datum/gas_mixture/breath
- // HACK NEED CHANGING LATER
- if(health < 0)
- losebreath++
-
- if(losebreath>0) //Suffocating so do not take a breath
- losebreath--
- if (prob(75)) //High chance of gasping for air
- spawn emote("gasp")
- if(istype(loc, /obj/))
- var/obj/location_as_object = loc
- location_as_object.handle_internal_lifeform(src, 0)
- else
- //First, check for air from internal atmosphere (using an air tank and mask generally)
- breath = get_breath_from_internal(BREATH_VOLUME)
-
- //No breath from internal atmosphere so get breath from location
- if(!breath)
- if(istype(loc, /obj/))
- var/obj/location_as_object = loc
- breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
- else if(istype(loc, /turf/))
- var/breath_moles = 0
- /*if(environment.return_pressure() > ONE_ATMOSPHERE)
- // Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
- breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
- else*/
- // Not enough air around, take a percentage of what's there to model this properly
- breath_moles = environment.total_moles*BREATH_PERCENTAGE
-
- breath = loc.remove_air(breath_moles)
-
- // Handle chem smoke effect -- Doohl
- for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
- if(smoke.reagents.total_volume)
- smoke.reagents.reaction(src, INGEST)
- spawn(5)
- if(smoke)
- smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
- break // If they breathe in the nasty stuff once, no need to continue checking
-
-
- else //Still give containing object the chance to interact
- if(istype(loc, /obj/))
- var/obj/location_as_object = loc
- location_as_object.handle_internal_lifeform(src, 0)
-
- handle_breath(breath)
-
- if(breath)
- loc.assume_air(breath)
-
-
- proc/get_breath_from_internal(volume_needed)
- if(internal)
- if (!contents.Find(internal))
- internal = null
- if (!wear_mask || !(wear_mask.flags & MASKINTERNALS) )
- internal = null
- if(internal)
- if (internals)
- internals.icon_state = "internal1"
- return internal.remove_air_volume(volume_needed)
- else
- if (internals)
- internals.icon_state = "internal0"
- return null
-
- proc/handle_breath(datum/gas_mixture/breath)
- if(status_flags & GODMODE)
- return
-
- if(!breath || (breath.total_moles == 0))
- //Aliens breathe in vaccuum
- return 0
-
- var/phoron_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["phoron"] / breath.total_moles) * breath_pressure
-
- if(Toxins_pp) // Detect phoron in air
-
- adjustToxLoss(breath.gas["phoron"] * 250)
- phoron_alert = max(phoron_alert, 1)
-
- phoron_used = breath.gas["phoron"]
-
- else
- phoron_alert = 0
-
- //Breathe in phoron and out oxygen
- breath.adjust_gas("phoron", -phoron_used)
- breath.adjust_gas("oxygen", phoron_used)
-
- if(breath.temperature > (T0C+66) && !(COLD_RESISTANCE in mutations)) // Hot air hurts :(
- if(prob(20))
- src << "\red You feel a searing heat in your lungs!"
- fire_alert = max(fire_alert, 1)
- else
- fire_alert = 0
-
- //Temporary fixes to the alerts.
-
- return 1
-
-
-
- proc/adjust_body_temperature(current, loc_temp, boost)
- var/temperature = current
- var/difference = abs(current-loc_temp) //get difference
- var/increments// = difference/10 //find how many increments apart they are
- if(difference > 50)
- increments = difference/5
- else
- increments = difference/10
- var/change = increments*boost // Get the amount to change by (x per increment)
- var/temp_change
- if(current < loc_temp)
- temperature = min(loc_temp, temperature+change)
- else if(current > loc_temp)
- temperature = max(loc_temp, temperature-change)
- temp_change = (temperature - current)
- return temp_change
-
- /*
- proc/get_thermal_protection()
- var/thermal_protection = 1.0
- //Handle normal clothing
- if(head && (head.body_parts_covered & HEAD))
- thermal_protection += 0.5
- if(wear_suit && (wear_suit.body_parts_covered & UPPER_TORSO))
- thermal_protection += 0.5
- if(wear_suit && (wear_suit.body_parts_covered & LEGS))
- thermal_protection += 0.2
- if(wear_suit && (wear_suit.body_parts_covered & ARMS))
- thermal_protection += 0.2
- if(wear_suit && (wear_suit.body_parts_covered & HANDS))
- thermal_protection += 0.2
- if(wear_suit && (wear_suit.flags & SUITSPACE))
- thermal_protection += 3
- if(COLD_RESISTANCE in mutations)
- thermal_protection += 5
-
- return thermal_protection
-
- proc/add_fire_protection(var/temp)
- var/fire_prot = 0
- if(head)
- if(head.protective_temperature > temp)
- fire_prot += (head.protective_temperature/10)
- if(wear_mask)
- if(wear_mask.protective_temperature > temp)
- fire_prot += (wear_mask.protective_temperature/10)
- if(wear_suit)
- if(wear_suit.protective_temperature > temp)
- fire_prot += (wear_suit.protective_temperature/10)
-
-
- return fire_prot
- */
-
- proc/handle_chemicals_in_body()
-
- if(reagents) reagents.metabolize(src)
-
- if(FAT in mutations)
- if(nutrition < 100)
- if(prob(round((50 - nutrition) / 100)))
- src << "\blue You feel fit again!"
- mutations.Remove(FAT)
-/* else
- if(nutrition > 500)
- if(prob(5 + round((nutrition - 200) / 2)))
- src << "\red You suddenly feel blubbery!"
- mutations.Add(FAT)
- FUCK YOU FATCODE -Hawk */
- if (nutrition > 0)
- nutrition -= HUNGER_FACTOR
-
- if (drowsyness)
- drowsyness--
- eye_blurry = max(2, eye_blurry)
- if (prob(5))
- sleeping += 1
- Paralyse(5)
-
- confused = max(0, confused - 1)
- // decrement dizziness counter, clamped to 0
- if(resting)
- dizziness = max(0, dizziness - 5)
- jitteriness = max(0, jitteriness - 5)
- else
- dizziness = max(0, dizziness - 1)
- jitteriness = max(0, jitteriness - 1)
-
- updatehealth()
-
- return //TODO: DEFERRED
-
-
- proc/handle_regular_status_updates()
- updatehealth()
-
- if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
- blinded = 1
- silent = 0
- else //ALIVE. LIGHTS ARE ON
- if(health < config.health_threshold_dead || !has_brain())
- death()
- blinded = 1
- stat = DEAD
- silent = 0
- return 1
-
- //UNCONSCIOUS. NO-ONE IS HOME
- if( (getOxyLoss() > 50) || (config.health_threshold_crit > health) )
- if( health <= 20 && prob(1) )
- spawn(0)
- emote("gasp")
- if(!reagents.has_reagent("inaprovaline"))
- adjustOxyLoss(1)
- Paralyse(3)
-
- if(paralysis)
- AdjustParalysis(-1)
- blinded = 1
- stat = UNCONSCIOUS
- else if(sleeping)
- sleeping = max(sleeping-1, 0)
- blinded = 1
- stat = UNCONSCIOUS
- if( prob(10) && health )
- spawn(0)
- emote("hiss")
- //CONSCIOUS
- else
- stat = CONSCIOUS
-
- /* What in the living hell is this?*/
- if(move_delay_add > 0)
- move_delay_add = max(0, move_delay_add - rand(1, 2))
-
- //Eyes
- if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own
- blinded = 1
- else if(eye_blind) //blindness, heals slowly over time
- eye_blind = max(eye_blind-1,0)
- blinded = 1
- else if(eye_blurry) //blurry eyes heal slowly
- eye_blurry = max(eye_blurry-1, 0)
-
- //Ears
- if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
- ear_deaf = max(ear_deaf, 1)
- else if(ear_deaf) //deafness, heals slowly over time
- ear_deaf = max(ear_deaf-1, 0)
- else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
- ear_damage = max(ear_damage-0.05, 0)
-
- //Other
- 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(100 to INFINITY)
- healths.icon_state = "health0"
- if(75 to 100)
- healths.icon_state = "health1"
- if(50 to 75)
- healths.icon_state = "health2"
- if(25 to 50)
- healths.icon_state = "health3"
- if(0 to 25)
- healths.icon_state = "health4"
- else
- healths.icon_state = "health5"
- else
- healths.icon_state = "health6"
-
- if(pullin) pullin.icon_state = "pull[pulling ? 1 : 0]"
-
-
- if (toxin) toxin.icon_state = "tox[phoron_alert ? 1 : 0]"
- if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]"
- if (fire) fire.icon_state = "fire[fire_alert ? 1 : 0]"
- //NOTE: the alerts dont reset when youre out of danger. dont blame me,
- //blame the person who coded them. Temporary fix added.
- if (client)
- client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
-
- if ((blind && stat != 2))
- if ((blinded))
- blind.layer = 18
- else
- blind.layer = 0
-
- if (disabilities & NEARSIGHTED)
- client.screen += global_hud.vimpaired
-
- if (eye_blurry)
- client.screen += global_hud.blurry
-
- if (druggy)
- client.screen += global_hud.druggy
-
- if (stat != 2)
- if (machine)
- if (!( machine.check_eye(src) ))
- reset_view(null)
- else
- if(client && !client.adminobs)
- reset_view(null)
-
- return 1
-
- proc/handle_stomach()
- spawn(0)
- for(var/mob/living/M in stomach_contents)
- if(M.loc != src)
- stomach_contents.Remove(M)
- continue
- if(istype(M, /mob/living/carbon) && stat != 2)
- if(M.stat == 2)
- M.death(1)
- stomach_contents.Remove(M)
- del(M)
- continue
- if(air_master.current_cycle%3==1)
- if(!(status_flags & GODMODE))
- M.adjustBruteLoss(5)
- nutrition += 10
-
-/mob/living/carbon/alien/humanoid/handle_stunned()
- if(stunned && !..())
- update_icons()
- return stunned
diff --git a/code/modules/mob/living/carbon/alien/humanoid/login.dm b/code/modules/mob/living/carbon/alien/humanoid/login.dm
deleted file mode 100644
index 607a03fef0..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/login.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-/mob/living/carbon/alien/humanoid/Login()
- ..()
- update_hud()
- if(!isturf(loc))
- client.eye = loc
- client.perspective = EYE_PERSPECTIVE
- return
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
deleted file mode 100644
index 1b98392b81..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ /dev/null
@@ -1,92 +0,0 @@
-/mob/living/carbon/alien/humanoid/queen
- name = "alien queen"
- caste = "q"
- maxHealth = 250
- health = 250
- icon_state = "alienq_s"
- status_flags = CANPARALYSE
- heal_rate = 5
- plasma_rate = 20
-
-
-/mob/living/carbon/alien/humanoid/queen/New()
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
-
- //there should only be one queen
- for(var/mob/living/carbon/alien/humanoid/queen/Q in living_mob_list)
- if(Q == src) continue
- if(Q.stat == DEAD) continue
- if(Q.client)
- name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
- break
-
- real_name = src.name
- verbs.Add(/mob/living/carbon/alien/humanoid/proc/corrosive_acid,/mob/living/carbon/alien/humanoid/proc/neurotoxin,/mob/living/carbon/alien/humanoid/proc/resin)
- verbs -= /mob/living/carbon/alien/verb/ventcrawl
- ..()
-
-
-/mob/living/carbon/alien/humanoid/queen
-
- handle_regular_hud_updates()
-
- ..() //-Yvarov
-
- if (src.healths)
- if (src.stat != 2)
- switch(health)
- if(250 to INFINITY)
- src.healths.icon_state = "health0"
- if(175 to 250)
- src.healths.icon_state = "health1"
- if(100 to 175)
- src.healths.icon_state = "health2"
- if(50 to 100)
- src.healths.icon_state = "health3"
- if(0 to 50)
- src.healths.icon_state = "health4"
- else
- src.healths.icon_state = "health5"
- else
- src.healths.icon_state = "health6"
-
-
-//Queen verbs
-/mob/living/carbon/alien/humanoid/queen/verb/lay_egg()
-
- set name = "Lay Egg (75)"
- set desc = "Lay an egg to produce huggers to impregnate prey with."
- set category = "Alien"
-
- if(locate(/obj/effect/alien/egg) in get_turf(src))
- src << "There's already an egg here."
- return
-
- if(powerc(75,1))//Can't plant eggs on spess tiles. That's silly.
- adjustToxLoss(-75)
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\green [src] has laid an egg!"), 1)
- new /obj/effect/alien/egg(loc)
- return
-
-
-/mob/living/carbon/alien/humanoid/queen/large
- icon = 'icons/mob/alienqueen.dmi'
- icon_state = "queen_s"
- pixel_x = -16
-
-/mob/living/carbon/alien/humanoid/queen/large/update_icons()
- lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
- update_hud() //TODO: remove the need for this to be here
- overlays.Cut()
- if(lying)
- if(resting) icon_state = "queen_sleep"
- else icon_state = "queen_l"
- for(var/image/I in overlays_lying)
- overlays += I
- else
- icon_state = "queen_s"
- for(var/image/I in overlays_standing)
- overlays += I
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
deleted file mode 100644
index 57d0300b39..0000000000
--- a/code/modules/mob/living/carbon/alien/humanoid/update_icons.dm
+++ /dev/null
@@ -1,154 +0,0 @@
-//Xeno Overlays Indexes//////////
-#define X_HEAD_LAYER 1
-#define X_SUIT_LAYER 2
-#define X_L_HAND_LAYER 3
-#define X_R_HAND_LAYER 4
-#define TARGETED_LAYER 5
-#define X_TOTAL_LAYERS 5
-/////////////////////////////////
-
-/mob/living/carbon/alien/humanoid
- var/list/overlays_lying[X_TOTAL_LAYERS]
- var/list/overlays_standing[X_TOTAL_LAYERS]
-
-/mob/living/carbon/alien/humanoid/update_icons()
- lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
- update_hud() //TODO: remove the need for this to be here
- overlays.Cut()
- if(stat == DEAD)
- //If we mostly took damage from fire
- if(fireloss > 125)
- icon_state = "alien[caste]_husked"
- else
- icon_state = "alien[caste]_dead"
- for(var/image/I in overlays_lying)
- overlays += I
- else if(lying)
- if(resting)
- icon_state = "alien[caste]_sleep"
- else if(stat == UNCONSCIOUS)
- icon_state = "alien[caste]_unconscious"
- else
- icon_state = "alien[caste]_l"
- for(var/image/I in overlays_lying)
- overlays += I
- else
- if(m_intent == "run") icon_state = "alien[caste]_running"
- else icon_state = "alien[caste]_s"
- for(var/image/I in overlays_standing)
- overlays += I
-
-/mob/living/carbon/alien/humanoid/regenerate_icons()
- ..()
- if (monkeyizing) return
-
- update_inv_head(0)
- update_inv_wear_suit(0)
- update_inv_r_hand(0)
- update_inv_l_hand(0)
- update_inv_pockets(0)
- update_hud()
- update_icons()
-
-
-/mob/living/carbon/alien/humanoid/update_hud()
- //TODO
- if (client)
-// if(other) client.screen |= hud_used.other //Not used
-// else client.screen -= hud_used.other //Not used
- client.screen |= contents
-
-
-
-/mob/living/carbon/alien/humanoid/update_inv_wear_suit(var/update_icons=1)
- if(wear_suit)
- var/t_state = wear_suit.item_state
- if(!t_state) t_state = wear_suit.icon_state
- var/image/lying = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]2")
- var/image/standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]")
-
- if(wear_suit.blood_DNA)
- var/t_suit = "suit"
- if( istype(wear_suit, /obj/item/clothing/suit/armor) )
- t_suit = "armor"
- lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood2")
- standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[t_suit]blood")
-
- //TODO
- wear_suit.screen_loc = ui_alien_oclothing
- if (istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
- drop_from_inventory(handcuffed)
- drop_r_hand()
- drop_l_hand()
-
- overlays_lying[X_SUIT_LAYER] = lying
- overlays_standing[X_SUIT_LAYER] = standing
- else
- overlays_lying[X_SUIT_LAYER] = null
- overlays_standing[X_SUIT_LAYER] = null
- if(update_icons) update_icons()
-
-
-/mob/living/carbon/alien/humanoid/update_inv_head(var/update_icons=1)
- if (head)
- var/t_state = head.item_state
- if(!t_state) t_state = head.icon_state
- var/image/lying = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]2")
- var/image/standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "[t_state]")
- if(head.blood_DNA)
- lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood2")
- standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
- head.screen_loc = ui_alien_head
- overlays_lying[X_HEAD_LAYER] = lying
- overlays_standing[X_HEAD_LAYER] = standing
- else
- overlays_lying[X_HEAD_LAYER] = null
- overlays_standing[X_HEAD_LAYER] = null
- if(update_icons) update_icons()
-
-
-/mob/living/carbon/alien/humanoid/update_inv_pockets(var/update_icons=1)
- if(l_store) l_store.screen_loc = ui_storage1
- if(r_store) r_store.screen_loc = ui_storage2
- if(update_icons) update_icons()
-
-
-/mob/living/carbon/alien/humanoid/update_inv_r_hand(var/update_icons=1)
- if(r_hand)
- var/t_state = r_hand.item_state
- if(!t_state) t_state = r_hand.icon_state
- r_hand.screen_loc = ui_rhand
- overlays_standing[X_R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = t_state)
- else
- overlays_standing[X_R_HAND_LAYER] = null
- if(update_icons) update_icons()
-
-/mob/living/carbon/alien/humanoid/update_inv_l_hand(var/update_icons=1)
- if(l_hand)
- var/t_state = l_hand.item_state
- if(!t_state) t_state = l_hand.icon_state
- l_hand.screen_loc = ui_lhand
- overlays_standing[X_L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = t_state)
- else
- overlays_standing[X_L_HAND_LAYER] = null
- if(update_icons) update_icons()
-
-//Call when target overlay should be added/removed
-/mob/living/carbon/alien/humanoid/update_targeted(var/update_icons=1)
- if (targeted_by && target_locked)
- overlays_lying[TARGETED_LAYER] = target_locked
- overlays_standing[TARGETED_LAYER] = target_locked
- else if (!targeted_by && target_locked)
- del(target_locked)
- if (!targeted_by)
- overlays_lying[TARGETED_LAYER] = null
- overlays_standing[TARGETED_LAYER] = null
- if(update_icons) update_icons()
-
-//Xeno Overlays Indexes//////////
-#undef X_HEAD_LAYER
-#undef X_SUIT_LAYER
-#undef X_L_HAND_LAYER
-#undef X_R_HAND_LAYER
-#undef TARGETED_LAYER
-#undef X_TOTAL_LAYERS
diff --git a/code/modules/mob/living/carbon/alien/larva/death.dm b/code/modules/mob/living/carbon/alien/larva/death.dm
deleted file mode 100644
index 27f49e3ad9..0000000000
--- a/code/modules/mob/living/carbon/alien/larva/death.dm
+++ /dev/null
@@ -1,15 +0,0 @@
-/mob/living/carbon/alien/larva/death(gibbed)
- if(stat == DEAD) return
- if(healths) healths.icon_state = "health6"
- stat = DEAD
- icon_state = "larva_dead"
-
- if(!gibbed)
- update_canmove()
- if(client) blind.layer = 0
-
- tod = worldtime2text() //weasellos time of death patch
- if(mind) mind.store_memory("Time of death: [tod]", 0)
- living_mob_list -= src
-
- return ..(gibbed)
diff --git a/code/modules/mob/living/carbon/alien/larva/inventory.dm b/code/modules/mob/living/carbon/alien/larva/inventory.dm
deleted file mode 100644
index 076053b253..0000000000
--- a/code/modules/mob/living/carbon/alien/larva/inventory.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-//can't unequip since it can't equip anything
-/mob/living/carbon/alien/larva/u_equip(obj/item/W as obj)
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 9f5640c69b..c811fd2b09 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -1,375 +1,19 @@
/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 You fail to push [tmob]'s fat ass out of the way."
- 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 [M] [M.attacktext] [src]!", 1)
- var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
- adjustBruteLoss(damage)
- M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])")
- src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])")
- 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 [M.name] has bit [src]!"), 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 The [M.name] glomps []!", 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 [src] has been touched with the stun gloves by [M]!", 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 Remove that mask!"
- 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 [] has punched []!", 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 [] has weakened []!", 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 [] has attempted to punch []!", 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 [M.name] has bit []!", src), 1)
- adjustBruteLoss(damage)
- updatehealth()
- else
- M << "\green [name] is too injured for that."
- 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 = {"
-
[name]
-
-
Close
-
"}
- 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) */
\ No newline at end of file
+ add_language("Rootspeak")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
deleted file mode 100644
index 97abbdec38..0000000000
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ /dev/null
@@ -1,369 +0,0 @@
-//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/phoron_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["phoron"] / breath.total_moles) * breath_pressure
-
- if(Toxins_pp) // Detect phoron in air
-
- adjustToxLoss(breath.gas["phoron"] * 250)
- phoron_alert = max(phoron_alert, 1)
-
- phoron_used = breath.gas["phoron"]
-
- else
- phoron_alert = 0
-
- //Breathe in phoron and out oxygen
- breath.adjust_gas("phoron", -phoron_used)
- breath.adjust_gas("oxygen", phoron_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 || !has_brain())
- 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[phoron_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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/login.dm b/code/modules/mob/living/carbon/alien/larva/login.dm
deleted file mode 100644
index 33808a4d96..0000000000
--- a/code/modules/mob/living/carbon/alien/larva/login.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-/mob/living/carbon/alien/larva/Login()
- return ..()
-
diff --git a/code/modules/mob/living/carbon/alien/larva/powers.dm b/code/modules/mob/living/carbon/alien/larva/powers.dm
deleted file mode 100644
index a1806692df..0000000000
--- a/code/modules/mob/living/carbon/alien/larva/powers.dm
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/mob/living/carbon/alien/larva/verb/hide()
- set name = "Hide"
- set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
- set category = "Alien"
-
- if(stat != CONSCIOUS)
- return
-
- if (layer != TURF_LAYER+0.2)
- layer = TURF_LAYER+0.2
- src << text("\green You are now hiding.")
- for(var/mob/O in oviewers(src, null))
- if ((O.client && !( O.blinded )))
- O << text("[] scurries to the ground!", src)
- else
- layer = MOB_LAYER
- src << text("\green You have stopped hiding.")
- for(var/mob/O in oviewers(src, null))
- if ((O.client && !( O.blinded )))
- O << text("[] slowly peaks up from the ground...", src)
-
-/mob/living/carbon/alien/larva/verb/evolve()
- set name = "Evolve"
- set desc = "Evolve into a fully grown Alien."
- set category = "Alien"
-
- if(stat != CONSCIOUS)
- return
-
- if(handcuffed || legcuffed)
- src << "\red You cannot evolve when you are cuffed."
-
- if(amount_grown >= max_grown) //TODO ~Carn
- //green is impossible to read, so i made these blue and changed the formatting slightly
- src << "\blue You are growing into a beautiful alien! It is time to choose a caste."
- src << "\blue There are three to choose from:"
- src << "Hunters \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 << "Sentinels \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 << "Drones \blue are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen."
- var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
-
- var/mob/living/carbon/alien/humanoid/new_xeno
- switch(alien_caste)
- if("Hunter")
- new_xeno = new /mob/living/carbon/alien/humanoid/hunter(loc)
- if("Sentinel")
- new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(loc)
- if("Drone")
- new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc)
- if(mind) mind.transfer_to(new_xeno)
- del(src)
- return
- else
- src << "\red You are not fully grown."
- return
diff --git a/code/modules/mob/living/carbon/alien/larva/progression.dm b/code/modules/mob/living/carbon/alien/larva/progression.dm
new file mode 100644
index 0000000000..50d75af813
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/larva/progression.dm
@@ -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 You are growing into a beautiful alien! It is time to choose a caste."
+ src << "\blue There are three to choose from:"
+ src << "Hunters \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 << "Sentinels \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 << "Drones \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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
deleted file mode 100644
index 3ab3fb3b38..0000000000
--- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/mob/living/carbon/alien/larva/regenerate_icons()
- overlays = list()
- update_icons()
-
-/mob/living/carbon/alien/larva/update_icons()
- var/state = 0
- if(amount_grown > 150)
- state = 2
- else if(amount_grown > 50)
- state = 1
-
- if(stat == DEAD)
- icon_state = "larva[state]_dead"
- else if (handcuffed || legcuffed)
- icon_state = "larva[state]_cuff"
- else if (stunned)
- icon_state = "larva[state]_stun"
- else if(lying || resting)
- icon_state = "larva[state]_sleep"
- else
- icon_state = "larva[state]"
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
new file mode 100644
index 0000000000..5c0ea8ed1f
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -0,0 +1,63 @@
+// Alien larva are quite simple.
+/mob/living/carbon/alien/Life()
+
+ set invisibility = 0
+ set background = 1
+
+ if (monkeyizing)
+ return
+
+ ..()
+
+ if (stat != DEAD) //still breathing
+
+ // GROW!
+ update_progression()
+
+ // Radiation.
+ handle_mutations_and_radiation()
+
+ // Chemicals in the body
+ handle_chemicals_in_body()
+
+ blinded = null
+
+ handle_environment()
+
+ //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_environment(enviroment)
+ //TODO: Work out if larvae breathe/suffer from pressure/suffer from heat.
+ if(!enviroment)
+ return
+
+/mob/living/carbon/alien/proc/handle_regular_status_updates()
+ // TODO: sleep, blind, stunned, paralyzed?
+ return
+
+/mob/living/carbon/alien/proc/handle_regular_hud_updates()
+ return //TODO: Not sure what to do with this yet.
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/login.dm b/code/modules/mob/living/carbon/alien/login.dm
deleted file mode 100644
index 9701338e4b..0000000000
--- a/code/modules/mob/living/carbon/alien/login.dm
+++ /dev/null
@@ -1,4 +0,0 @@
-/mob/living/carbon/alien/humanoid/Login()
- ..()
- AddInfectionImages()
- return
diff --git a/code/modules/mob/living/carbon/alien/logout.dm b/code/modules/mob/living/carbon/alien/logout.dm
deleted file mode 100644
index c0734cd21f..0000000000
--- a/code/modules/mob/living/carbon/alien/logout.dm
+++ /dev/null
@@ -1,4 +0,0 @@
-/mob/living/carbon/alien/humanoid/Logout()
- ..()
- RemoveInfectionImages()
- return
diff --git a/code/modules/mob/living/carbon/alien/powers.dm b/code/modules/mob/living/carbon/alien/powers.dm
deleted file mode 100644
index d9452a8d79..0000000000
--- a/code/modules/mob/living/carbon/alien/powers.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/mob/living/carbon/alien/verb/ventcrawl() // -- TLE
- set name = "Crawl through vent"
- set desc = "Enter an air vent and crawl through the pipe system."
- set category = "Alien"
- handle_ventcrawl()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/progression.dm b/code/modules/mob/living/carbon/alien/progression.dm
new file mode 100644
index 0000000000..fe3ec5d2d5
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/progression.dm
@@ -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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm
index 28947ac55e..f822078885 100644
--- a/code/modules/mob/living/carbon/alien/say.dm
+++ b/code/modules/mob/living/carbon/alien/say.dm
@@ -1,68 +1,34 @@
-/mob/living/carbon/alien/say(var/message)
-
- if (silent)
- return
-
- if (length(message) >= 2)
- if (department_radio_keys[copytext(message, 1, 3)] == "alientalk")
- message = copytext(message, 3)
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
- if (stat == 2)
- return say_dead(message)
- else
- alien_talk(message)
- else
- if (copytext(message, 1, 2) != "*" && !stat)
- playsound(loc, "hiss", 25, 1, 1)//So aliens can hiss while they hiss yo/N
- return ..(message)
- else
-
-/mob/living/proc/alien_talk(var/message)
-
- log_say("[key_name(src)] : [message]")
- message = trim(message)
-
- if (!message)
- return
-
- var/message_a = say_quote(message)
- var/rendered = "Hivemind, [name] [message_a]"
- for (var/mob/living/S in player_list)
- if(!S.stat)
- if(S.alien_talk_understand)
- if(S.alien_talk_understand == alien_talk_understand)
- S.show_message(rendered, 2)
- else if (S.hivecheck())
- S.show_message(rendered, 2)
-
- var/list/listening = hearers(1, src)
- listening -= src
- listening += src
-
- var/list/heard = list()
- for (var/mob/M in listening)
- if(!istype(M, /mob/living/carbon/alien) && !M.alien_talk_understand)
- heard += M
-
-
- if (length(heard))
- var/message_b
-
- message_b = "hsssss"
- message_b = say_quote(message_b)
- message_b = "[message_b]"
-
- rendered = "[voice_name] [message_b]"
-
- for (var/mob/M in heard)
- M.show_message(rendered, 2)
-
- message = say_quote(message)
-
- rendered = "Hivemind, [name] [message_a]"
-
- for (var/mob/M in player_list)
- if (istype(M, /mob/new_player))
- continue
- if (M.stat > 1)
- M.show_message(rendered, 2)
\ No newline at end of file
+/mob/living/carbon/alien/say(var/message)
+ var/verb = "says"
+ var/message_range = world.view
+
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "\red You cannot speak in IC (Muted)."
+ return
+
+ message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
+
+ if(stat == 2)
+ return say_dead(message)
+
+ var/datum/language/speaking = null
+
+ if(length(message) >= 2)
+ var/channel_prefix = copytext(message, 1 ,3)
+ if(languages.len)
+ for(var/datum/language/L in languages)
+ if(lowertext(channel_prefix) == ":[L.key]")
+ verb = L.speech_verb
+ speaking = L
+ break
+
+ if(speaking)
+ message = trim(copytext(message,3))
+
+ message = capitalize(trim_left(message))
+
+ if(!message || stat)
+ return
+
+ ..(message, speaking, verb, null, null, message_range, null)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/special/_main.dm b/code/modules/mob/living/carbon/alien/special/_main.dm
deleted file mode 100644
index eb5594f3c9..0000000000
--- a/code/modules/mob/living/carbon/alien/special/_main.dm
+++ /dev/null
@@ -1,71 +0,0 @@
-//XCOM alien code
-//By Xerif (Donated by the Foundation project, ss13.org)
-
-/mob/living/carbon/alien/humanoid/special
- has_fine_manipulation = 1
- var/xcom_state
-
- New()
- ..()
- spawn (1)
- var/datum/reagents/R = new/datum/reagents(100)
- reagents = R
- R.my_atom = src
-
- mind = new()
- mind.key = key
- mind.special_role = "Special Xeno"
-
- name = "[name] ([rand(1, 1000)])"
- real_name = name
-
- src.stand_icon = new /icon('xcomalien.dmi', xcom_state)
- src.lying_icon = new /icon('xcomalien.dmi', xcom_state)
- src.icon = src.stand_icon
-
- remove_special_verbs()
-
- rebuild_appearance()
-
- death(gibbed)
- ..()
- spawn(5)
- gib()
-
- Stat()
- statpanel("Status")
- if (src.client && src.client.holder)
- stat(null, "([x], [y], [z])")
-
- stat(null, "Intent: [src.a_intent]")
- stat(null, "Move Mode: [src.m_intent]")
-
- if (src.client.statpanel == "Status")
- if (src.internal)
- if (!src.internal.air_contents)
- del(src.internal)
- else
- stat("Internal Atmosphere Info", src.internal.name)
- stat("Tank Pressure", src.internal.air_contents.return_pressure())
- stat("Distribution Pressure", src.internal.distribute_pressure)
- return
-
- alien_talk()
- if(istype(src, /mob/living/carbon/alien/humanoid/special/etheral))
- ..()
- return
- if(istype(src, /mob/living/carbon/alien/humanoid/special/sectoid))
- ..()
- return
- return
-
-/mob/living/carbon/alien/humanoid/special/proc/xcom_attack()
- return
-
-/mob/living/carbon/alien/humanoid/special/proc/remove_special_verbs()
- verbs -= /mob/living/carbon/alien/humanoid/verb/plant
- verbs -= /mob/living/carbon/alien/humanoid/verb/ActivateHuggers
- verbs -= /mob/living/carbon/alien/humanoid/verb/whisp
- verbs -= /mob/living/carbon/alien/humanoid/verb/transfer_plasma
- verbs -= /mob/living/carbon/alien/humanoid/verb/corrode
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/special/snakeman.dm b/code/modules/mob/living/carbon/alien/special/snakeman.dm
deleted file mode 100644
index 7aa7b9d5db..0000000000
--- a/code/modules/mob/living/carbon/alien/special/snakeman.dm
+++ /dev/null
@@ -1,59 +0,0 @@
-/mob/living/carbon/alien/humanoid/special/snakeman
- name = "Snakeman"
- desc = "This race developed in an extremely hostile environment. They are extremely tough and can resist extreme temperature variations. Their mobility depends on a snake-like giant \"foot\" which protects all the vital organs. "
- xcom_state = "snake"
-
- movement_delay()
- return 4
-
-/mob/living/carbon/alien/humanoid/special/snakeman/verb/lay_egg(mob/living/carbon/human/M as mob)
- set name = "Impregnate"
- set desc = "Lays an egg on a corpse, allowing the egg to feed."
- set category = "Snakeman"
-
- set src = view(0)
-
- if(stat)
- return
-
- if(!M)
- return
-
- if(!M.client)
- src << "This being is missing a brain."
- return
-
- visible_message("[src] extends a probiscis and stabs it into [M]")
-
- if (!do_mob(usr, M, 50))
- usr << "\red The injection of the egg has been interrupted!"
- return
-
- if(M.client)
- M.client.mob = new/mob/living/carbon/alien/humanoid/special/snakeman(new/obj/effect/snake_egg(src.loc))
- visible_message("[src] injects [M] with an egg.")
- visible_message("The egg absorbs [M]")
- M.mutations |= NOCLONE
- M.update_body()
- M.death()
- else
- src << "This being is missing a brain."
-
- return
-
-/obj/effect/snake_egg
- name = "Egg"
- icon = 'icons/mob/alien.dmi'
- icon_state = "egg"
- density = 1
- anchored = 1
-
- New()
- ..()
-
- spawn(300)
- for(var/mob/M in src)
- M.loc = src.loc
- icon_state = "egg_hatched"
- density = 0
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/update_icons.dm b/code/modules/mob/living/carbon/alien/update_icons.dm
new file mode 100644
index 0000000000..794078a3b3
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/update_icons.dm
@@ -0,0 +1,22 @@
+/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 (handcuffed || legcuffed)
+ icon_state = "[initial(icon_state)][state]_cuff"
+ 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]"
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index 5ee424bd8d..f17bfa5d73 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -132,7 +132,6 @@
src.brainmob.real_name = src.brainmob.name
src.brainmob.loc = src
src.brainmob.container = src
- src.brainmob.robot_talk_understand = 1
src.brainmob.stat = 0
src.brainmob.silent = 0
dead_mob_list -= src.brainmob
diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm
index fa09d87f22..4756cc88ad 100644
--- a/code/modules/mob/living/carbon/brain/say.dm
+++ b/code/modules/mob/living/carbon/brain/say.dm
@@ -1,3 +1,4 @@
+//TODO: Convert this over for languages.
/mob/living/carbon/brain/say(var/message)
if (silent)
return
@@ -5,11 +6,6 @@
if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/mmi/posibrain))))
return //No MMI, can't speak, bucko./N
else
- if ((department_radio_keys[copytext(message, 1, 3)] == "binary") && (container && istype(container, /obj/item/device/mmi/posibrain)))
- message = copytext(message, 3)
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
- robot_talk(message)
- return
if(prob(emp_damage*4))
if(prob(10))//10% chane to drop the message entirely
return
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index f0c22c9f59..1687016f85 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -224,7 +224,11 @@
M.visible_message("[M] shakes [src] trying to wake [t_him] up!", \
"You shake [src] trying to wake [t_him] up!")
else
- M.visible_message("[M] hugs [src] to make [t_him] feel better!", \
+ var/mob/living/carbon/human/H = M
+ if(istype(H))
+ H.species.hug(H,src)
+ else
+ M.visible_message("[M] hugs [src] to make [t_him] feel better!", \
"You hug [src] to make [t_him] feel better!")
AdjustParalysis(-3)
@@ -427,7 +431,7 @@
//Brain slug proc for voluntary removal of control.
/mob/living/carbon/proc/release_control()
- set category = "Alien"
+ set category = "Abilities"
set name = "Release Control"
set desc = "Release control of your host's body."
@@ -447,7 +451,7 @@
//Brain slug proc for tormenting the host.
/mob/living/carbon/proc/punish_host()
- set category = "Alien"
+ set category = "Abilities"
set name = "Torment host"
set desc = "Punish your host with agony."
@@ -470,7 +474,7 @@
return 0
/mob/living/carbon/proc/spawn_larvae()
- set category = "Alien"
+ set category = "Abilities"
set name = "Reproduce"
set desc = "Spawn several young."
@@ -491,4 +495,4 @@
else
src << "You do not have enough chemicals stored to reproduce."
- return
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/carbon_powers.dm b/code/modules/mob/living/carbon/carbon_powers.dm
new file mode 100644
index 0000000000..c477d26031
--- /dev/null
+++ b/code/modules/mob/living/carbon/carbon_powers.dm
@@ -0,0 +1,39 @@
+//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.")
diff --git a/code/modules/mob/living/carbon/human/alien/alien.dm b/code/modules/mob/living/carbon/human/alien/alien.dm
new file mode 100644
index 0000000000..4c5c9e739b
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/alien/alien.dm
@@ -0,0 +1,92 @@
+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")
+
+/mob/living/carbon/human/Stat()
+
+ ..()
+
+// 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 = {"
+
[name]
+
+
Left Hand: [(l_hand ? text("[]", l_hand) : "Nothing")]
+
Right Hand: [(r_hand ? text("[]", r_hand) : "Nothing")]
+
Head: [(head ? text("[]", head) : "Nothing")]
+
(Exo)Suit: [(wear_suit ? text("[]", wear_suit) : "Nothing")]
+
Empty Pouches
+
Close
+
"}
+ 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*/
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/human/alien/alien_embryo.dm
similarity index 90%
rename from code/modules/mob/living/carbon/alien/special/alien_embryo.dm
rename to code/modules/mob/living/carbon/human/alien/alien_embryo.dm
index 35b9e9fbfd..4bdddc2ca6 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/human/alien/alien_embryo.dm
@@ -1,143 +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/alien in player_list)
- if(alien.client)
- for(var/image/I in alien.client.images)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- del(I)
- for(var/mob/living/L in mob_list)
- if(iscorgi(L) || iscarbon(L))
- if(L.status_flags & XENO_HOST)
- var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
- alien.client.images += I
-
-/*----------------------------------------
-Proc: AddInfectionImages(C)
-Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
-----------------------------------------*/
-/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
- if(C)
- for(var/mob/living/carbon/alien/alien in player_list)
- if(alien.client)
- if(C.status_flags & XENO_HOST)
- var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
- alien.client.images += I
-
-/*----------------------------------------
-Proc: RemoveInfectionImage(C)
-Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
-----------------------------------------*/
-
-/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
- if(C)
- for(var/mob/living/carbon/alien/alien in player_list)
- if(alien.client)
- for(var/image/I in alien.client.images)
- if(I.loc == C)
- if(dd_hasprefix_case(I.icon_state, "infected"))
+// 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)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/human/alien/alien_facehugger.dm
similarity index 86%
rename from code/modules/mob/living/carbon/alien/special/facehugger.dm
rename to code/modules/mob/living/carbon/human/alien/alien_facehugger.dm
index fc702d3f63..ffbaed6cc7 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/human/alien/alien_facehugger.dm
@@ -1,241 +1,239 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-//TODO: Make these simple_animals
-
-var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
-var/const/MAX_IMPREGNATION_TIME = 150
-
-var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
-var/const/MAX_ACTIVE_TIME = 400
-
-/obj/item/clothing/mask/facehugger
- name = "alien"
- desc = "It has some sort of a tube at the end of its tail."
- icon = 'icons/mob/alien.dmi'
- icon_state = "facehugger"
- item_state = "facehugger"
- w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
- flags = FPRINT | TABLEPASS | MASKCOVERSMOUTH | MASKCOVERSEYES | MASKINTERNALS
- 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
- if(isalien(user))
- attack_hand(user)
- return
- else
- ..()
- return
-
-/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
- if((stat == CONSCIOUS && !sterile) && !isalien(user))
- Attach(user)
- return
- else
- ..()
- return
-
-/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
- ..()
- user.drop_from_inventory(src)
- Attach(M)
-
-/obj/item/clothing/mask/facehugger/New()
- if(aliens_allowed)
- ..()
- else
- del(src)
-
-/obj/item/clothing/mask/facehugger/examine()
- ..()
- switch(stat)
- if(DEAD,UNCONSCIOUS)
- usr << "\red \b [src] is not moving."
- if(CONSCIOUS)
- usr << "\red \b [src] seems to be active."
- if (sterile)
- usr << "\red \b It looks like the proboscis has been removed."
- return
-
-/obj/item/clothing/mask/facehugger/attackby()
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/bullet_act()
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/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)) || isalien(M))
- return
- if(attached)
- return
- else
- attached++
- spawn(MAX_IMPREGNATION_TIME)
- attached = 0
-
- var/mob/living/L = M //just so I don't need to use :
-
- if(loc == L) return
- if(stat != CONSCIOUS) return
- if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
-
- L.visible_message("\red \b [src] leaps at [L]'s face!")
-
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(H.head && H.head.flags & HEADCOVERSMOUTH)
- H.visible_message("\red \b [src] smashes against [H]'s [H.head]!")
- Die()
- return
-
- if(iscarbon(M))
- var/mob/living/carbon/target = L
-
- if(target.wear_mask)
- if(prob(20)) return
- var/obj/item/clothing/W = target.wear_mask
- if(!W.canremove) return
- target.drop_from_inventory(W)
-
- target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
-
- target.equip_to_slot(src, slot_wear_mask)
-
- if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
- else if (iscorgi(M))
- var/mob/living/simple_animal/corgi/C = M
- src.loc = C
- C.facehugger = src
- C.wear_mask = src
- //C.regenerate_icons()
-
- GoIdle() //so it doesn't jump the people that tear it off
-
- spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
- Impregnate(L)
-
- return
-
-/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
- if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
- return
-
- if(!sterile)
- //target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
- new /obj/item/alien_embryo(target)
- target.status_flags |= XENO_HOST
-
- target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
-
- Die()
- icon_state = "[initial(icon_state)]_impregnated"
-
- if(iscorgi(target))
- var/mob/living/simple_animal/corgi/C = target
- src.loc = get_turf(C)
- C.facehugger = null
- else
- target.visible_message("\red \b [src] violates [target]'s face!")
- return
-
-/obj/item/clothing/mask/facehugger/proc/GoActive()
- if(stat == DEAD || stat == CONSCIOUS)
- return
-
- stat = CONSCIOUS
- icon_state = "[initial(icon_state)]"
-
-/* for(var/mob/living/carbon/alien/alien in world)
- var/image/activeIndicator = image('icons/mob/alien.dmi', loc = src, icon_state = "facehugger_active")
- activeIndicator.override = 1
- if(alien && alien.client)
- alien.client.images += activeIndicator */
-
- return
-
-/obj/item/clothing/mask/facehugger/proc/GoIdle()
- if(stat == DEAD || stat == UNCONSCIOUS)
- return
-
-/* RemoveActiveIndicators() */
-
- stat = UNCONSCIOUS
- icon_state = "[initial(icon_state)]_inactive"
-
- spawn(rand(MIN_ACTIVE_TIME,MAX_ACTIVE_TIME))
- GoActive()
- return
-
-/obj/item/clothing/mask/facehugger/proc/Die()
- if(stat == DEAD)
- return
-
-/* RemoveActiveIndicators() */
-
- icon_state = "[initial(icon_state)]_dead"
- stat = DEAD
-
- src.visible_message("\red \b[src] curls up into a ball!")
-
- return
-
-/proc/CanHug(var/mob/M)
-
- if(iscorgi(M))
- return 1
-
- if(!iscarbon(M) || isalien(M))
- return 0
- var/mob/living/carbon/C = M
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(H.head && H.head.flags & HEADCOVERSMOUTH)
- return 0
- return 1
+//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))
+ Attach(user)
+ return
+ else
+ ..()
+ return
+
+/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
+ ..()
+ user.drop_from_inventory(src)
+ Attach(M)
+
+/obj/item/clothing/mask/facehugger/New()
+ if(aliens_allowed)
+ ..()
+ else
+ del(src)
+
+/obj/item/clothing/mask/facehugger/examine()
+ ..()
+ switch(stat)
+ if(DEAD,UNCONSCIOUS)
+ usr << "\red \b [src] is not moving."
+ if(CONSCIOUS)
+ usr << "\red \b [src] seems to be active."
+ if (sterile)
+ usr << "\red \b It looks like the proboscis has been removed."
+ return
+
+/obj/item/clothing/mask/facehugger/attackby()
+ Die()
+ return
+
+/obj/item/clothing/mask/facehugger/bullet_act()
+ Die()
+ return
+
+/obj/item/clothing/mask/facehugger/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)
+
+ 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
diff --git a/code/modules/mob/living/carbon/human/alien/alien_powers.dm b/code/modules/mob/living/carbon/human/alien/alien_powers.dm
new file mode 100644
index 0000000000..4b522c3552
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/alien/alien_powers.dm
@@ -0,0 +1,228 @@
+/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 << "Your plasma vessel has been removed!"
+ return
+
+ if(needs_organ)
+ var/datum/organ/internal/I = internal_organs_by_name[needs_organ]
+ if(!I)
+ src << "Your [needs_organ] has been removed!"
+ return
+ else if((I.status & ORGAN_CUT_AWAY) || I.is_broken())
+ src << "Your [needs_organ] is too damaged to function!"
+ 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 [src] has laid an egg!"), 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 << "We already have an active queen."
+ 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 [src] begins to twist and contort!"), 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 [src] has planted some alien weeds!"), 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 [src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!")
+
+ 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
+
+ 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 [src] vomits up a thick purple substance and begins to shape it!"), 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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/alien/alien_species.dm b/code/modules/mob/living/carbon/human/alien/alien_species.dm
new file mode 100644
index 0000000000..185a3b60c7
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/alien/alien_species.dm
@@ -0,0 +1,251 @@
+//TODO: Generalize some kind of power pool so that other races can use it.
+//Stand-in until this is made more lore-friendly.
+/datum/species/xenos
+ name = "Xenomorph"
+ language = "Hivemind"
+ unarmed_type = /datum/unarmed_attack/claws/strong
+ secondary_unarmed_type = /datum/unarmed_attack/bite/strong
+ hud_type = /datum/hud_data/alien
+ 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 = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_PAIN | RAD_ABSORB | 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'
+
+ breath_type = null
+ poison_type = null
+
+ has_organ = list(
+ "heart" = /datum/organ/internal/heart,
+ "lungs" = /datum/organ/internal/lungs,
+ "brain" = /datum/organ/internal/brain,
+ "plasma vessel" = /datum/organ/internal/xenos/plasmavessel,
+ "hive node" = /datum/organ/internal/xenos/hivenode
+ )
+
+ 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/hug(var/mob/living/carbon/human/H,var/mob/living/target)
+ H.visible_message("[H] caresses [target] with its scythe-like arm.", \
+ "You caress [target] with your scythe-like arm.")
+
+
+/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)
+
+ if(!H.loc)
+ return
+
+ if(locate(/obj/effect/alien/weeds) in H.loc)
+ 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"
+
+ 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,
+ "lungs" = /datum/organ/internal/lungs,
+ "brain" = /datum/organ/internal/brain,
+ "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
+ )
+
+ inherent_verbs = list(
+ /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,
+ "lungs" = /datum/organ/internal/lungs,
+ "brain" = /datum/organ/internal/brain,
+ "plasma vessel" = /datum/organ/internal/xenos/plasmavessel/hunter,
+ "hive node" = /datum/organ/internal/xenos/hivenode
+ )
+
+ inherent_verbs = list(
+ /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,
+ "lungs" = /datum/organ/internal/lungs,
+ "brain" = /datum/organ/internal/brain,
+ "plasma vessel" = /datum/organ/internal/xenos/plasmavessel/sentinel,
+ "acid gland" = /datum/organ/internal/xenos/acidgland,
+ "hive node" = /datum/organ/internal/xenos/hivenode
+ )
+
+ inherent_verbs = list(
+ /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"
+ weeds_heal_rate = 5
+ weeds_plasma_rate = 20
+ caste_name = "queen"
+ slowdown = 5
+ tail = "xenos_queen_tail"
+
+ 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,
+ "lungs" = /datum/organ/internal/lungs,
+ "brain" = /datum/organ/internal/brain,
+ "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
+ )
+
+ inherent_verbs = list(
+ /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"),
+ )
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index e14cd9c534..f97397fe4c 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -19,10 +19,11 @@
// Override the current limb status and don't cause an explosion
E.droplimb(1,1)
- 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 +43,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)
@@ -97,7 +98,9 @@
vox_kills++ //Bad vox. Shouldn't be killing humans.
if(!gibbed)
- emote("deathgasp") //let the world KNOW WE ARE DEAD
+
+ emote("deathgasp") //let the world KNOW WE ARE DEAD // Doing this with the deathgasp emote seems odd.
+ if(species && species.death_sound) playsound(loc, species.death_sound, 80, 1, 1)
//For ninjas exploding when they die.
if( istype(wear_suit, /obj/item/clothing/suit/space/space_ninja) && wear_suit:s_initialized )
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 75eff694fa..9b5a526ca1 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -207,7 +207,7 @@
m_type = 2
if ("deathgasp")
- message = "[src] seizes up and falls limp, \his eyes dead and lifeless..."
+ message = "[src] [species.death_message]"
m_type = 1
if ("giggle")
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index c672950a18..6196e71159 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -240,7 +240,7 @@
if(getBrainLoss() >= 60)
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
- if(has_brain() && stat != DEAD)
+ if((!species.has_organ["brain"] || has_brain()) && stat != DEAD)
if(!key)
msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n"
else if(!client)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 3f7faeac8e..ba433afb17 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -4,46 +4,20 @@
voice_name = "unknown"
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
+
var/list/hud_list[9]
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
-
-/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")
-
/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()
@@ -51,10 +25,6 @@
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")
@@ -65,7 +35,6 @@
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[STATUS_HUD_OOC] = image('icons/mob/hud.dmi', src, "hudhealthy")
-
..()
if(dna)
@@ -176,6 +145,7 @@
stat(null, eta_status)
if (client.statpanel == "Status")
+
if (internal)
if (!internal.air_contents)
del(internal)
@@ -183,10 +153,15 @@
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, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
if(mind)
if(mind.changeling)
stat("Chemical Storage", mind.changeling.chem_charges)
stat("Genetic Damage Time", mind.changeling.geneticdamage)
+
if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
stat("Energy Charge", round(wear_suit:cell:charge/100))
@@ -299,7 +274,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
@@ -856,11 +831,21 @@
..()
return
-
///eyecheck()
///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
@@ -878,7 +863,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)
@@ -1261,7 +1246,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)
@@ -1272,16 +1257,15 @@
else
dna.species = new_species
- if(species && (species.name && species.name == new_species))
- return
-
- if(species && species.language)
- remove_language(species.language)
+ if(species)
+ if(species.name && species.name == new_species)
+ return
+ if(species.language)
+ remove_language(species.language)
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)
@@ -1300,6 +1284,7 @@
spawn(0)
update_icons()
+ vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
if(species)
@@ -1381,156 +1366,6 @@
// Might need re-wording.
user << "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into."
-
-//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"
- 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("\The [src] leaps at [T]!")
- 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 raider vox get the grab and no self-prone."
- if(src.mind && src.mind.special_role != "Vox Raider")
- 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("\The [src] seizes [T] aggressively!")
-
- 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 = "IC"
- 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("\The [src] rips viciously at \the [G.affecting]'s body with its claws!")
-
- 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 = "IC"
- 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/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
@@ -1569,6 +1404,16 @@
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"]
@@ -1581,4 +1426,4 @@
var/datum/organ/internal/eyes = internal_organs_by_name["eyes"]
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
return 1
- return 0
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_attackalien.dm b/code/modules/mob/living/carbon/human/human_attackalien.dm
deleted file mode 100644
index ea73d63f8d..0000000000
--- a/code/modules/mob/living/carbon/human/human_attackalien.dm
+++ /dev/null
@@ -1,62 +0,0 @@
-/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
- if(check_shields(0, M.name))
- visible_message("\red [M] attempted to touch [src]!")
- return 0
-
- switch(M.a_intent)
- if ("help")
- visible_message(text("\blue [M] caresses [src] with its scythe like arm."))
- if ("grab")
- if(M == src || anchored)
- return
- if (w_uniform)
- w_uniform.add_fingerprint(M)
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
-
- M.put_in_active_hand(G)
-
- grabbed_by += G
- G.synch()
- LAssailant = M
-
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- visible_message(text("\red [] has grabbed [] passively!", M, src))
-
- if("hurt")
- if (w_uniform)
- w_uniform.add_fingerprint(M)
- var/damage = rand(15, 30)
- if(!damage)
- playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
- visible_message("\red [M] has lunged at [src]!")
- return 0
- var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
- var/armor_block = run_armor_check(affecting, "melee")
-
- playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
- visible_message("\red [M] has slashed at [src]!")
-
- apply_damage(damage, BRUTE, affecting, armor_block)
- if (damage >= 25)
- visible_message("\red [M] has wounded [src]!")
- apply_effect(rand(0.5,3), WEAKEN, armor_block)
- updatehealth()
-
- if("disarm")
- if (prob(80))
- playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
- Weaken(rand(0.5,3))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has tackled down []!", M, src), 1)
- if (prob(25))
- M.Weaken(rand(2,4))
- else
- if (prob(80))
- playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
- drop_item()
- visible_message(text("\red [] disarmed []!", M, src))
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
- visible_message(text("\red [] has tried to disarm []!", M, src))
- return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index bacef8541b..46e70c06ac 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -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
M.attack_log += text("\[[time_stamp()]\] [pick(attack.attack_verb)]ed [src.name] ([src.ckey])")
src.attack_log += text("\[[time_stamp()]\] Has been [pick(attack.attack_verb)]ed by [M.name] ([M.ckey])")
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 8b4e010d4b..602c00edf6 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -1,7 +1,8 @@
//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,9 +10,15 @@
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() //TODO: link this to RAD_ABSORB or NO_SCAN
+
+ 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
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 337d32652c..30c883becb 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -1,8 +1,9 @@
/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 +80,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.
diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm
new file mode 100644
index 0000000000..1837380855
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/human_powers.dm
@@ -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(6,src))
+ if(!istype(M,/mob/living/silicon))
+ 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(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 + 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 [] [failed ? "tried to tackle" : "has tackled"] down []!", 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("\The [src] leaps at [T]!")
+ 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("\The [src] seizes [T] aggressively!")
+
+ 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("\The [src] rips viciously at \the [G.affecting]'s body with its claws!")
+
+ 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 [src] hurls out the contents of their stomach!")
+ 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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm
new file mode 100644
index 0000000000..c313c6015e
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/human_species.dm
@@ -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")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index dd02d3c17d..c4dec0abe8 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -638,9 +638,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)
@@ -1084,7 +1088,7 @@
handle_organs() //Optimized.
handle_blood()
- if(health <= config.health_threshold_dead || !has_brain())
+ if(health <= config.health_threshold_dead || (species.has_organ["brain"] && !has_brain()))
death()
blinded = 1
silent = 0
@@ -1660,8 +1664,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)
diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm
index 80d6f00288..d18d503502 100644
--- a/code/modules/mob/living/carbon/human/login.dm
+++ b/code/modules/mob/living/carbon/human/login.dm
@@ -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
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/logout.dm b/code/modules/mob/living/carbon/human/logout.dm
new file mode 100644
index 0000000000..f449ce991a
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/logout.dm
@@ -0,0 +1,4 @@
+/mob/living/carbon/human/Logout()
+ ..()
+ if(species) species.handle_logout_special(src)
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 8d361c7060..2b9878e345 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -1,4 +1,7 @@
/mob/living/carbon/human/say(var/message)
+
+ //TODO: Add checks for species who do not speak common.
+
var/verb = "says"
var/alt_name = ""
var/message_range = world.view
@@ -38,6 +41,12 @@
verb = speaking.speech_verb
message = copytext(message,3)
+ // This is broadcast to all mobs with the language,
+ // irrespective of distance or anything else.
+ if(speaking.flags & HIVEMIND)
+ speaking.broadcast(src,trim(message))
+ return
+
message = capitalize(trim(message))
if(speech_problem_flag)
@@ -103,16 +112,6 @@
if("whisper")
whisper_say(message, speaking, alt_name)
return
- if("binary")
- if(robot_talk_understand || binarycheck())
- robot_talk(message)
- return
- if("changeling")
- if(mind && mind.changeling)
- for(var/mob/Changeling in mob_list)
- if((Changeling.mind && Changeling.mind.changeling) || istype(Changeling, /mob/dead/observer))
- Changeling << "[mind.changeling.changelingID]: [message]"
- return
else
if(message_mode)
if(message_mode in (radiochannels | "department"))
@@ -125,8 +124,8 @@
var/sound/speech_sound
var/sound_vol
- if((species.name == "Vox" || species.name == "Vox Armalis") && prob(20))
- speech_sound = sound('sound/voice/shriek1.ogg')
+ if(species.speech_sounds && prob(20))
+ speech_sound = sound(pick(species.speech_sounds))
sound_vol = 50
..(message, speaking, verb, alt_name, italics, message_range, used_radios, speech_sound, sound_vol) //ohgod we should really be passing a datum here.
@@ -172,8 +171,8 @@
//These only pertain to common. Languages are handled by mob/say_understands()
if (!speaking)
- if (istype(other, /mob/living/carbon/monkey/diona))
- if(other.languages.len >= 2) //They've sucked down some blood and can speak common now.
+ if (istype(other, /mob/living/carbon/alien/diona))
+ if(other.languages.len >= 2) //They've sucked down some blood and can speak common now.
return 1
if (istype(other, /mob/living/silicon))
return 1
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/human/species.dm
similarity index 52%
rename from code/modules/mob/living/carbon/species.dm
rename to code/modules/mob/living/carbon/human/species.dm
index d5e8a16761..d2727d94d3 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -3,24 +3,43 @@
*/
/datum/species
- var/name // Species name.
-
+ var/name // Species name.
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
var/eyes = "eyes_s" // Icon for eyes.
- var/primitive // Lesser form, if any (ie. monkey for humans)
- var/tail // Name of tail image in species effects icon file.
- var/language // Default racial language, if any.
- var/unarmed //For empty hand harm-intent attack
- var/unarmed_type = /datum/unarmed_attack
- var/secondary_langs = list() // The names of secondary languages that are available to this species.
- var/mutantrace // Safeguard due to old code.
+ var/primitive // Lesser form, if any (ie. monkey for humans)
+ var/tail // Name of tail image in species effects icon file.
+ var/language // Default racial language, if any.
+ var/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/unarmed_type = /datum/unarmed_attack
+ var/secondary_unarmed_type = /datum/unarmed_attack/bite
+
+ 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/has_fine_manipulation = 1 // Can use small items.
+ var/insulated // Immune to electrocution.
+
+ // 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.
@@ -54,6 +73,8 @@
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,
@@ -63,12 +84,30 @@
"appendix" = /datum/organ/internal/appendix,
"eyes" = /datum/organ/internal/eyes
)
+
/datum/species/New()
- unarmed = new unarmed_type()
+ 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.
- //This is a basic humanoid limb setup.
+
+ //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"])
@@ -81,7 +120,6 @@
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"])
- H.internal_organs = list()
for(var/organ in has_organ)
var/organ_type = has_organ[organ]
H.internal_organs_by_name[organ] = new organ_type(H)
@@ -99,19 +137,60 @@
for(var/datum/organ/internal/I in H.internal_organs)
I.mechanize()
-/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
+/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("[H] hugs [target] to make [t_him] feel better!", \
+ "You hug [target] to make [t_him] feel better!")
+
+/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.make_jittery(200) //S-s-s-s-sytem f-f-ai-i-i-i-i-lure-ure-ure-ure
H.h_style = ""
spawn(100)
- //H.is_jittery = 0
- //H.jitteriness = 0
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
+
/datum/species/human
name = "Human"
language = "Sol Common"
@@ -130,8 +209,10 @@
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
@@ -191,7 +272,10 @@
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
language = "Vox-pidgin"
- unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too.
+ unarmed_type = /datum/unarmed_attack/claws/strong
+ secondary_unarmed_type = /datum/unarmed_attack/bite/strong
+
+ speech_sounds = list('sound/voice/shriek1.ogg')
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -204,6 +288,7 @@
breath_type = "nitrogen"
poison_type = "oxygen"
+ insulated = 1
flags = NO_SCAN
@@ -212,23 +297,24 @@
reagent_tag = IS_VOX
-/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
+ inherent_verbs = list(
+ /mob/living/carbon/human/proc/leap
+ )
- H.verbs += /mob/living/carbon/human/proc/leap
- ..()
-
-/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H)
-
- H.verbs += /mob/living/carbon/human/proc/gut
- H.verbs += /mob/living/carbon/human/proc/commune
- ..()
+ 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
+ )
/datum/species/vox/armalis
name = "Vox Armalis"
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
language = "Vox-pidgin"
- unarmed_type = /datum/unarmed_attack/claws/armalis
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -258,13 +344,29 @@
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"
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/monkey/diona
+ primitive = /mob/living/carbon/alien/diona
+ slowdown = 7
+
+ 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
@@ -279,7 +381,7 @@
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
- flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
+ flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | NO_PAIN | NO_SLIP
blood_color = "#004400"
flesh_color = "#907E4A"
@@ -288,17 +390,16 @@
/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/monkey/diona/S = new(get_turf(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/monkey/diona/D in H.contents)
+ for(var/mob/living/carbon/alien/diona/D in H.contents)
if(D.client)
D.loc = H.loc
else
@@ -335,18 +436,65 @@
blood_color = "#1F181F"
flesh_color = "#575757"
-//Species unarmed attacks
+ 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.shredding && unarmed.is_usable(H))
+ return 1
+ else if(secondary_unarmed.shredding && secondary_unarmed.is_usable(H))
+ 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 = 1
+ 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")
@@ -360,6 +508,47 @@
sharp = 1
edge = 1
-/datum/unarmed_attack/claws/armalis
- attack_verb = list("slash", "claw")
- damage = 10 //they're huge! they should do a little more damage, i'd even go for 15-20 maybe...
+/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.
+
+ // 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")
+ )
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 2ae79230d2..ad609cad73 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -412,7 +412,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)
diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm
index c82d517d59..7820e2a416 100644
--- a/code/modules/mob/living/carbon/metroid/life.dm
+++ b/code/modules/mob/living/carbon/metroid/life.dm
@@ -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
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index 85fdb33a8d..df9d22c5dc 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -54,6 +54,9 @@
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)
@@ -274,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
@@ -447,93 +450,6 @@
visible_message("[M] has attempted to punch [src]!")
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("[M] caresses [src] with its scythe like arm.")
-
- 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("[M] has attacked [name]!", \
- "[M] has attacked [name]!")
- else
- visible_message("[M] has wounded [name]!", \
- ")[M] has wounded [name]!")
- adjustBruteLoss(damage)
- updatehealth()
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- visible_message("[M] has attempted to lunge at [name]!", \
- "[M] has attempted to lunge at [name]!")
-
- 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(" [M] has grabbed [name] passively!")
-
- if ("disarm")
- playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
- var/damage = 5
- attacked += 10
-
- if(prob(95))
- visible_message("[M] has tackled [name]!", \
- "[M] has tackled [name]!")
-
- 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("[M] has disarmed [name]!",
- "[M] has disarmed [name]!")
- adjustBruteLoss(damage)
- updatehealth()
- return
-
/mob/living/carbon/slime/attackby(obj/item/W, mob/user)
if(W.force > 0)
attacked += 10
@@ -615,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\"."
diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm
index bb7dcbe7bb..15fdb60349 100644
--- a/code/modules/mob/living/carbon/metroid/powers.dm
+++ b/code/modules/mob/living/carbon/metroid/powers.dm
@@ -104,7 +104,7 @@
adjustBruteLoss(-10)
adjustFireLoss(-10)
adjustCloneLoss(-10)
-
+
updatehealth()
if(Victim)
Victim.updatehealth()
@@ -225,11 +225,4 @@
else
src << "I am not ready to reproduce yet..."
else
- src << "I am not old enough to reproduce yet..."
-
-/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()
\ No newline at end of file
+ src << "I am not old enough to reproduce yet..."
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm
deleted file mode 100644
index 0a12334701..0000000000
--- a/code/modules/mob/living/carbon/monkey/diona.dm
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- Tiny babby plant critter plus procs.
-*/
-
-//Mob defines.
-/mob/living/carbon/monkey/diona
- name = "diona nymph"
- voice_name = "diona nymph"
- speak_emote = list("chirrups")
- icon_state = "nymph1"
- var/list/donors = list()
- var/ready_evolve = 0
- 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/monkey/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/monkey/diona/proc/split
- src.verbs -= /mob/living/carbon/monkey/diona/proc/merge
- src.loc = M
- else
- get_scooped(M)
-
- ..()
-
-/mob/living/carbon/monkey/diona/New()
-
- ..()
- gender = NEUTER
- dna.mutantrace = "plant"
- greaterform = "Diona"
- add_language("Rootspeak")
- src.verbs += /mob/living/carbon/monkey/diona/proc/merge
-
-//Verbs after this point.
-
-/mob/living/carbon/monkey/diona/proc/merge()
-
- set category = "Diona"
- set name = "Merge with gestalt"
- set desc = "Merge with another diona."
-
- if(istype(src.loc,/mob/living/carbon))
- src.verbs -= /mob/living/carbon/monkey/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/monkey/diona/proc/split
- src.verbs -= /mob/living/carbon/monkey/diona/proc/merge
- else
- return
-
-/mob/living/carbon/monkey/diona/proc/split()
-
- set category = "Diona"
- 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/monkey/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/monkey/diona/proc/split
- src.verbs += /mob/living/carbon/monkey/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/monkey/diona/verb/fertilize_plant()
-
- set category = "Diona"
- set name = "Fertilize plant"
- set desc = "Turn your food into nutrients for plants."
-
- var/list/trays = list()
- for(var/obj/machinery/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 from its tail, refilling [target]'s nutrient tray.","\red You secrete a trickle of green liquid from your tail, refilling [target]'s nutrient tray.")
-
-/mob/living/carbon/monkey/diona/verb/eat_weeds()
-
- set category = "Diona"
- set name = "Eat Weeds"
- set desc = "Clean the weeds out of soil or a hydroponics tray."
-
- var/list/trays = list()
- for(var/obj/machinery/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.")
-
-/mob/living/carbon/monkey/diona/verb/evolve()
-
- set category = "Diona"
- set name = "Evolve"
- set desc = "Grow to a more complex form."
-
- if(!is_alien_whitelisted(src, "Diona") && config.usealienwhitelist)
- src << alert("You are currently not whitelisted to play as a full diona.")
- return 0
-
- if(donors.len < 5)
- src << "You are not yet ready for your growth..."
- return
-
- if(nutrition < 400)
- src << "You have not yet consumed enough to grow..."
- return
-
- src.split()
- 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.")
-
- var/mob/living/carbon/human/adult = new(get_turf(src.loc))
- adult.set_species("Diona")
-
- if(istype(loc,/obj/item/weapon/holder/diona))
- var/obj/item/weapon/holder/diona/L = loc
- src.loc = L.loc
- del(L)
-
- for(var/datum/language/L in languages)
- adult.add_language(L.name)
- adult.regenerate_icons()
-
- adult.name = "diona ([rand(100,999)])"
- adult.real_name = adult.name
- adult.ckey = src.ckey
-
- for (var/obj/item/W in src.contents)
- src.drop_from_inventory(W)
- del(src)
-
-/mob/living/carbon/monkey/diona/verb/steal_blood()
- set category = "Diona"
- set name = "Steal Blood"
- set desc = "Take a blood sample from a suitable donor."
-
- var/list/choices = list()
- for(var/mob/living/carbon/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()
-
-/mob/living/carbon/monkey/diona/proc/update_progression()
-
- if(!donors.len)
- return
-
- if(donors.len == 5)
- ready_evolve = 1
- src << "\green You feel ready to move on to your next stage of growth."
- else if(donors.len == 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."
-
-
-/mob/living/carbon/monkey/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 ..()
-
-/mob/living/carbon/monkey/diona/say(var/message)
- var/verb = "says"
- var/message_range = world.view
-
- if(client)
- if(client.prefs.muted & MUTE_IC)
- src << "\red You cannot speak in IC (Muted)."
- return
-
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
-
- if(stat == 2)
- return say_dead(message)
-
- var/datum/language/speaking = null
-
- if(length(message) >= 2)
- var/channel_prefix = copytext(message, 1 ,3)
- if(languages.len)
- for(var/datum/language/L in languages)
- if(lowertext(channel_prefix) == ":[L.key]")
- verb = L.speech_verb
- speaking = L
- break
-
- if(speaking)
- message = trim(copytext(message,3))
-
- message = capitalize(trim_left(message))
-
- if(!message || stat)
- return
-
- ..(message, speaking, verb, null, null, message_range, null)
diff --git a/code/modules/mob/living/carbon/monkey/emote.dm b/code/modules/mob/living/carbon/monkey/emote.dm
index d5328183f3..92493b6d38 100644
--- a/code/modules/mob/living/carbon/monkey/emote.dm
+++ b/code/modules/mob/living/carbon/monkey/emote.dm
@@ -31,11 +31,6 @@
if ("custom")
return custom_emote(m_type, message)
- if ("chirp")
- if(istype(src,/mob/living/carbon/monkey/diona))
- message = "The [src.name] chirps!"
- playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
- m_type = 2
if("sign")
if (!src.restrained())
message = text("The monkey signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
@@ -119,10 +114,7 @@
message = "The [src.name] lets out a faint chimper as it collapses and stops moving..."
m_type = 1
if("help")
- var/text = "choke, "
- if(istype(src,/mob/living/carbon/monkey/diona))
- text += "chirp, "
- text += "collapse, dance, deathgasp, drool, gasp, shiver, gnarl, jump, paw, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
+ text += "choke, collapse, dance, deathgasp, drool, gasp, shiver, gnarl, jump, paw, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper"
src << text
else
src << text("Invalid Emote: []", act)
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index 44a7e7a259..50380a580a 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -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()
@@ -122,15 +120,6 @@
if (radiation)
- if(istype(src,/mob/living/carbon/monkey/diona)) //Filthy check. Dionaea don't take rad damage.
- var/rads = radiation/25
- radiation -= rads
- nutrition += rads
- heal_overall_damage(rads,rads)
- adjustOxyLoss(-(rads))
- adjustToxLoss(-(rads))
- return
-
if (radiation > 100)
radiation = 100
Weaken(10)
@@ -439,27 +428,8 @@
proc/handle_chemicals_in_body()
- if(alien) //Diona nymphs are the only alien monkey currently.
- var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
- if(isturf(loc)) //else, there's considered to be no light
- var/turf/T = loc
- var/area/A = T.loc
- if(A)
- if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
- else light_amount = 5
-
- nutrition += light_amount
- traumatic_shock -= light_amount
-
- if(nutrition > 500)
- nutrition = 500
- if(light_amount > 2) //if there's enough light, heal
- adjustBruteLoss(-1)
- adjustToxLoss(-1)
- adjustOxyLoss(-1)
-
if(reagents && reagents.reagent_list.len)
- reagents.metabolize(src,alien)
+ reagents.metabolize(src)
if (drowsyness)
drowsyness--
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 7bb9af2a15..2d9abfa246 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -14,7 +14,6 @@
//var/uni_append = "12C4E2" // Small appearance modifier for different species.
var/list/uni_append = list(0x12C,0x4E2) // Same as above for DNA2.
var/update_muts = 1 // Monkey gene must be set at start.
- var/alien = 0 //Used for reagent metabolism.
/mob/living/carbon/monkey/tajara
name = "farwa"
@@ -98,15 +97,6 @@
greaterform = "Tajaran"
add_language("Siik'tajr")
-/mob/living/carbon/monkey/diona/New()
-
- ..()
- alien = 1
- gender = NEUTER
- dna.mutantrace = "plant"
- greaterform = "Diona"
- add_language("Rootspeak")
-
/mob/living/carbon/monkey/movement_delay()
var/tally = 0
if(reagents)
@@ -301,78 +291,7 @@
O.show_message(text("\red [] has disarmed [name]!", M), 1)
return
-/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if (istype(loc, /turf) && istype(loc.loc, /area/start))
- M << "No attacking people at spawn, you jackass."
- return
-
- switch(M.a_intent)
- if ("help")
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
-
- if ("hurt")
- if ((prob(95) && health > 0))
- playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
- var/damage = rand(15, 30)
- if (damage >= 25)
- damage = rand(20, 40)
- if (paralysis < 15)
- Paralyse(rand(10, 15))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has wounded [name]!", M), 1)
- else
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has slashed [name]!", M), 1)
- adjustBruteLoss(damage)
- updatehealth()
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attempted to lunge at [name]!", M), 1)
-
- if ("grab")
- if (M == src)
- return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
-
- M.put_in_active_hand(G)
-
- grabbed_by += G
- G.synch()
-
- LAssailant = M
-
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
-
- if ("disarm")
- playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
- var/damage = 5
- if(prob(95))
- Weaken(15)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has tackled down [name]!", M), 1)
- else
- drop_item()
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has disarmed [name]!", M), 1)
- adjustBruteLoss(damage)
- updatehealth()
- return
-
-/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M as mob)
+/mob/living/carbon/monkey/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
diff --git a/code/modules/mob/living/carbon/monkey/powers.dm b/code/modules/mob/living/carbon/monkey/powers.dm
deleted file mode 100644
index e7c6937cda..0000000000
--- a/code/modules/mob/living/carbon/monkey/powers.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/mob/living/carbon/monkey/verb/ventcrawl()
- set name = "Crawl through Vent"
- set desc = "Enter an air vent and crawl through the pipe system."
- set category = "Monkey"
- handle_ventcrawl()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index a4e5e0586f..8fc440c921 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1,4 +1,3 @@
-
/mob/living/verb/succumb()
set hidden = 1
if ((src.health < 0 && src.health > -95.0))
@@ -611,7 +610,7 @@
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.
+ if(HULK in usr.mutations) //Don't want to do a lot of logic gating here.
usr << "\red You attempt to break your handcuffs. (This will take around 5 seconds and you need to stand still)"
for(var/mob/O in viewers(CM))
O.show_message(text("\red [] is trying to break the handcuffs!", CM), 1)
@@ -648,7 +647,7 @@
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.
+ if(HULK in usr.mutations) //Don't want to do a lot of logic gating here.
usr << "\red You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)"
for(var/mob/O in viewers(CM))
O.show_message(text("\red [] is trying to break the legcuffs!", CM), 1)
@@ -699,6 +698,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."
@@ -784,6 +788,9 @@
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
+/mob/living/proc/can_use_vents()
+ return "You can't fit into that vent."
+
/mob/living/proc/has_brain()
return 1
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 312bccff0f..1ac5faa11f 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -38,3 +38,11 @@
var/tod = null // Time of death
var/update_slimes = 1
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
\ No newline at end of file
diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm
new file mode 100644
index 0000000000..d2a8e35320
--- /dev/null
+++ b/code/modules/mob/living/living_powers.dm
@@ -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.")
\ No newline at end of file
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 95dd82aafe..f778e46209 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -9,12 +9,8 @@ var/list/department_radio_keys = list(
":e" = "Engineering", "#e" = "Engineering", ".e" = "Engineering",
":s" = "Security", "#s" = "Security", ".s" = "Security",
":w" = "whisper", "#w" = "whisper", ".w" = "whisper",
- ":b" = "binary", "#b" = "binary", ".b" = "binary",
- ":a" = "alientalk", "#a" = "alientalk", ".a" = "alientalk",
":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate",
":u" = "Supply", "#u" = "Supply", ".u" = "Supply",
- ":g" = "changeling", "#g" = "changeling", ".g" = "changeling",
- ":d" = "dronechat", "#d" = "dronechat", ".d" = "dronechat",
":R" = "right ear", "#R" = "right ear", ".R" = "right ear",
":L" = "left ear", "#L" = "left ear", ".L" = "left ear",
@@ -26,12 +22,8 @@ var/list/department_radio_keys = list(
":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering",
":S" = "Security", "#S" = "Security", ".S" = "Security",
":W" = "whisper", "#W" = "whisper", ".W" = "whisper",
- ":B" = "binary", "#B" = "binary", ".B" = "binary",
- ":A" = "alientalk", "#A" = "alientalk", ".A" = "alientalk",
":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate",
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
- ":G" = "changeling", "#G" = "changeling", ".G" = "changeling",
- ":D" = "dronechat", "#D" = "dronechat", ".D" = "dronechat",
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
@@ -45,33 +37,18 @@ var/list/department_radio_keys = list(
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
":û" = "Security", "#û" = "Security", ".û" = "Security",
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
- ":è" = "binary", "#è" = "binary", ".è" = "binary",
- ":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk",
":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate",
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
- ":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling"
)
/mob/living/proc/binarycheck()
+
if (istype(src, /mob/living/silicon/pai))
return
- if (issilicon(src))
- return 1
+
if (!ishuman(src))
return
- var/mob/living/carbon/human/H = src
- if (H.l_ear || H.r_ear)
- var/obj/item/device/radio/headset/dongle
- if(istype(H.l_ear,/obj/item/device/radio/headset))
- dongle = H.l_ear
- else
- dongle = H.r_ear
- if(!istype(dongle)) return
- if(dongle.translate_binary) return 1
-/mob/living/proc/hivecheck()
- if (isalien(src)) return 1
- if (!ishuman(src)) return
var/mob/living/carbon/human/H = src
if (H.l_ear || H.r_ear)
var/obj/item/device/radio/headset/dongle
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 1fd5dff535..c84c5b4355 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -511,41 +511,7 @@ var/list/ai_verbs_default = list(
updatehealth()
return 2
-/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if (istype(loc, /turf) && istype(loc.loc, /area/start))
- M << "No attacking people at spawn, you jackass."
- return
-
- switch(M.a_intent)
-
- if ("help")
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src]'s plating with its scythe like arm."), 1)
-
- else //harm
- var/damage = rand(10, 20)
- if (prob(90))
- playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has slashed at []!", M, src), 1)
- if(prob(8))
- flick("noise", flash)
- adjustBruteLoss(damage)
- updatehealth()
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] took a swipe at []!", M, src), 1)
- return
-
-/mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M as mob)
+/mob/living/silicon/ai/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 6015ab1302..6c6904e310 100755
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -3,7 +3,6 @@
icon = 'icons/mob/pai.dmi'
icon_state = "repairbot"
- robot_talk_understand = 0
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
small = 1
pass_flags = 1
@@ -204,40 +203,6 @@
//mob/living/silicon/pai/bullet_act(var/obj/item/projectile/Proj)
-/mob/living/silicon/pai/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(src.loc, /turf) && istype(src.loc.loc, /area/start))
- M << "You cannot attack someone in the spawn area."
- return
-
- switch(M.a_intent)
-
- if ("help")
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src]'s casing with its scythe like arm."), 1)
-
- else //harm
- var/damage = rand(10, 20)
- if (prob(90))
- playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has slashed at []!", M, src), 1)
- if(prob(8))
- flick("noise", src.flash)
- src.adjustBruteLoss(damage)
- src.updatehealth()
- else
- playsound(src.loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] took a swipe at []!", M, src), 1)
- return
-
///mob/living/silicon/pai/attack_hand(mob/living/carbon/M as mob)
/mob/living/silicon/pai/proc/switchCamera(var/obj/machinery/camera/C)
@@ -470,4 +435,8 @@
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\nIt is [pose]"
- usr << msg
\ No newline at end of file
+ usr << msg
+
+// No binary for pAIs.
+/mob/living/silicon/pai/binarycheck()
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index be9a36c819..cdca3b18ef 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -13,6 +13,8 @@
lawupdate = 0
density = 1
req_access = list(access_engine, access_robotics)
+ integrated_light_power = 2
+ local_transmit = 1
// We need to keep track of a few module items so we don't need to do list operations
// every time we need them. These get set in New() after the module is chosen.
@@ -30,6 +32,13 @@
..()
+ verbs += /mob/living/proc/ventcrawl
+ verbs += /mob/living/proc/hide
+
+ remove_language("Robot Talk")
+ add_language("Robot Talk", 0)
+ add_language("Drone Talk", 1)
+
if(camera && "Robots" in camera.network)
camera.network.Add("Engineering")
@@ -87,57 +96,6 @@
/mob/living/silicon/robot/drone/pick_module()
return
-//Drones can only use binary and say emotes. NOTHING else.
-//TBD, fix up boilerplate. ~ Z
-/mob/living/silicon/robot/drone/say(var/message)
-
- if (!message)
- return
-
- if (src.client)
- if(client.prefs.muted & MUTE_IC)
- src << "You cannot send IC messages (muted)."
- return
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return
-
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
-
- if (stat == 2)
- return say_dead(message)
-
- if(copytext(message,1,2) == "*")
- return emote(copytext(message,2))
- else if(length(message) >= 2)
-
- if(parse_message_mode(message, "NONE") == "dronechat")
-
- if(!is_component_functioning("radio"))
- src << "\red Your radio transmitter isn't functional."
- return
-
- for (var/mob/living/S in living_mob_list)
- if(istype(S, /mob/living/silicon/robot/drone))
- S << "Drone Talk, [name] transmits, \"[trim(copytext(message,3))]\""
-
- for (var/mob/M in dead_mob_list)
- if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain))
- M << "Drone Talk, [name] transmits, \"[trim(copytext(message,3))]\""
-
- else
-
- var/list/listeners = hearers(5,src)
- listeners |= src
-
- for(var/mob/living/silicon/robot/drone/D in listeners)
- if(D.client) D << "[src] transmits, \"[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)
- if(M.client) M << "[src] transmits, \"[message]\""
-
//Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..().
/mob/living/silicon/robot/drone/attackby(obj/item/weapon/W as obj, mob/user as mob)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
index 2c45af24d1..bac16de92e 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
@@ -21,28 +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."
- set category = "Drone"
-
- if(luminosity)
- SetLuminosity(0)
- return
- SetLuminosity(2)
-
//Actual picking-up event.
/mob/living/silicon/robot/drone/attack_hand(mob/living/carbon/human/M as mob)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
index 94a9e138e9..50806f0da2 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -80,14 +80,14 @@
wrapped = thing
break
- if(wrapped) //Already have an item.
-
+ if(wrapped) //Already have an item.
+
//Temporary put wrapped into user so target's attackby() checks pass.
wrapped.loc = user
-
+
//Pass the attack on to the target. This might delete/relocate wrapped.
target.attackby(wrapped,user)
-
+
//If wrapped did neither get deleted nor put into target, put it back into the gripper.
if(wrapped && user && (wrapped.loc == user))
wrapped.loc = src
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index a39f27022c..667aeb186d 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -19,6 +19,7 @@ var/list/robot_verbs_default = list(
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
var/crisis //Admin-settable for combat module use.
var/crisis_override = 0
+ var/integrated_light_power = 5
//Hud stuff
@@ -79,6 +80,8 @@ var/list/robot_verbs_default = list(
spark_system.set_up(5, 0, src)
spark_system.attach(src)
+ add_language("Robot Talk", 1)
+
ident = rand(1, 999)
updatename("Default")
updateicon()
@@ -846,72 +849,6 @@ var/list/robot_verbs_default = list(
spark_system.start()
return ..()
-/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- if (istype(loc, /turf) && istype(loc.loc, /area/start))
- M << "No attacking people at spawn, you jackass."
- return
-
- switch(M.a_intent)
-
- if ("help")
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src]'s plating with its scythe-like arm."), 1)
-
- if ("grab")
- if (M == src)
- return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
-
- M.put_in_active_hand(G)
-
- grabbed_by += G
- G.synch()
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
-
- if ("hurt")
- var/damage = rand(10, 20)
- if (prob(90))
-
- playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\red [] has slashed at []!", M, src), 1)
- if(prob(8))
- flick("noise", flash)
- adjustBruteLoss(damage)
- updatehealth()
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] took a swipe at []!", M, src), 1)
-
- if ("disarm")
- if(!(lying))
- if (rand(1,100) <= 85)
- Stun(7)
- step(src,get_dir(M,src))
- spawn(5) step(src,get_dir(M,src))
- playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has forced back []!", M, src), 1)
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] attempted to force back []!", M, src), 1)
- return
-
-
-
/mob/living/silicon/robot/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
@@ -970,7 +907,7 @@ var/list/robot_verbs_default = list(
return
-/mob/living/silicon/robot/attack_animal(mob/living/simple_animal/M as mob)
+/mob/living/silicon/robot/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
@@ -1337,7 +1274,6 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/remove_robot_verbs()
src.verbs -= robot_verbs_default
-
// Uses power from cyborg's cell. Returns 1 on success or 0 on failure.
// Properly converts using CELLRATE now! Amount is in Joules.
/mob/living/silicon/robot/proc/cell_use_power(var/amount = 0)
@@ -1352,4 +1288,11 @@ var/list/robot_verbs_default = list(
if(cell.use(amount * CELLRATE * CYBORG_POWER_USAGE_MULTIPLIER))
used_power_this_tick += amount * CYBORG_POWER_USAGE_MULTIPLIER
return 1
- return 0
+ return 0
+
+/mob/living/silicon/robot/binarycheck()
+ if(is_component_functioning("comms"))
+ var/datum/robot_component/RC = get_component("comms")
+ use_power(RC.active_usage)
+ return 1
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot_powers.dm b/code/modules/mob/living/silicon/robot/robot_powers.dm
new file mode 100644
index 0000000000..f51af52b18
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/robot_powers.dm
@@ -0,0 +1,9 @@
+/mob/living/silicon/robot/verb/light()
+ set name = "Light On/Off"
+ set desc = "Activate your inbuilt light. Toggled on or off."
+ set category = "Robot Commands"
+
+ if(luminosity)
+ SetLuminosity(0)
+ return
+ SetLuminosity(integrated_light_power)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index c979eec0dc..7f04c7b3ee 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -54,7 +54,6 @@
var/mob/living/silicon/robot/R = src
var/mob/living/silicon/pai/P = src
-
//Must be concious to speak
if (stat)
return
@@ -69,21 +68,35 @@
else
message = trim(copytext(message,3))
- if(message_mode && bot_type == IS_ROBOT && message_mode != "binary" && !R.is_component_functioning("radio"))
- src << "\red Your radio isn't functional at this time."
- return
- if(bot_type == IS_ROBOT && message_mode != "binary")
- var/datum/robot_component/radio/RA = R.get_component("radio")
- if (!R.cell_use_power(RA.active_usage))
- usr << "\red Not enough power to transmit message."
- return
-
//parse language key and consume it
var/datum/language/speaking = parse_language(message)
if (speaking)
verb = speaking.speech_verb
message = copytext(message,3)
+ if(speaking.flags & HIVEMIND)
+ speaking.broadcast(src,trim(message))
+ return
+
+ // Currently used by drones.
+ if(local_transmit)
+ var/list/listeners = hearers(5,src)
+ listeners |= src
+
+ for(var/mob/living/silicon/D in listeners)
+ if(D.client && istype(D,src.type))
+ D << "[src] transmits, \"[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)
+ if(M.client) M << "[src] transmits, \"[message]\""
+ return
+
+ if(message_mode && bot_type == IS_ROBOT && !R.is_component_functioning("radio"))
+ src << "\red Your radio isn't functional at this time."
+ return
switch(message_mode)
if("department")
@@ -98,21 +111,6 @@
P.radio.talk_into(src,message,message_mode,verb,speaking)
return 1
- if("binary")
- switch(bot_type)
- if(IS_ROBOT)
- if(!R.is_component_functioning("comms"))
- src << "\red Your binary communications component isn't functional."
- return
- var/datum/robot_component/binary_communication/B = R.get_component("comms")
- if(!R.cell_use_power(B.active_usage))
- src << "\red Not enough power to transmit message."
- return
- if(IS_PAI)
- src << "You do not appear to have that function"
- return
-
- robot_talk(message)
return 1
if("general")
switch(bot_type)
@@ -185,64 +183,6 @@
return
return 1
-/mob/living/proc/robot_talk(var/message)
-
- log_say("[key_name(src)] : [message]")
-
- message = trim(message)
-
- if (!message)
- return
-
- var/verb = say_quote(message)
-
-
- var/rendered = "Robotic Talk, [name] [verb], \"[message]\""
-
- for (var/mob/living/S in living_mob_list)
- if(S.robot_talk_understand && (S.robot_talk_understand == robot_talk_understand)) // This SHOULD catch everything caught by the one below, but I'm not going to change it.
- if(istype(S , /mob/living/silicon/ai))
- var/renderedAI = "Robotic Talk, [name] [verb], \"[message]\""
- S.show_message(renderedAI, 2)
- else
- var/mob/living/silicon/robot/borg = S
- if(istype(borg) && borg.is_component_functioning("comms"))
- var/datum/robot_component/RC = borg.get_component("comms")
- if(!borg.use_power(RC.active_usage))
- continue // No power.
- S.show_message(rendered, 2)
-
-
- else if (S.binarycheck())
- if(istype(S , /mob/living/silicon/ai))
- var/renderedAI = "Robotic Talk, [name] [verb], \"[message]\""
- S.show_message(renderedAI, 2)
- else
- S.show_message(rendered, 2)
-
- var/list/listening = hearers(1, src)
- listening -= src
-
- var/list/heard = list()
- for (var/mob/M in listening)
- if(!istype(M, /mob/living/silicon) && !M.robot_talk_understand)
- heard += M
- if (length(heard))
- var/message_beep
- verb = "beeps"
- message_beep = "beep beep beep"
-
- rendered = "[voice_name] [verb], \"[message_beep]\""
-
- for (var/mob/M in heard)
- M.show_message(rendered, 2)
-
- rendered = "Robotic Talk, [name] [verb], \"[message]\""
-
- 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(rendered, 2)
-
#undef IS_AI
#undef IS_ROBOT
#undef IS_PAI
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 6f0778a056..692609afb8 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -1,6 +1,5 @@
/mob/living/silicon
gender = NEUTER
- robot_talk_understand = 1
voice_name = "synthesized voice"
var/syndicate = 0
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
@@ -14,6 +13,7 @@
var/speak_query = "queries"
var/pose //Yes, now AIs can pose too.
var/obj/item/device/camera/siliconcam/aiCamera = null //photography
+ var/local_transmit //If set, can only speak to others of the same type within a short range.
var/sensor_mode = 0 //Determines the current HUD.
#define SEC_HUD 1 //Security HUD mode
@@ -214,4 +214,7 @@
set desc = "Sets an extended description of your character's features."
set category = "IC"
- flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1)
\ No newline at end of file
+ flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1)
+
+/mob/living/silicon/binarycheck()
+ return 1
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/borer.dm b/code/modules/mob/living/simple_animal/borer.dm
deleted file mode 100644
index f377a846c6..0000000000
--- a/code/modules/mob/living/simple_animal/borer.dm
+++ /dev/null
@@ -1,580 +0,0 @@
-/datum/game_mode/var/list/borers = list()
-
-/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
-
-/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/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/New()
- ..()
- truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]"
- if(!roundstart) request_player()
-
-/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))
-
- if (copytext(message, 1, 2) == ";") //Brain borer hivemind.
- return borer_speak(message)
-
- 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]\""
-
-/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)
-
-// VERBS!
-
-/mob/living/simple_animal/borer/proc/borer_speak(var/message)
- if(!message)
- return
-
- for(var/mob/M in mob_list)
- if(M.mind && (istype(M, /mob/living/simple_animal/borer) || istype(M, /mob/dead/observer)))
- M << "Cortical link, [truename]: [copytext(message, 2)]"
-
-/mob/living/simple_animal/borer/verb/dominate_victim()
- set category = "Alien"
- 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 = "Alien"
- 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 You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system."
- host << "\red You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours."
-
- // 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/simple_animal/borer/verb/secrete_chemicals()
- set category = "Alien"
- 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 You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream."
- host.reagents.add_reagent(chem, 10)
- chemicals -= 50
-
-/mob/living/simple_animal/borer/verb/release_host()
- set category = "Alien"
- 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.stat)
- host << "Something slimy wiggles out of your ear and plops to the ground!"
-
- detatch()
- leave_host()
-
-/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.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
-
- 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
-
-/mob/living/simple_animal/borer/verb/infest()
- set category = "Alien"
- 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(C.stat != 2 && 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.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.stat == 2)
- src << "That is not an appropriate target."
- 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.loc = M
-
- if(istype(M,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- var/datum/organ/external/head = H.get_organ("head")
- head.implants += src
-
- host.status_flags |= PASSEMOTES
-
- return
- else
- src << "They are no longer in range!"
- return
-
-/mob/living/simple_animal/borer/verb/ventcrawl()
- set name = "Crawl through Vent"
- set desc = "Enter an air vent and crawl through the pipe system."
- set category = "Alien"
-
-// 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/borer/verb/hide()
- set name = "Hide"
- set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
- set category = "Alien"
-
- 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.")
-
-//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"
diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm
new file mode 100644
index 0000000000..2cfdc1f8c4
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/borer/borer.dm
@@ -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 << "You are no longer an antagonist."
+ 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/carbon/alien/can_use_vents()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm
new file mode 100644
index 0000000000..808a2199f1
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/borer/borer_captive.dm
@@ -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
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm
new file mode 100644
index 0000000000..9f47dd6cf4
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm
@@ -0,0 +1,348 @@
+/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 << "Something slimy wiggles out of your ear and plops to the ground!"
+ host << "As though waking from a dream, you shake off the insidious mind control of the brain worm. Your thoughts are your own again."
+
+ 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 << "A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine."
+ host << "You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head."
+ 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 << "It only takes a few moments to render the dead host brain down into a nutrient-rich slurry..."
+ 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 << "You settle into the empty brainpan and begin to expand, fusing inextricably with the dead flesh of [H]."
+
+ 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/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 You squirt a measure of [chem] from your reservoirs into [host]'s bloodstream."
+ 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 You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system."
+ host << "\red You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours."
+ 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("With a hideous, rattling moan, [src] shudders back to life!")
+
+ rejuvenate()
+ vessel.add_reagent("blood",560-vessel.total_volume)
+ fixblood()
+ update_canmove()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm
new file mode 100644
index 0000000000..c0bfb0711f
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/borer/say.dm
@@ -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]\""
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 48dc61b08e..d3aa156ea4 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -88,7 +88,7 @@
now_pushing = null
-/mob/living/simple_animal/construct/attack_animal(mob/living/simple_animal/M as mob)
+/mob/living/simple_animal/construct/attack_animal(mob/living/M as mob)
if(istype(M, /mob/living/simple_animal/construct/builder))
health += 5
M.emote("mends some of \the [src]'s wounds.")
diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm
index 5a13dccc49..4f5eda2af9 100644
--- a/code/modules/mob/living/simple_animal/friendly/mouse.dm
+++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm
@@ -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("[] scurries to the ground!", 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 << "You are too small to pull anything."
return
@@ -163,3 +113,6 @@
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "splats"
+
+/mob/living/carbon/alien/can_use_vents()
+ return
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
index 1c489f4902..4c95c54c7b 100644
--- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm
@@ -215,67 +215,7 @@
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()
set name = "Drop held item"
set category = "Spiderbot"
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 5740e51b1e..000b125673 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -135,8 +135,8 @@
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return
- //Is the usr's mob type able to do this? (lolaliens)
- if(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))
+ //Is the usr's mob type able to do this?
+ if(ishuman(usr) || ismonkey(usr) || isrobot(usr))
//Removing from inventory
if(href_list["remove_inv"])
@@ -235,11 +235,8 @@
/mob/living/simple_animal/parrot/attack_paw(mob/living/carbon/monkey/M as mob)
attack_hand(M)
-/mob/living/simple_animal/parrot/attack_alien(mob/living/carbon/monkey/M as mob)
- attack_hand(M)
-
//Simple animals
-/mob/living/simple_animal/parrot/attack_animal(mob/living/simple_animal/M as mob)
+/mob/living/simple_animal/parrot/attack_animal(mob/living/M as mob)
if(client) return
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index e5f9136362..b9e6e714dd 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -44,17 +44,14 @@
var/min_n2 = 0
var/max_n2 = 0
var/unsuitable_atoms_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
-
+ var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
//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
-
- var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
+ 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
/mob/living/simple_animal/New()
..()
@@ -212,7 +209,7 @@
if(act == "scream") act = "whimper" //ugly hack to stop animals screaming when crushed :P
..(act, type, desc)
-/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M as mob)
+/mob/living/simple_animal/attack_animal(mob/living/M as mob)
if(M.melee_damage_upper == 0)
M.emote("[M.friendly] [src]")
else
@@ -228,7 +225,7 @@
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
if(!Proj || Proj.nodamage)
return
-
+
adjustBruteLoss(Proj.damage)
return 0
@@ -270,59 +267,6 @@
return
-/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
-
- switch(M.a_intent)
-
- if ("help")
-
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
- if ("grab")
- if(M == src)
- return
- if(!(status_flags & CANPUSH))
- 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()
- G.affecting = src
- LAssailant = M
-
- playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
-
- if("hurt", "disarm")
- var/damage = rand(15, 30)
- visible_message("\red [M] has slashed at [src]!")
- adjustBruteLoss(damage)
-
- return
-
-/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L as mob)
-
- switch(L.a_intent)
- if("help")
- visible_message("\blue [L] rubs it's head against [src]")
-
-
- else
-
- var/damage = rand(5, 10)
- visible_message("\red [L] bites [src]!")
-
- if(stat != DEAD)
- adjustBruteLoss(damage)
- L.amount_grown = min(L.amount_grown + damage, L.max_grown)
-
-
/mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M as mob)
if (!ticker)
M << "You cannot attack people before the game has started."
@@ -461,4 +405,4 @@
message = capitalize(trim_left(message))
- ..(message, null, verb)
+ ..(message, null, verb)
\ No newline at end of file
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index bf5be72fc4..4b9d28402c 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -45,15 +45,4 @@
client.eye = src
client.perspective = MOB_PERSPECTIVE
- //Clear ability list and update from mob.
- client.verbs -= ability_verbs
-
- if(abilities)
- client.verbs |= abilities
-
- if(istype(src,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- if(H.species && H.species.abilities)
- client.verbs |= H.species.abilities
-
nanomanager.send_resources(client)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 86f3724fb5..ca3a2b8551 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -88,7 +88,6 @@
var/list/pinned = list() // List of things pinning this creature to walls (see living_defense.dm)
var/list/embedded = list() // Embedded items, since simple mobs don't have organs.
var/list/languages = list() // For speaking/listening.
- var/list/abilities = list() // For species-derived or admin-given powers.
var/list/speak_emote = list("says") // Verbs used when speaking. Defaults to 'say' if speak_emote is null.
var/emote_type = 1 // Define emote default type, 1 for seen emotes, 2 for heard emotes
@@ -97,7 +96,6 @@
var/timeofdeath = 0.0//Living
var/cpr_time = 1.0//Carbon
-
var/bodytemperature = 310.055 //98.7 F
var/drowsyness = 0.0//Carbon
var/dizziness = 0//Carbon
@@ -210,8 +208,6 @@
//Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything.
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
var/universal_understand = 0 // Set to 1 to enable the mob to understand everyone, not necessarily speak
- var/robot_talk_understand = 0
- var/alien_talk_understand = 0
var/has_limbs = 1 //Whether this mob have any limbs he can move with
var/can_stand = 1 //Whether this mob have ability to stand
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index a95f8612c1..ad8915f5e3 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -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("[user] is attempting to devour [affecting]!")
- 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
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 93cca72284..51676ca04f 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -5,6 +5,11 @@
return 1
return 0
+/proc/isalien(A)
+ if(istype(A, /mob/living/carbon/alien))
+ return 1
+ return 0
+
/proc/ismonkey(A)
if(A && istype(A, /mob/living/carbon/monkey))
return 1
@@ -15,21 +20,6 @@
return 1
return 0
-/proc/isalien(A)
- if(istype(A, /mob/living/carbon/alien))
- return 1
- return 0
-
-/proc/isalienadult(A)
- if(istype(A, /mob/living/carbon/alien/humanoid))
- return 1
- return 0
-
-/proc/islarva(A)
- if(istype(A, /mob/living/carbon/alien/larva))
- return 1
- return 0
-
/proc/isslime(A)
if(istype(A, /mob/living/carbon/slime))
return 1
@@ -189,7 +179,7 @@ var/list/global/organ_rel_size = list(
var/ran_zone = zone
while (ran_zone == zone)
- ran_zone = pick (
+ ran_zone = pick (
organ_rel_size["head"]; "head",
organ_rel_size["chest"]; "chest",
organ_rel_size["groin"]; "groin",
@@ -202,7 +192,7 @@ var/list/global/organ_rel_size = list(
organ_rel_size["l_foot"]; "l_foot",
organ_rel_size["r_foot"]; "r_foot",
)
-
+
return ran_zone
// Emulates targetting a specific body part, and miss chances
@@ -399,7 +389,7 @@ var/list/intents = list("help","disarm","grab","hurt")
set name = "a-intent"
set hidden = 1
- if(ishuman(src) || isalienadult(src) || isbrain(src))
+ if(ishuman(src) || isbrain(src))
switch(input)
if("help","disarm","grab","hurt")
a_intent = input
@@ -410,7 +400,7 @@ var/list/intents = list("help","disarm","grab","hurt")
if(hud_used && hud_used.action_intent)
hud_used.action_intent.icon_state = "intent_[a_intent]"
- else if(isrobot(src) || ismonkey(src) || islarva(src))
+ else if(isrobot(src) || ismonkey(src))
switch(input)
if("help")
a_intent = "help"
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 6d5e308c7a..27ecfcc87e 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -90,8 +90,6 @@
return 1
if (istype(other, src.type) || istype(src, other.type))
return 1
- if(src.alien_talk_understand && other.alien_talk_understand)
- return 1
return 0
//Language check.
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 2307d00bcb..77ec2c1305 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -197,14 +197,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
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm
new file mode 100644
index 0000000000..5d1d487423
--- /dev/null
+++ b/code/modules/organs/organ_alien.dm
@@ -0,0 +1,164 @@
+//DIONA ORGANS.
+/datum/organ/internal/diona
+ removed_type = /obj/item/organ/diona
+
+/datum/organ/internal/diona/process()
+ return
+
+/datum/organ/internal/diona/nutrients
+ name = "nutrient vessel"
+ parent_organ = "chest"
+
+/datum/organ/internal/diona/strata
+ name = "neural strata"
+ parent_organ = "chest"
+
+/datum/organ/internal/diona/node
+ name = "receptor node"
+ parent_organ = "head"
+
+/datum/organ/internal/diona/bladder
+ name = "gas bladder"
+ parent_organ = "head"
+
+/datum/organ/internal/diona/polyp
+ name = "polyp segment"
+ parent_organ = "groin"
+
+/datum/organ/internal/diona/ligament
+ name = "anchoring ligament"
+ parent_organ = "groin"
+
+/obj/item/organ/diona
+ name = "diona nymph"
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "nymph"
+
+/obj/item/organ/diona/removed(var/mob/living/target,var/mob/living/user)
+
+ var/mob/living/carbon/human/H = target
+ if(!istype(target))
+ del(src)
+
+ if(!H.internal_organs.len)
+ H.death()
+
+ //This is a terrible hack and I should be ashamed.
+ var/datum/seed/diona = seed_types["diona"]
+ if(!diona)
+ del(src)
+
+ var/mob/living/carbon/alien/diona/D = new(get_turf(src))
+ diona.request_player(D)
+
+ del(src)
+
+//CORTICAL BORER ORGANS.
+/datum/organ/internal/borer
+ name = "cortical borer"
+ parent_organ = "head"
+ removed_type = /obj/item/organ/borer
+ vital = 1
+
+/datum/organ/internal/borer/process()
+
+ // Borer husks regenerate health, feel no pain, and are resistant to stuns and brainloss.
+ for(var/chem in list("tricordrazine","tramadol","hyperzine","alkysine"))
+ if(owner.reagents.get_reagent_amount(chem) < 3)
+ owner.reagents.add_reagent(chem, 5)
+
+ // They're also super gross and ooze ichor.
+ if(prob(5))
+ var/obj/effect/decal/cleanable/blood/splatter/goo = new(get_turf(owner))
+ goo.name = "husk ichor"
+ goo.desc = "It's thick and stinks of decay."
+ goo.basecolor = "#412464"
+ goo.update_icon()
+
+/obj/item/organ/borer
+ name = "cortical borer"
+ icon = 'icons/obj/objects.dmi'
+ icon_state = "borer"
+ organ_tag = "brain"
+ desc = "A disgusting space slug."
+
+/obj/item/organ/borer/removed(var/mob/living/target,var/mob/living/user)
+
+
+ ..()
+
+ var/mob/living/simple_animal/borer/B = target.has_brain_worms()
+ if(B)
+ B.leave_host()
+ B.ckey = target.ckey
+
+ spawn(0)
+ del(src)
+
+//XENOMORPH ORGANS
+/datum/organ/internal/xenos/eggsac
+ name = "egg sac"
+ parent_organ = "groin"
+ removed_type = /obj/item/organ/xenos/eggsac
+
+/datum/organ/internal/xenos/plasmavessel
+ name = "plasma vessel"
+ parent_organ = "chest"
+ removed_type = /obj/item/organ/xenos/plasmavessel
+ var/stored_plasma = 0
+ var/max_plasma = 500
+
+/datum/organ/internal/xenos/plasmavessel/queen
+ name = "bloated plasma vessel"
+ stored_plasma = 200
+ max_plasma = 500
+
+/datum/organ/internal/xenos/plasmavessel/sentinel
+ stored_plasma = 100
+ max_plasma = 250
+
+/datum/organ/internal/xenos/plasmavessel/hunter
+ name = "tiny plasma vessel"
+ stored_plasma = 100
+ max_plasma = 150
+
+/datum/organ/internal/xenos/acidgland
+ name = "acid gland"
+ parent_organ = "head"
+ removed_type = /obj/item/organ/xenos/acidgland
+
+/datum/organ/internal/xenos/hivenode
+ name = "hive node"
+ parent_organ = "chest"
+ removed_type = /obj/item/organ/xenos/hivenode
+
+/datum/organ/internal/xenos/resinspinner
+ name = "resin spinner"
+ parent_organ = "head"
+ removed_type = /obj/item/organ/xenos/resinspinner
+
+/obj/item/organ/xenos
+ name = "xeno organ"
+ icon = 'icons/effects/blood.dmi'
+ desc = "It smells like an accident in a chemical factory."
+ organ_tag = "special" //TODO functionality for transplants.
+
+/obj/item/organ/xenos/eggsac
+ name = "egg sac"
+ icon_state = "xgibmid1"
+
+/obj/item/organ/xenos/plasmavessel
+ name = "plasma vessel"
+ icon_state = "xgibdown"
+
+/obj/item/organ/xenos/acidgland
+ name = "acid gland"
+ icon_state = "xgibtorso"
+
+/obj/item/organ/xenos/hivenode
+ name = "hive node"
+ icon_state = "xgibmid2"
+
+/obj/item/organ/xenos/resinspinner
+ name = "hive node"
+ icon_state = "xgibmid2"
\ No newline at end of file
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index e8c7acbfbf..9c26f814e9 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -2,7 +2,7 @@
INTERNAL ORGANS
****************************************************/
-/mob/living/carbon/human/var/list/internal_organs = list()
+/mob/living/carbon/var/list/internal_organs = list()
/datum/organ/internal
var/damage = 0 // amount of damage to the organ
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 64f53e5e55..e3b758e6b2 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -161,8 +161,6 @@
spawn(5)
src.update()
-
-
/obj/machinery/power/apc/proc/make_terminal()
// create a terminal object at the same position as original turf loc
// wires will attach to this
@@ -627,15 +625,16 @@
// attack with hand - remove cell (if cover open) or interact with the APC
/obj/machinery/power/apc/attack_hand(mob/user)
-// if (!can_use(user)) This already gets called in interact() and in topic()
-// return
+
if(!user)
return
+
src.add_fingerprint(user)
- //Synthetic human mob goes here.
+ //Human mob special interaction goes here.
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
+
if(H.species.flags & IS_SYNTHETIC && H.a_intent == "grab")
if(emagged || stat & BROKEN)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
@@ -663,6 +662,28 @@
else
user << "There is no charge to draw from that APC."
return
+ else if(H.species.can_shred(H))
+ user.visible_message("\red [user.name] slashes at the [src.name]!", "\blue You slash at the [src.name]!")
+ playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
+ var/allcut = 1
+ for(var/wire in apcwirelist)
+ if(!isWireCut(apcwirelist[wire]))
+ allcut = 0
+ break
+ if(beenhit >= pick(3, 4) && wiresexposed != 1)
+ wiresexposed = 1
+ src.update_icon()
+ src.visible_message("\red The [src.name]'s cover flies open, exposing the wires!")
+
+ else if(wiresexposed == 1 && allcut == 0)
+ for(var/wire in apcwirelist)
+ cut(apcwirelist[wire])
+ src.update_icon()
+ src.visible_message("\red The [src.name]'s wires are shredded!")
+ else
+ beenhit += 1
+ return
+
if(usr == user && opened && (!issilicon(user)))
if(cell)
@@ -683,32 +704,6 @@
//user.set_machine(src)
src.interact(user)
-/obj/machinery/power/apc/attack_alien(mob/living/carbon/alien/humanoid/user)
- if(!user)
- return
- user.visible_message("\red [user.name] slashes at the [src.name]!", "\blue You slash at the [src.name]!")
- playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
- var/allcut = 1
- for(var/wire in apcwirelist)
- if(!isWireCut(apcwirelist[wire]))
- allcut = 0
- break
- if(beenhit >= pick(3, 4) && wiresexposed != 1)
- wiresexposed = 1
- src.update_icon()
- src.visible_message("\red The [src.name]'s cover flies open, exposing the wires!")
-
- else if(wiresexposed == 1 && allcut == 0)
- for(var/wire in apcwirelist)
- cut(apcwirelist[wire])
- src.update_icon()
- src.visible_message("\red The [src.name]'s wires are shredded!")
- else
- beenhit += 1
- return
-
-
-
/obj/machinery/power/apc/interact(mob/user)
if(!user)
return
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 067b207d13..9f82dbec05 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -454,18 +454,7 @@
src.flicker(1)
return
-// Aliens smash the bulb but do not get electrocuted./N
-/obj/machinery/light/attack_alien(mob/living/carbon/alien/humanoid/user)//So larva don't go breaking light bulbs.
- if(status == LIGHT_EMPTY||status == LIGHT_BROKEN)
- user << "\green That object is useless to you."
- return
- else if (status == LIGHT_OK||status == LIGHT_BURNED)
- for(var/mob/M in viewers(src))
- M.show_message("\red [user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2)
- broken()
- return
-
-/obj/machinery/light/attack_animal(mob/living/simple_animal/M)
+/obj/machinery/light/attack_animal(mob/living/M)
if(M.melee_damage_upper == 0) return
if(status == LIGHT_EMPTY||status == LIGHT_BROKEN)
M << "\red That object is useless to you."
@@ -486,6 +475,14 @@
user << "There is no [fitting] in this light."
return
+ if(istype(user,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = user
+ if(H.species.can_shred(H))
+ for(var/mob/M in viewers(src))
+ M.show_message("\red [user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2)
+ broken()
+ return
+
// make it burn hands if not wearing fire-insulated gloves
if(on)
var/prot = 0
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index e6b49ec298..82936a1dc8 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -78,7 +78,7 @@
has_power = master_area.powered(power_channel)
else
has_power = powered(power_channel)
-
+
if(has_power)
stat &= ~NOPOWER
else
@@ -271,14 +271,17 @@
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb
-
- //This is for performance optimization only.
+
+ //This is for performance optimization only.
//DO NOT modify siemens_coeff here. That is checked in human/electrocute_act()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.gloves)
+ if(H.species.insulated)
+ return 0
+ else if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
- if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on
+ if(G.siemens_coefficient == 0)
+ return 0 //to avoid spamming with insulated glvoes on
var/area/source_area
if(istype(power_source,/area))
diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm
index fc88f6b519..72250fbf1a 100644
--- a/code/modules/projectiles/projectile/change.dm
+++ b/code/modules/projectiles/projectile/change.dm
@@ -53,11 +53,7 @@
new_mob.universal_speak = 1
if("xeno")
var/alien_caste = pick("Hunter","Sentinel","Drone","Larva")
- switch(alien_caste)
- if("Hunter") new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc)
- if("Sentinel") new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc)
- if("Drone") new_mob = new /mob/living/carbon/alien/humanoid/drone(M.loc)
- else new_mob = new /mob/living/carbon/alien/larva(M.loc)
+ new_mob = create_new_xenomorph(alien_caste,M.loc)
new_mob.universal_speak = 1
if("human")
new_mob = new /mob/living/carbon/human(M.loc, pick(all_species))
diff --git a/code/modules/surgery/slimes.dm b/code/modules/surgery/slimes.dm
index d962cfd3f4..048c6d3e3c 100644
--- a/code/modules/surgery/slimes.dm
+++ b/code/modules/surgery/slimes.dm
@@ -20,7 +20,7 @@
max_duration = 50
can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && target.core_removal_stage == 0
+ return ..() && istype(target) && target.core_removal_stage == 0
begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
user.visible_message("[user] starts cutting through [target]'s flesh with \the [tool].", \
@@ -46,7 +46,7 @@
max_duration = 50
can_use(mob/living/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
- return ..() && target.core_removal_stage == 1
+ return ..() && istype(target) && target.core_removal_stage == 1
begin_step(mob/user, mob/living/carbon/slime/target, target_zone, obj/item/tool)
user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \
diff --git a/code/setup.dm b/code/setup.dm
index cd455dda5b..fd44b399ca 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -741,27 +741,28 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define NO_BREATHE 2
#define NO_SCAN 4
#define NO_PAIN 8
+#define NO_SLIP 16
+#define NO_POISON 32
-#define HAS_SKIN_TONE 16
-#define HAS_SKIN_COLOR 32
-#define HAS_LIPS 64
-#define HAS_UNDERWEAR 128
-#define HAS_TAIL 256
+#define HAS_SKIN_TONE 64
+#define HAS_SKIN_COLOR 128
+#define HAS_LIPS 256
+#define HAS_UNDERWEAR 512
+#define HAS_TAIL 1024
-#define IS_SLOW 512
-#define IS_PLANT 1024
-#define IS_WHITELISTED 2048
+#define IS_PLANT 2048
+#define IS_WHITELISTED 4096
+#define IS_SYNTHETIC 8192
-#define RAD_ABSORB 4096
-#define REQUIRE_LIGHT 8192
-
-#define IS_SYNTHETIC 16384
+#define RAD_ABSORB 16384
+#define REQUIRE_LIGHT 32768
//Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
#define RESTRICTED 2 // Language can only be accquired by spawning or an admin.
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
+#define HIVEMIND 16 // Broadcast to all mobs with this language.
//Flags for zone sleeping
#define ZONE_ACTIVE 1
@@ -826,6 +827,7 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define IS_VOX 2
#define IS_SKRELL 3
#define IS_UNATHI 4
+#define IS_XENOS 5
#define MAX_GEAR_COST 5 //Used in chargen for loadout limit.
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 4d93845d98..2647e5a0d3 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -65,6 +65,7 @@ h1.alert, h2.alert {color: #000000;}
.tajaran_signlang {color: #941C1C;}
.skrell {color: #00CED1;}
.soghun {color: #228B22;}
+.changeling {color: #800080;}
.vox {color: #AA00AA;}
.rough {font-family: "Trebuchet MS", cursive, sans-serif;}
.say_quote {font-family: Georgia, Verdana, sans-serif;}
diff --git a/icons/effects/species.dmi b/icons/effects/species.dmi
index d5405066ab..4c1516b858 100644
Binary files a/icons/effects/species.dmi and b/icons/effects/species.dmi differ
diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi
index 36a6aa3368..24b09492de 100644
Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_drone.dmi b/icons/mob/human_races/xenos/r_xenos_drone.dmi
new file mode 100644
index 0000000000..19094d66ed
Binary files /dev/null and b/icons/mob/human_races/xenos/r_xenos_drone.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_hunter.dmi b/icons/mob/human_races/xenos/r_xenos_hunter.dmi
new file mode 100644
index 0000000000..ef1b3a6f4d
Binary files /dev/null and b/icons/mob/human_races/xenos/r_xenos_hunter.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_queen.dmi b/icons/mob/human_races/xenos/r_xenos_queen.dmi
new file mode 100644
index 0000000000..efb5558ac1
Binary files /dev/null and b/icons/mob/human_races/xenos/r_xenos_queen.dmi differ
diff --git a/icons/mob/human_races/xenos/r_xenos_sentinel.dmi b/icons/mob/human_races/xenos/r_xenos_sentinel.dmi
new file mode 100644
index 0000000000..5b250c7445
Binary files /dev/null and b/icons/mob/human_races/xenos/r_xenos_sentinel.dmi differ
diff --git a/icons/mob/monkey.dmi b/icons/mob/monkey.dmi
index b00b4a08fa..b9c1299ec2 100644
Binary files a/icons/mob/monkey.dmi and b/icons/mob/monkey.dmi differ
diff --git a/icons/mob/screen1_alien.dmi b/icons/mob/screen1_alien.dmi
index d42c521068..b21cd203dd 100644
Binary files a/icons/mob/screen1_alien.dmi and b/icons/mob/screen1_alien.dmi differ