diff --git a/code/datums/beam.dm b/code/datums/beam.dm index a934ce0189a..d5b5bf2be20 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -16,12 +16,13 @@ var/beam_type = /obj/effect/ebeam //must be subtype -/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam) +/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3) endtime = world.time+time origin = beam_origin origin_oldloc = get_turf(origin) target = beam_target target_oldloc = get_turf(target) + sleep_time = beam_sleep_time if(origin_oldloc == origin && target_oldloc == target) static_beam = 1 max_distance = maxdistance @@ -128,8 +129,8 @@ return ..() -/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam) - var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type) +/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time = 3) + var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) spawn(0) newbeam.Start() return newbeam diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 97aade8598b..6c50490a577 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -17,6 +17,7 @@ dna_cost = -1 genetic_damage = 1000 + var/silent = FALSE var/weapon_type var/weapon_name_simple @@ -28,9 +29,10 @@ /obj/effect/proc_holder/changeling/weapon/proc/check_weapon(mob/user, obj/item/hand_item) if(istype(hand_item, weapon_type)) - playsound(user, 'sound/effects/blobattack.ogg', 30, 1) qdel(hand_item) - user.visible_message("With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!", "We assimilate the [weapon_name_simple] back into our body.", "[user]'s missing arm reforms, making a loud, grotesque sound!", "Your arm regrows, making a loud, crunchy sound and giving you great pain!", "You hear organic matter ripping and tearing!") user.emote("scream") - var/obj/item/W = new weapon_type(user) + var/obj/item/W = new weapon_type(user, silent) user.put_in_hands(W) - playsound(user, 'sound/effects/blobattack.ogg', 30, 1) + if(!silent) + playsound(user, 'sound/effects/blobattack.ogg', 30, 1) return W /obj/effect/proc_holder/changeling/weapon/on_refund(mob/user) @@ -191,6 +194,172 @@ "You hear a metal screeching sound.") A.open(2) +/***************************************\ +|***********COMBAT TENTACLES*************| +\***************************************/ + +/obj/effect/proc_holder/changeling/weapon/tentacle + name = "Tentacle" + desc = "We ready a tentacle to grab items or victims with." + helptext = "We can use it once to retrieve a distant item. If used on living creatures, the effect depends on the intent: \ + Help will simply drag them closer, Disarm will grab whatever they're holding instead of them, Grab will put the victim in our hold after catching it, \ + and Harm will stun it, and stab it if we're also holding a sharp weapon. Cannot be used while in lesser form." + chemical_cost = 10 + dna_cost = 2 + genetic_damage = 5 + req_human = 1 + max_genetic_damage = 10 + weapon_type = /obj/item/weapon/gun/magic/tentacle + weapon_name_simple = "tentacle" + silent = TRUE + +/obj/item/weapon/gun/magic/tentacle + name = "tentacle" + desc = "A fleshy tentacle that can stretch out and grab things or people." + icon = 'icons/obj/weapons.dmi' + icon_state = "proboscis" + item_state = null + flags = ABSTRACT | NODROP | DROPDEL | NOBLUDGEON + w_class = WEIGHT_CLASS_HUGE + ammo_type = /obj/item/ammo_casing/magic/tentacle + fire_sound = 'sound/effects/splat.ogg' + force = 0 + max_charges = 1 + throwforce = 0 //Just to be on the safe side + throw_range = 0 + throw_speed = 0 + +/obj/item/weapon/gun/magic/tentacle/New(location,silent) + ..() + if(ismob(loc)) + if(!silent) + loc.visible_message("[loc.name]\'s arm starts stretching inhumanly!", "Our arm twists and mutates, transforming it into a tentacle.", "You hear organic matter ripping and tearing!") + else + loc << "You prepare to extend a tentacle." + + +/obj/item/weapon/gun/magic/tentacle/shoot_with_empty_chamber(mob/living/user as mob|obj) + user << "The [name] is not ready yet." + +/obj/item/ammo_casing/magic/tentacle + name = "tentacle" + desc = "a tentacle." + projectile_type = /obj/item/projectile/tentacle + caliber = "tentacle" + icon_state = "tentacle_end" + firing_effect_type = null + var/obj/item/weapon/gun/magic/tentacle/gun //the item that shot it + +/obj/item/ammo_casing/magic/tentacle/New(obj/item/weapon/gun/magic/tentacle/tentacle_gun) + gun = tentacle_gun + ..() + +/obj/item/ammo_casing/magic/tentacle/Destroy(obj/item/weapon/gun/magic/tentacle/tentacle_gun) + gun = null + ..() + +/obj/item/projectile/tentacle + name = "tentacle" + icon_state = "tentacle_end" + pass_flags = PASSTABLE + damage = 0 + damage_type = BRUTE + range = 8 + hitsound = 'sound/weapons/thudswoosh.ogg' + var/chain + var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it + +/obj/item/projectile/tentacle/New(obj/item/ammo_casing/magic/tentacle/tentacle_casing) + source = tentacle_casing + ..() + +/obj/item/projectile/tentacle/fire(setAngle) + if(firer) + chain = firer.Beam(src, icon_state = "tentacle", time = INFINITY, 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 + +/obj/item/projectile/tentacle/proc/tentacle_grab(mob/living/carbon/human/H, mob/living/carbon/C) + if(H.Adjacent(C)) + C.grabbedby(H) + C.grippedby(H) //instant aggro grab + +/obj/item/projectile/tentacle/proc/tentacle_stab(mob/living/carbon/human/H, mob/living/carbon/C) + if(H.Adjacent(C)) + for(var/obj/item/I in H.held_items) + if(I.is_sharp()) + C.visible_message("[H] impales [C] with [H.p_their()] [I.name]!", "[H] impales you with [H.p_their()] [I.name]!") + C.apply_damage(I.force*2, BRUTE, "chest") + H.do_item_attack_animation(C, used_item = I) + H.add_mob_blood(C) + playsound(get_turf(H),I.hitsound,75,1) + C.Weaken(4) + return + C.visible_message("[C] falls at [H]'s feet!", "You are thrown at [H]'s feet!") + C.Weaken(2) + +/obj/item/projectile/tentacle/on_hit(atom/target, blocked = 0) + qdel(source.gun) //one tentacle only unless you miss + if(blocked >= 100) + return 0 + var/mob/living/carbon/human/H = firer + if(istype(target, /obj/item)) + var/obj/item/I = target + if(!I.anchored) + firer << "You pull [I] towards yourself." + H.throw_mode_on() + I.throw_at(H, 10, 2) + . = 1 + + 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(INTENT_HELP) + C.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!") + C.throw_at(get_step_towards(H,C), 8, 2) + return 1 + + if(INTENT_DISARM) + var/obj/item/I = C.get_active_held_item() + if(I) + if(C.drop_item()) + C.visible_message("[I] is yanked off of [C]'s hand by [src]!","A tentacle pulls [I] away from you!") + on_hit(I) //grab the item as if you had hit it directly with the tentacle + return 1 + else + firer << "You can't seem to pry [I] off of [C]'s hands!" + return 0 + else + firer << "[C] has nothing in hand to disarm!" + return 0 + + if(INTENT_GRAB) + C.visible_message("[L] is grabbed by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!") + C.throw_at(get_step_towards(H,C), 8, 2) + addtimer(src, "tentacle_grab", 3, TIMER_NORMAL, H, C) + return 1 + + if(INTENT_HARM) + C.visible_message("[L] is thrown towards [H] by a tentacle!","A tentacle grabs you and throws you towards [H]!") + C.throw_at(get_step_towards(H,C), 8, 2) + addtimer(src, "tentacle_stab", 3, TIMER_NORMAL, H, C) + return 1 + else + L.visible_message("[L] is pulled by [H]'s tentacle!","A tentacle grabs you and pulls you towards [H]!") + L.throw_at(get_step_towards(H,L), 8, 2) + . = 1 + +/obj/item/projectile/tentacle/Destroy() + qdel(chain) + source = null + return ..() + /***************************************\ |****************SHIELD*****************| diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 247d6a401f7..769e61ee264 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 5dd8e8913b3..2da176d5390 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ