Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changeling Combat Tentacle #10784

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions code/game/gamemodes/changeling/helpers/_store.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
168 changes: 164 additions & 4 deletions code/game/gamemodes/changeling/implements/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
return ..()

/obj/item/melee/arm_blade/dropped(var/mob/living/user)
visible_message("<span class='danger'>With a sickening crunch, [user] reforms their arm blade into an arm!</span>",
"<span class='warning'>You hear organic matter ripping and tearing!</span>")
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)

Expand Down Expand Up @@ -85,8 +85,8 @@
return ..()

/obj/item/shield/riot/changeling/dropped(var/mob/living/user)
visible_message("<span class='danger'>With a sickening crunch, [user] reforms their shield into an arm!</span>",
"<span class='warning'>You hear organic matter ripping and tearing!</span>")
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)

Expand Down Expand Up @@ -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
Comment on lines +247 to +261
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have concerns about that capability, as we removed a lot of the "slap things out of hands" mechanics in the past due to balance issues.


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 ..()
37 changes: 37 additions & 0 deletions code/game/gamemodes/changeling/implements/powers/body.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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("<span class='danger'>[H] tears through the [H.wear_suit] with their spindly arm tentacle!</span>",
"<span class='danger'>We tear through the [H.wear_suit] with our arm tentacle!</span>",
"<span class='danger'>You hear cloth ripping and tearing!</span>")
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("<span class='danger'>A spindly tentacle forms around [M]\'s arm!</span>",
"<span class='danger'>Our arm twists and mutates, transforming it into a tentacle.</span>",
"<span class='danger'>You hear organic matter ripping and tearing!</span>")

/mob/proc/armblades()
set category = "Changeling"
set name = "Form Blades (20)"
Expand Down
3 changes: 1 addition & 2 deletions code/game/gamemodes/vampire/vampire_powers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion code/modules/martial_arts/sleeping_carp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/martial_arts/unathi.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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("<span class='danger'>[A] gets a strong grip on [D]!</span>")
return 1

Expand Down
2 changes: 1 addition & 1 deletion code/modules/martial_arts/vaurca.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/martial_arts/wrestling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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("<span class='danger'>[A] has [D] in a clinch!</span>")
else
D.visible_message("<span class='danger'>[A] fails to get [D] in a clinch!</span>")
Expand Down
2 changes: 1 addition & 1 deletion code/modules/martial_arts/zombie.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
5 changes: 1 addition & 4 deletions code/modules/mob/living/carbon/human/human_attackhand.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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("<span class='warning'>[M] gets a strong grip on [src]!</span>")
return 1
visible_message("<span class='warning'>[M] has grabbed [src] passively!</span>")
Expand Down
9 changes: 3 additions & 6 deletions code/modules/mob/living/carbon/human/human_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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("<span class='warning'>[user] gets a strong grip on [src]!</span>")
return 1
return G
visible_message("<span class='warning'>[user] has grabbed [src] passively!</span>")
return 1
return G

/mob/living/carbon/human/set_on_fire()
..()
Expand Down
3 changes: 1 addition & 2 deletions code/modules/mob/living/carbon/human/human_powers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading