diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index be1b9db2254..1a1dc2b9e0b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -108,7 +108,7 @@ return TRUE -/atom/movable/proc/throw_at(atom/target, range, speed, thrower, var/do_throw_animation = TRUE) +/atom/movable/proc/throw_at(atom/target, range, speed, thrower, var/do_throw_animation = TRUE, datum/callback/callback) if(!target || !src) return 0 //use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target @@ -184,7 +184,8 @@ src.SpinAnimation(speed = 4, loops = 1) //done throwing, either because it hit something or it finished moving - if(isobj(src)) src.throw_impact(get_turf(src),speed) + if(isobj(src)) + src.throw_impact(get_turf(src),speed) src.throwing = 0 src.thrower = null src.throw_source = null @@ -193,6 +194,9 @@ var/turf/Tloc = loc Tloc.Entered(src) + if(callback) + callback.Invoke() + /atom/movable/proc/throw_at_random(var/include_own_turf, var/maxrange, var/speed) var/list/turfs = RANGE_TURFS(maxrange, src) if(!maxrange) diff --git a/code/game/gamemodes/changeling/helpers/_store.dm b/code/game/gamemodes/changeling/helpers/_store.dm index 7e692f81164..f94704d3756 100644 --- a/code/game/gamemodes/changeling/helpers/_store.dm +++ b/code/game/gamemodes/changeling/helpers/_store.dm @@ -194,6 +194,12 @@ var/list/datum/power/changeling/powerinstances = list() //weapon and armor like powers +/datum/power/changeling/combat_tentacle + name = "Mutate Tentacles" + desc = "Permits us to reshape our arms into a multi-purpose tentacles." + genomecost = 4 + verbpath = /mob/proc/combat_tentacle + /datum/power/changeling/armblades name = "Mutate Armblades" desc = "Permits us to reshape our arms into a deadly blade." diff --git a/code/game/gamemodes/changeling/implements/items.dm b/code/game/gamemodes/changeling/implements/items.dm index a6ddf5d21d9..5417e0984ce 100644 --- a/code/game/gamemodes/changeling/implements/items.dm +++ b/code/game/gamemodes/changeling/implements/items.dm @@ -28,8 +28,8 @@ return ..() /obj/item/melee/arm_blade/dropped(var/mob/living/user) - visible_message("With a sickening crunch, [user] reforms their arm blade into an arm!", - "You hear organic matter ripping and tearing!") + visible_message(SPAN_DANGER("With a sickening crunch, [user] reforms their arm blade into an arm!"), + SPAN_WARNING("You hear organic matter ripping and tearing!")) playsound(loc, 'sound/effects/blobattack.ogg', 30, 1) QDEL_IN(src, 1) @@ -85,8 +85,8 @@ return ..() /obj/item/shield/riot/changeling/dropped(var/mob/living/user) - visible_message("With a sickening crunch, [user] reforms their shield into an arm!", - "You hear organic matter ripping and tearing!") + visible_message(SPAN_DANGER("With a sickening crunch, [user] reforms their shield into an arm!"), + SPAN_WARNING("You hear organic matter ripping and tearing!")) playsound(loc, 'sound/effects/blobattack.ogg', 30, 1) QDEL_IN(src, 1) @@ -122,3 +122,163 @@ edge = FALSE throwforce = 5 w_class = ITEMSIZE_SMALL + + +/***************************************\ +|***********COMBAT TENTACLES*************| +\***************************************/ + +/obj/item/gun/energy/tentacle + name = "tentacle" + desc = "A horrible amalgamation of blood and flesh, warped into the shape of a pulsing tentacle." + desc_info = null + desc_antag = "A fleshy tentacle that can stretch out and grab things or people." + icon = 'icons/obj/contained_items/weapons/ling_tentacle.dmi' + icon_state = "tentacle" + item_state = "tentacle" + flags = NOBLUDGEON + w_class = ITEMSIZE_HUGE + has_safety = FALSE + needspin = FALSE + pin = null + projectile_type = /obj/item/projectile/tentacle + fire_sound = 'sound/effects/splat.ogg' + force = 0 + max_shots = 1 + throwforce = 0 //Just to be on the safe side + throw_range = 0 + throw_speed = 0 + charge_failure_message = "cannot be charged." + +/obj/item/gun/energy/tentacle/update_icon() + return + +/obj/item/gun/energy/tentacle/dropped(mob/living/user) + if(power_supply?.charge > 0 && !user.stat) + user.visible_message(SPAN_DANGER("With a sickening crunch, [user] reforms their tentacle into an arm!"), SPAN_NOTICE("You reform your tentacle into an arm."), SPAN_WARNING("You hear organic matter ripping and tearing!")) + playsound(loc, 'sound/effects/blobattack.ogg', 30, 1) + QDEL_IN(src, 1) + +/obj/item/gun/energy/tentacle/handle_click_empty(user) + to_chat(user, SPAN_WARNING("\The [src] is not ready yet.")) + +/obj/item/gun/energy/tentacle/handle_suicide(mob/living/user) + user.visible_message(SPAN_WARNING("[user] coils \the [src] tightly around [user.get_pronoun("his")] neck!")) + if(!do_after(user, 40)) + return + user.adjustOxyLoss(300) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/internal/brain = H.internal_organs_by_name[BP_BRAIN] + if(brain) + brain.take_internal_damage(brain.max_damage) + user.death() // double tap - geeves + +/obj/item/projectile/tentacle + name = "tentacle" + icon = 'icons/obj/contained_items/weapons/ling_tentacle.dmi' + icon_state = "tentacle_end" + pass_flags = PASSTABLE + cant_miss = TRUE + damage = 0 + damage_type = BRUTE + range = 8 + hitsound = 'sound/weapons/thudswoosh.ogg' + var/chain + var/obj/item/gun/energy/tentacle/source //the item that shot it + +/obj/item/projectile/tentacle/New(obj/item/gun/energy/tentacle/tentacle_gun) + source = tentacle_gun + ..() + +/obj/item/projectile/tentacle/fire(setAngle) + if(firer) + chain = firer.Beam(src, icon_state = "tentacle", time = -1, maxdistance = INFINITY, beam_sleep_time = 1) + ..() + +/obj/item/projectile/tentacle/proc/reset_throw(mob/living/carbon/human/H) + if(H.in_throw_mode) + H.throw_mode_off() //Don't annoy the changeling if he doesn't catch the item + +/mob/proc/tentacle_grab(mob/living/carbon/human/H) + if(ishuman(H) && Adjacent(H)) + var/obj/item/grab/G = H.grabbedby(src, TRUE) + if(istype(G)) + G.set_state(GRAB_AGGRESSIVE) //Instant aggressive grab + +/mob/proc/tentacle_stab(mob/living/carbon/C) + if(Adjacent(C)) + var/obj/item/I = r_hand + if(!is_sharp(I)) + I = l_hand + if(!is_sharp(I)) + return + + C.visible_message(SPAN_DANGER("[src] impales [C] with [I]!"), SPAN_DANGER("[src] impales you with [I]!")) + C.apply_damage(I.force, BRUTE, "chest") + do_attack_animation(C) + add_blood(C) + playsound(get_turf(src), I.hitsound, 75, 1) + +/obj/item/projectile/tentacle/on_hit(atom/target, blocked = 0) + qdel(source) //one tentacle only unless you miss + if(blocked >= 100) + return FALSE + var/mob/living/carbon/human/H = firer + if(istype(target, /obj/item)) + var/obj/item/I = target + if(!I.anchored) + to_chat(firer, SPAN_NOTICE("You pull [I] towards yourself.")) + H.throw_mode_on() + I.throw_at(H, 10, 2) + . = TRUE + + else if(isliving(target)) + var/mob/living/L = target + if(!L.anchored && !L.throwing)//avoid double hits + if(iscarbon(L)) + var/mob/living/carbon/C = L + switch(firer.a_intent) + if(I_HELP) + C.visible_message(SPAN_DANGER("[L] is pulled by [H]'s tentacle!"), SPAN_DANGER("A tentacle grabs you and pulls you towards [H]!")) + C.throw_at(get_step_towards(H,C), 8, 2) + return TRUE + + if(I_DISARM) + var/obj/item/I = C.get_active_hand() + if(!I || istype(I, /obj/item/grab)) + I = C.get_inactive_hand() + if(I && !istype(I, /obj/item/grab)) + if(C.unEquip(I)) + C.visible_message(SPAN_DANGER("[I] is yanked out of [C]'s hand by [src]!"),SPAN_DANGER("A tentacle pulls [I] away from you!")) + I.throw_at(get_step_towards(H, C), 8, 2, callback = CALLBACK(H, /mob/proc/put_in_any_hand_if_possible, I)) + return TRUE + else + to_chat(firer, SPAN_DANGER("You can't seem to pry [I] out of [C]'s hands!")) + return FALSE + else + to_chat(firer, SPAN_DANGER("[C] has nothing in hand to disarm!")) + return FALSE + + if(I_GRAB) + C.visible_message(SPAN_DANGER("[L] is grabbed by [H]'s tentacle!"), SPAN_DANGER("A tentacle grabs you and pulls you towards [H]!")) + C.throw_at(get_step_towards(H,C), 8, 2, callback=CALLBACK(H, /mob/proc/tentacle_grab, C)) + return TRUE + + if(I_HURT) + C.visible_message(SPAN_DANGER("[L] is thrown towards [H] by a tentacle!"), SPAN_DANGER("A tentacle grabs you and throws you towards [H]!")) + C.throw_at(get_step_towards(H,C), 8, 2, callback=CALLBACK(H, /mob/proc/tentacle_stab, C)) + return TRUE + else + L.visible_message(SPAN_DANGER("[L] is pulled by [H]'s tentacle!"), SPAN_DANGER("A tentacle grabs you and pulls you towards [H]!")) + L.throw_at(get_step_towards(H,L), 8, 2) + . = TRUE + +/obj/item/projectile/tentacle/on_impact(var/atom/A) + if(isturf(A)) + qdel(source) + +/obj/item/projectile/tentacle/Destroy() + qdel(chain) + source = null + return ..() \ No newline at end of file diff --git a/code/game/gamemodes/changeling/implements/powers/body.dm b/code/game/gamemodes/changeling/implements/powers/body.dm index db673a2ff9e..079845ddb14 100644 --- a/code/game/gamemodes/changeling/implements/powers/body.dm +++ b/code/game/gamemodes/changeling/implements/powers/body.dm @@ -372,6 +372,43 @@ if(src && src.mind && src.mind.changeling) src.mind.changeling.mimicing = "" +/mob/proc/combat_tentacle() + set category = "Changeling" + set name = "Form Tentacle (20)" + set desc = "Rupture the flesh and mend the bone of your hand into a multi-purpose tentacle." + + var/datum/changeling/changeling = changeling_power(20, 0, 0) + if(!changeling) + return FALSE + mind.changeling.chem_charges -= 20 + + var/mob/living/carbon/M = src + + if(M.l_hand && M.r_hand) + to_chat(M, SPAN_WARNING("Your hands are full.")) + return + + if(M.handcuffed) + var/cuffs = M.handcuffed + M.u_equip(M.handcuffed) + qdel(cuffs) + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) + src.visible_message("[H] tears through the [H.wear_suit] with their spindly arm tentacle!", + "We tear through the [H.wear_suit] with our arm tentacle!", + "You hear cloth ripping and tearing!") + QDEL_IN(H.wear_suit, 0) + H.unEquip(H.wear_suit, force = TRUE) + + var/obj/item/gun/energy/tentacle/T = new(M) + M.put_in_hands(T) + playsound(loc, 'sound/effects/splat.ogg', 30, 1) + src.visible_message("A spindly tentacle forms around [M]\'s arm!", + "Our arm twists and mutates, transforming it into a tentacle.", + "You hear organic matter ripping and tearing!") + /mob/proc/armblades() set category = "Changeling" set name = "Form Blades (20)" diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 58bc2c26f63..eaadb7b65f4 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -1011,8 +1011,7 @@ else r_hand = G - G.state = GRAB_AGGRESSIVE - G.icon_state = "grabbed1" + G.set_state(GRAB_AGGRESSIVE) G.synch() verbs -= /mob/living/carbon/human/proc/grapple diff --git a/code/modules/martial_arts/sleeping_carp.dm b/code/modules/martial_arts/sleeping_carp.dm index 98c6f9da2fd..bf6c4e5bd7d 100644 --- a/code/modules/martial_arts/sleeping_carp.dm +++ b/code/modules/martial_arts/sleeping_carp.dm @@ -102,7 +102,7 @@ D.grabbedby(A,1) var/obj/item/grab/G = A.get_active_hand() if(G) - G.state = GRAB_AGGRESSIVE //Instant aggressive grab + G.set_state(GRAB_AGGRESSIVE) //Instant aggressive grab /datum/martial_art/the_sleeping_carp/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) add_to_streak("D",D) diff --git a/code/modules/martial_arts/unathi.dm b/code/modules/martial_arts/unathi.dm index 24bbfbc1b47..a4b5d0c7a91 100644 --- a/code/modules/martial_arts/unathi.dm +++ b/code/modules/martial_arts/unathi.dm @@ -30,7 +30,7 @@ D.grabbedby(A,1) var/obj/item/grab/G = A.get_active_hand() if(G && prob(50)) - G.state = GRAB_AGGRESSIVE + G.set_state(GRAB_AGGRESSIVE) D.visible_message("[A] gets a strong grip on [D]!") return 1 diff --git a/code/modules/martial_arts/vaurca.dm b/code/modules/martial_arts/vaurca.dm index 238a7787d38..d92301fdb50 100644 --- a/code/modules/martial_arts/vaurca.dm +++ b/code/modules/martial_arts/vaurca.dm @@ -59,7 +59,7 @@ if(istype(A.get_active_hand(),/obj/item/grab)) var/obj/item/grab/G = A.get_active_hand() if(G && G.affecting == D) - G.state = GRAB_AGGRESSIVE + G.set_state(GRAB_AGGRESSIVE) D.visible_message(SPAN_DANGER("[A] gets a strong grip on [D]!")) if(isvaurca(A)) A.bugbite(TRUE) diff --git a/code/modules/martial_arts/wrestling.dm b/code/modules/martial_arts/wrestling.dm index 2aa041e6dee..d614e0bf746 100644 --- a/code/modules/martial_arts/wrestling.dm +++ b/code/modules/martial_arts/wrestling.dm @@ -11,7 +11,7 @@ D.grabbedby(A,1) var/obj/item/grab/G = A.get_active_hand() if(G && prob(50)) - G.state = GRAB_AGGRESSIVE + G.set_state(GRAB_AGGRESSIVE) D.visible_message("[A] has [D] in a clinch!") else D.visible_message("[A] fails to get [D] in a clinch!") diff --git a/code/modules/martial_arts/zombie.dm b/code/modules/martial_arts/zombie.dm index f0770469f3c..484e594be8a 100644 --- a/code/modules/martial_arts/zombie.dm +++ b/code/modules/martial_arts/zombie.dm @@ -26,7 +26,7 @@ /datum/martial_art/zombie/proc/check_grab(var/mob/living/carbon/human/A) var/obj/item/grab/G = A.get_active_hand() if(G) - G.state = GRAB_AGGRESSIVE + G.set_state(GRAB_AGGRESSIVE) G.icon_state = "grabbed1" G.hud.icon_state = "reinforce1" diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 4fac2a1d9f5..bd156f9e5e9 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -194,10 +194,7 @@ H.do_attack_animation(src) playsound(loc, /decl/sound_category/grab_sound, 50, FALSE, -1) if(H.gloves && istype(H.gloves,/obj/item/clothing/gloves/force/syndicate)) //only antag gloves can do this for now - G.state = GRAB_AGGRESSIVE - G.icon_state = "grabbed1" - G.hud.icon_state = "reinforce1" - G.last_action = world.time + G.set_state(GRAB_AGGRESSIVE) visible_message("[M] gets a strong grip on [src]!") return 1 visible_message("[M] has grabbed [src] passively!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1aba1476965..bc1166c99a8 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -559,14 +559,11 @@ emp_act user.do_attack_animation(src) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) if(user.gloves && istype(user.gloves,/obj/item/clothing/gloves/force/syndicate)) //only antag gloves can do this for now - G.state = GRAB_AGGRESSIVE - G.icon_state = "grabbed1" - G.hud.icon_state = "reinforce1" - G.last_action = world.time + G.set_state(GRAB_AGGRESSIVE) visible_message("[user] gets a strong grip on [src]!") - return 1 + return G visible_message("[user] has grabbed [src] passively!") - return 1 + return G /mob/living/carbon/human/set_on_fire() ..() diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 77a420d8db8..df90801616e 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -170,8 +170,7 @@ mob/living/carbon/human/proc/change_monitor() else r_hand = G - G.state = GRAB_PASSIVE - G.icon_state = "grabbed1" + G.set_state(GRAB_AGGRESSIVE) G.synch() return TRUE diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 91a35c3e72b..d621de1c5df 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -88,6 +88,45 @@ return affecting return null +/obj/item/grab/proc/set_state(var/set_state) + last_action = world.time + switch(set_state) + if(GRAB_PASSIVE) + state = initial(state) + icon_state = initial(icon_state) + if(hud) + hud.icon_state = initial(hud.icon_state) + if(GRAB_AGGRESSIVE) + state = GRAB_AGGRESSIVE + icon_state = "grabbed1" + hud.icon_state = "reinforce1" + if(GRAB_NECK) + state = GRAB_NECK + icon_state = "grabbed+1" + if(hud) + hud.icon_state = "kill" + hud.name = "kill" + if(affecting) + affecting.Stun(10) + if(assailant) + assailant.visible_message(SPAN_WARNING("[assailant] reinforces [assailant.get_pronoun("his")] grip on [affecting]'s neck!"), SPAN_WARNING("You reinforce your grip on [affecting]'s neck!")) + if(GRAB_KILL) + state = GRAB_KILL + icon_state = "grabbed+1" + if(hud) + hud.icon_state = "kill1" + hud.name = "loosen" + if(affecting) + affecting.setClickCooldown(10) + if(ishuman(affecting)) + var/mob/living/carbon/human/A = affecting + if (!(A.species.flags & NO_BREATHE)) + A.losebreath += 4 + affecting.set_dir(WEST) + if(assailant) + assailant.visible_message(SPAN_DANGER("[assailant] starts strangling [affecting]!"), SPAN_DANGER("You start strangling [affecting]!")) + else + crash_with("Grab set to illegal state with set_state: [set_state]") //This makes sure that the grab screen object is displayed in the correct hand. /obj/item/grab/proc/synch() @@ -275,49 +314,32 @@ assailant.visible_message(SPAN_WARNING("[assailant] pins [affecting] down to the ground by the hands!"), SPAN_WARNING("You pin [affecting] down to the ground by the hands!")) apply_pinning(affecting, assailant) - state = GRAB_AGGRESSIVE - icon_state = "grabbed1" - hud.icon_state = "reinforce1" + set_state(GRAB_AGGRESSIVE) else if(state < GRAB_NECK) if(isslime(affecting)) assailant.visible_message(SPAN_WARNING("[assailant] tries to squeeze [affecting], but [assailant.get_pronoun("his")] hands sink right through!"), SPAN_WARNING("You try to squeeze [affecting], but your hands sink right through!")) return playsound(loc, /decl/sound_category/grab_sound, 50, FALSE, -1) - assailant.visible_message(SPAN_WARNING("[assailant] reinforces [assailant.get_pronoun("his")] grip on [affecting]'s neck!"), SPAN_WARNING("You reinforce your grip on [affecting]'s neck!")) - state = GRAB_NECK - icon_state = "grabbed+1" + set_state(GRAB_NECK) affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])" assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])" msg_admin_attack("[key_name_admin(assailant)] grabbed the neck of [key_name_admin(affecting)]",ckey=key_name(assailant),ckey_target=key_name(affecting)) - hud.icon_state = "kill" - hud.name = "kill" - affecting.Stun(10) //10 ticks of ensured grab else if(state < GRAB_UPGRADING) if(ishuman(affecting)) var/mob/living/carbon/human/H = affecting if(H.head && (H.head.item_flags & AIRTIGHT)) assailant.visible_message(SPAN_WARNING("[affecting]'s headgear prevents [assailant] from choking them out!"), SPAN_WARNING("[affecting]'s headgear prevents you from choking them out!")) return - hud.icon_state = "kill1" - hud.name = "loosen" - state = GRAB_KILL + set_state(GRAB_KILL) playsound(loc, /decl/sound_category/grab_sound, 50, FALSE, -1) - assailant.visible_message(SPAN_DANGER("[assailant] starts strangling [affecting]!"), SPAN_DANGER("You start strangling [affecting]!")) affecting.attack_log += "\[[time_stamp()]\] is being strangled by [assailant.name] ([assailant.ckey])" assailant.attack_log += "\[[time_stamp()]\] is strangling [affecting.name] ([affecting.ckey])" msg_admin_attack("[key_name_admin(assailant)] is strangling [key_name_admin(affecting)]",ckey=key_name(assailant),ckey_target=key_name(affecting)) - - affecting.setClickCooldown(10) - if(ishuman(affecting)) - var/mob/living/carbon/human/A = affecting - if (!(A.species.flags & NO_BREATHE)) - A.losebreath += 4 - affecting.set_dir(WEST) else if(state == GRAB_KILL) hud.icon_state = "kill" hud.name = "kill" - state = GRAB_NECK + state = GRAB_NECK // this one doesn't get a set state because it's unique assailant.visible_message(SPAN_WARNING("[assailant] stops strangling [affecting]!"), SPAN_WARNING("You stop strangling [affecting]!")) adjust_position() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index ddb416ed2b8..71c6024ab42 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -488,7 +488,7 @@ damage_mult = 1.5 P.damage *= damage_mult //you can't miss at point blank.. - P.can_miss = 1 + P.cant_miss = TRUE /obj/item/gun/proc/process_accuracy(obj/projectile, mob/user, atom/target, acc_mod, dispersion) var/obj/item/projectile/P = projectile @@ -543,7 +543,7 @@ mouthshoot = TRUE M.visible_message(SPAN_WARNING("\The [user] sticks their gun in their mouth, ready to pull the trigger...")) if(!do_after(user, 40)) - M.visible_message(SPAN_NOTICE("\The [user] decided life was worth living")) + M.visible_message(SPAN_NOTICE("\The [user] decided life was worth living.")) mouthshoot = FALSE return var/obj/item/projectile/in_chamber = consume_next_projectile() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index d1d97c7ad0a..43950046f3f 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -15,6 +15,7 @@ var/def_zone = "" //Aiming at var/hit_zone // The place that actually got hit var/mob/firer = null//Who shot it + var/no_attack_message var/silenced = FALSE //Attack message var/shot_from = "" // name of the object which shot us @@ -23,7 +24,7 @@ var/dispersion = 0.0 //used for shooting at blank range, you shouldn't be able to miss - var/can_miss = 0 + var/cant_miss = FALSE var/taser_effect = 0 //If set then the projectile will apply it's agony damage using stun_effect_act() to mobs it hits, and other damage will be ignored @@ -190,8 +191,8 @@ return TRUE result = target_mob.bullet_act(src, def_zone) - if(result == PROJECTILE_FORCE_MISS && (can_miss == 0)) //if you're shooting at point blank you can't miss. - if(!silenced) + if(result == PROJECTILE_FORCE_MISS && !cant_miss) //if you're shooting at point blank you can't miss. + if(!silenced && !no_attack_message) target_mob.visible_message("\The [src] misses [target_mob] narrowly!") playsound(target_mob, /decl/sound_category/bulletflyby_sound, 50, 1) return FALSE @@ -204,10 +205,11 @@ var/mob/living/simple_animal/SA = target_mob impacted_organ = pick(SA.organ_names) //hit messages - if(silenced) - to_chat(target_mob, "You've been hit in the [impacted_organ] by \a [src]!") - else - target_mob.visible_message("\The [target_mob] is hit by \a [src] in the [impacted_organ]!", "You are hit by \a [src] in the [impacted_organ]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter + if(!no_attack_message) + if(silenced) + to_chat(target_mob, "You've been hit in the [impacted_organ] by \a [src]!") + else + target_mob.visible_message("\The [target_mob] is hit by \a [src] in the [impacted_organ]!", "You are hit by \a [src] in the [impacted_organ]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter var/no_clients = FALSE //admin logs diff --git a/html/changelogs/geeves-combat_tentacle.yml b/html/changelogs/geeves-combat_tentacle.yml new file mode 100644 index 00000000000..6107229e0a3 --- /dev/null +++ b/html/changelogs/geeves-combat_tentacle.yml @@ -0,0 +1,6 @@ +author: Geeves + +delete-after: True + +changes: + - rscadd: "Ported Combat Tentacles for Changelings from Paradise station. You can use them to pull items or people towards you." \ No newline at end of file diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 3ab304ae67e..62256be2943 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/obj/contained_items/weapons/ling_tentacle.dmi b/icons/obj/contained_items/weapons/ling_tentacle.dmi new file mode 100644 index 00000000000..c6adb8a09ad Binary files /dev/null and b/icons/obj/contained_items/weapons/ling_tentacle.dmi differ