diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm
index 7bafd4a31fc..448425e454d 100644
--- a/code/modules/detectivework/scanner.dm
+++ b/code/modules/detectivework/scanner.dm
@@ -34,9 +34,11 @@
attack(mob/living/carbon/human/M as mob, mob/user as mob)
if (!ishuman(M))
user << "\red [M] is not human and cannot have the fingerprints."
+ flick("forensic0",src)
return 0
if (( !( istype(M.dna, /datum/dna) ) || M.gloves) )
user << "\blue No fingerprints found on [M]"
+ flick("forensic0",src)
return 0
else
if (src.amount < 1)
@@ -71,6 +73,7 @@
return
if(istype(A,/obj/item/weapon/f_card))
user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\""
+ flick("forensic0",src)
return
add_fingerprint(user)
@@ -81,6 +84,7 @@
if(!isnull(A.blood_DNA))
for(var/blood in A.blood_DNA)
user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]"
+ flick("forensic2",src)
return
//General
@@ -88,10 +92,12 @@
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
"\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!",\
"You hear a faint hum of electrical equipment.")
+ flick("forensic0",src)
return 0
if(add_data(A))
user << "\blue Object already in internal memory. Consolidating data..."
+ flick("forensic2",src)
return
@@ -116,6 +122,7 @@
//FIBERS
if(A.suit_fibers)
user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve."
+ flick("forensic2",src)
//Blood
if (A.blood_DNA)
@@ -127,11 +134,13 @@
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
"You finish scanning \the [A].",\
"You hear a faint hum of electrical equipment.")
+ flick("forensic2",src)
return 0
else
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]\n[user.gender == MALE ? "He" : "She"] seems to perk up slightly at the readout." ,\
"The results of the scan pique your interest.",\
"You hear a faint hum of electrical equipment, and someone making a thoughtful noise.")
+ flick("forensic2",src)
return 0
return
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 05f4b222a8e..02fffec17b4 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1119,8 +1119,8 @@
del(feet_blood_DNA)
return 1
-mob/living/carbon/human/verb/yank_out_object()
- set category = "IC"
+mob/living/carbon/human/yank_out_object()
+ set category = "Object"
set name = "Yank out object"
set desc = "Remove an embedded item at the cost of bleeding and pain."
set src in view(1)
@@ -1137,89 +1137,62 @@ mob/living/carbon/human/verb/yank_out_object()
usr << "You are restrained and cannot do that!"
return
-// /*
var/list/valid_objects = list()
var/datum/organ/external/affected = null
var/mob/living/carbon/human/S = src
var/mob/living/carbon/human/U = usr
+ var/self = null
- if(S == U) // Removing something from yourself.
- valid_objects = get_visible_implants(1)
+ if(S == U)
+ self = 1 // Removing object from yourself.
- if(!valid_objects.len)
+ valid_objects = get_visible_implants(1)
+
+ if(!valid_objects.len)
+ if(self)
src << "You have nothing stuck in your wounds that is large enough to remove without surgery."
- return
-
- var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
-
- for(var/datum/organ/external/organ in organs) //Grab the organ holding the implant. Messy as Hell, TBD: fix.
- for(var/obj/item/weapon/O in organ.implants)
- if(O == selection)
- affected = organ
-
- src << "You attempt to get a good grip on the [selection] in your [affected] with bloody fingers."
- bloody_hands(S)
-
- if(!do_after(U, 80))
- return
-
- if(!selection || !affected || !S || !U)
- return
-
- visible_message("[src] rips [selection] out of their [affected] in a welter of blood.","You rip [selection] out of your [affected] in a welter of blood.")
- selection.loc = get_turf(src)
- affected.implants -= selection
- shock_stage+=10
-
- for(var/obj/item/weapon/O in pinned)
- if(O == selection)
- pinned -= O
- anchored = 0
-
- if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
- var/datum/wound/internal_bleeding/I = new (15)
- affected.wounds += I
- custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
- return 1
-
- else // Removing something from someone else.
- valid_objects = src.get_visible_implants(1)
-
- if(!valid_objects.len)
+ else
U << "[src] has nothing stuck in their wounds that is large enough to remove without surgery."
- return
+ return
- var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
-
- for(var/datum/organ/external/organ in src.organs) //Grab the organ holding the implant. Messy as Hell, TBD: fix.
- for(var/obj/item/weapon/O in organ.implants)
- if(O == selection)
- affected = organ
+ var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
+ for(var/datum/organ/external/organ in organs) //Grab the organ holding the implant.
+ for(var/obj/item/weapon/O in organ.implants)
+ if(O == selection)
+ affected = organ
+ if(self)
+ src << "You attempt to get a good grip on the [selection] in your [affected] with bloody fingers."
+ else
U << "You attempt to get a good grip on the [selection] in [S]'s [affected] with bloody fingers."
- U.bloody_hands(S)
- if(!do_after(U, 80))
- return
+ if(istype(U,/mob/living/carbon/human/)) U.bloody_hands(S)
+
+ if(!do_after(U, 80))
+ return
if(!selection || !affected || !S || !U)
return
-
+ if(self)
+ visible_message("[src] rips [selection] out of their [affected] in a welter of blood.","You rip [selection] out of your [affected] in a welter of blood.")
+ else
visible_message("[usr] rips [selection] out of [src]'s [affected] in a welter of blood.","[src] rips [selection] out of your [affected] in a welter of blood.")
- selection.loc = get_turf(usr)
- affected.implants -= selection
- src.shock_stage+=10
- for(var/obj/item/weapon/O in S.pinned)
- if(O == selection)
- S.pinned -= O
- S.anchored = 0
+ selection.loc = get_turf(src)
+ affected.implants -= selection
+ shock_stage+=10
- if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
- var/datum/wound/internal_bleeding/I = new (15)
- affected.wounds += I
- custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
- return 1
+ for(var/obj/item/weapon/O in pinned)
+ if(O == selection)
+ pinned -= O
+ if(!pinned.len)
+ anchored = 0
+
+ if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
+ var/datum/wound/internal_bleeding/I = new (15)
+ affected.wounds += I
+ custom_pain("Something tears wetly in your [affected] as [selection] is pulled free!", 1)
+ return 1
/mob/living/carbon/human/proc/get_visible_implants(var/class = 0)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index f7b2caecae3..4107b30d877 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -86,7 +86,7 @@
// Begin BS12 momentum-transfer code.
- if(speed > 20)
+ if(speed >= 20)
var/obj/item/weapon/W = O
var/momentum = speed/2
var/dir = get_dir(M,src)
@@ -96,8 +96,14 @@
if(near_wall(dir,2) && W.w_class >= 3 && W.sharp) //If they're close to a wall and the projectile is suitable.
visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!")
- src.anchored = 1
- src.pinned += O
+ if(!istype(src,/mob/living/carbon/human))
+ O.loc = src
+ src.embedded += O
+ src.anchored = 1
+ src.pinned += O
+ else
+ src.anchored = 1
+ src.pinned += O
/mob/living/proc/near_wall(var/direction,var/distance=1)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index f7154694f7e..74bd81ca934 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -96,7 +96,7 @@
AdjustParalysis(-1)
//Movement
- if(!client && !stop_automated_movement && wander)
+ if(!client && !stop_automated_movement && wander && !anchored)
if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
turns_since_move++
if(turns_since_move >= turns_per_move)
diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm
index e73249f2bc8..2ea43707ba8 100644
--- a/code/modules/mob/living/simple_animal/vox.dm
+++ b/code/modules/mob/living/simple_animal/vox.dm
@@ -8,7 +8,7 @@
icon_living = "armalis"
maxHealth = 500
health = 500
- response_harm = "flails ineffectually at the"
+ response_harm = "slashes at the"
harm_intent_damage = 0
melee_damage_lower = 30
melee_damage_upper = 40
@@ -17,6 +17,22 @@
wall_smash = 1
attack_sound = 'sound/weapons/bladeslice.ogg'
status_flags = 0
+ universal_speak = 1
+ vox_talk_understand = 1
+
+ var/armour = null
+ var/amp = null
+ var/quills = 3
+
+/mob/living/simple_animal/vox/armalis/Die()
+
+ living_mob_list -= src
+ dead_mob_list += src
+ stat = DEAD
+ visible_message("\red [src] shudders violently and explodes!","\red You feel your body rupture!")
+ explosion(get_turf(loc), -1, -1, 3, 5)
+ src.gib()
+ return
/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(O.force)
@@ -44,11 +60,102 @@
set desc = "Fires a viciously pointed quill at a high speed."
set category = "Alien"
+ if(quills<=0)
+ return
+
src << "\red You launch a razor-sharp quill at [target]!"
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
O << "\red [src] launches a razor-sharp quill at [target]!"
var/obj/item/weapon/arrow/quill/Q = new(loc)
- Q.fingerprintslast = src
- Q.throw_at(target,10,15)
\ No newline at end of file
+ Q.fingerprintslast = src.ckey
+ Q.throw_at(target,10,20)
+ quills--
+
+ spawn(100)
+ src << "\red You feel a fresh quill slide into place."
+ quills++
+
+/mob/living/simple_animal/vox/armalis/verb/message_mob()
+ set category = "Alien"
+ 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
+ text = input("What would you like to say?", "Speak to creature", null, null)
+
+ if (!target || !text)
+ return
+
+ var/mob/M = targets[target]
+
+ if(istype(M, /mob/dead/observer) || M.stat == DEAD)
+ src << "Not even the armalis can speak to the dead."
+ return
+
+ 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.dna.mutantrace == "vox")
+ return
+ H << "\red Your nose begins to bleed..."
+ H.drip(1)
+
+/mob/living/simple_animal/vox/armalis/verb/shriek()
+ set category = "Alien"
+ set name = "Shriek"
+ set desc = "Give voice to a psychic shriek."
+
+/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(istype(O,/obj/item/vox/armalis_armour))
+ user.drop_item()
+ armour = O
+ speed = 1
+ maxHealth += 200
+ health += 200
+ O.loc = src
+ visible_message("\blue [src] is quickly outfitted in [O] by [user].","\blue You quickly outfit [src] in [O].")
+ regenerate_icons()
+ return
+ if(istype(O,/obj/item/vox/armalis_amp))
+ user.drop_item()
+ amp = O
+ O.loc = src
+ visible_message("\blue [src] is quickly outfitted in [O] by [user].","\blue You quickly outfit [src] in [O].")
+ regenerate_icons()
+ return
+ return ..()
+
+/mob/living/simple_animal/vox/armalis/regenerate_icons()
+
+ overlays = list()
+ if(armour)
+ var/icon/armour = image('icons/mob/vox.dmi',"armour")
+ speed = 1
+ overlays += armour
+ if(amp)
+ var/icon/amp = image('icons/mob/vox.dmi',"amplifier")
+ overlays += amp
+ return
+
+/obj/item/vox/armalis_armour
+
+ name = "strange armour"
+ desc = "Hulking reinforced armour for something huge."
+ icon = 'icons/obj/clothing/suits.dmi'
+ icon_state = "armalis_armour"
+ item_state = "armalis_armour"
+
+/obj/item/vox/armalis_amp
+
+ name = "strange lenses"
+ desc = "A series of metallic lenses and chains."
+ icon = 'icons/obj/clothing/hats.dmi'
+ icon_state = "amp"
+ item_state = "amp"
\ No newline at end of file
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 6e9beda1bad..02ea1aa4e7f 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -596,8 +596,6 @@ var/list/slot_equipment_priority = list( \
M.LAssailant = null
else
M.LAssailant = usr
- if (M.pinned.len)
- usr << "They're pinned, gtfo."
return
if(pulling)
@@ -895,3 +893,66 @@ note dizziness decrements automatically in the mob's Life() proc.
/mob/proc/flash_weak_pain()
flick("weak_pain",pain)
+
+mob/verb/yank_out_object()
+ set category = "Object"
+ set name = "Yank out object"
+ set desc = "Remove an embedded item at the cost of bleeding and pain."
+ set src in view(1)
+
+ if(!isliving(usr) || usr.next_move > world.time)
+ return
+ usr.next_move = world.time + 20
+
+ if(usr.stat == 1)
+ usr << "You are unconcious and cannot do that!"
+ return
+
+ if(usr.restrained())
+ usr << "You are restrained and cannot do that!"
+ return
+
+ var/mob/S = src
+ var/mob/U = usr
+ var/list/valid_objects = list()
+ var/self = null
+
+ if(S == U)
+ self = 1 // Removing object from yourself.
+
+ for(var/obj/item/weapon/W in embedded)
+ if(W.w_class >= 2)
+ valid_objects += W
+
+ if(!valid_objects.len)
+ if(self)
+ src << "You have nothing stuck in your body that is large enough to remove."
+ else
+ U << "[src] has nothing stuck in their wounds that is large enough to remove."
+ return
+
+ var/obj/item/weapon/selection = input("What do you want to yank out?", "Embedded objects") in valid_objects
+
+ if(self)
+ src << "You attempt to get a good grip on the [selection] in your body."
+ else
+ U << "You attempt to get a good grip on the [selection] in [S]'s body."
+
+ if(!do_after(U, 80))
+ return
+ if(!selection || !S || !U)
+ return
+
+ if(self)
+ visible_message("[src] rips [selection] out of their body.","You rip [selection] out of your body.")
+ else
+ visible_message("[usr] rips [selection] out of [src]'s body.","[src] rips [selection] out of your body.")
+
+ selection.loc = get_turf(src)
+
+ for(var/obj/item/weapon/O in pinned)
+ if(O == selection)
+ pinned -= O
+ if(!pinned.len)
+ anchored = 0
+ return 1
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index c83909fd8a9..0a41d0d60ce 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -86,6 +86,7 @@
var/unacidable = 0
var/small = 0
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/name_archive //For admin things like possession
diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm
index 6a8c3510f8e..aa113e86599 100644
--- a/code/modules/projectiles/guns/projectile/bow.dm
+++ b/code/modules/projectiles/guns/projectile/bow.dm
@@ -6,21 +6,21 @@
icon_state = "bolt"
item_state = "bolt"
flags = FPRINT | TABLEPASS
- throwforce = 12
+ throwforce = 8
w_class = 3.0
sharp = 1
-/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart..
+/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart.
return
/obj/item/weapon/arrow/quill
name = "vox quill"
desc = "A wickedly barbed quill from some bizarre animal."
- icon = 'icons/mob/vox.dmi'
+ icon = 'icons/obj/weapons.dmi'
icon_state = "quill"
item_state = "quill"
- throwforce = 15
+ throwforce = 5
/obj/item/weapon/arrow/rod
@@ -29,7 +29,7 @@
icon_state = "metal-rod"
/obj/item/weapon/arrow/rod/removed(mob/user)
- if(throwforce == 20) // The rod has been superheated - we don't want it to be useable when removed from the bow.
+ if(throwforce == 15) // The rod has been superheated - we don't want it to be useable when removed from the bow.
user << "[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow."
var/obj/item/weapon/shard/shrapnel/S = new()
S.loc = get_turf(src)
@@ -75,7 +75,7 @@
if(cell)
if(cell.charge >= 500)
user << "[arrow] plinks and crackles as it begins to glow red-hot."
- arrow.throwforce = 20
+ arrow.throwforce = 15
arrow.icon_state = "metal-rod-superheated"
cell.charge -= 500
return
@@ -89,7 +89,7 @@
if(arrow)
if(istype(arrow,/obj/item/weapon/arrow/rod) && cell.charge >= 500)
user << "[arrow] plinks and crackles as it begins to glow red-hot."
- arrow.throwforce = 20
+ arrow.throwforce = 15
arrow.icon_state = "metal-rod-superheated"
cell.charge -= 500
else
diff --git a/icons/mob/vox.dmi b/icons/mob/vox.dmi
index 6f0172bba70..6abba5c9e03 100644
Binary files a/icons/mob/vox.dmi and b/icons/mob/vox.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index 29487a42863..cf9c6d511d6 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 1e9f1c1efb4..003bf5c9f10 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index ecce9fa6aae..c15523cd40a 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ