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