From 54417b76542006a081f32d60c9f4c0973a00cc83 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Wed, 27 Sep 2023 21:55:58 +0200 Subject: [PATCH 01/13] WIP execution, don't look. Creates a new necro ability by a hackjob from different abilities --- .../code/necromorph/abilities/finisher.dm | 427 ++++++++++++++++++ 1 file changed, 427 insertions(+) create mode 100644 deadspace/code/necromorph/abilities/finisher.dm diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm new file mode 100644 index 00000000000..dc842500b0c --- /dev/null +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -0,0 +1,427 @@ + + +/datum/action/cooldown/necro/finish + name = "Finish" + desc = "Allows you to deal extraordinary amounts of damage to weakened humans, guarantees death of its victims upon completion." + cooldown_time = 2 SECONDS + click_to_activate = TRUE + /// Delay before the finisher actually occurs + var/finisher_delay = 2 SECONDS + /// The maximum amount of time we can finisher + var/finisher_time = 4 SECONDS + /// The initial damage the finisher does to the head limb trying to rip it off + var/finisher_damage = 50 + // If the finisher fails to keep the victim in their clutches + var/finisher_stagger = 2 SECONDS + /// If the current move is being triggered by us or not + var/actively_moving = FALSE + var/valid_steps_taken = 0 + + var/atom/target_atom + +/datum/action/cooldown/necro/finisher/PreActivate(atom/target) +var/turf/T = get_turf(target) + if(!T) + to_chat(owner, span_notice("You must target a human to execute them!")) + return FALSE + if(!ishuman(target)) + for(var/mob/living/carbon/human/hummie in view(1, T)) + if(!isnecromorph(hummie)) + target = hummie + break + if(target == owner || isnecromorph(target)) + to_chat(owner, span_notice("You can't peform an execution on a necromorph!")) + return FALSE + + return ..() + +/datum/action/cooldown/necro/finisher/Activate(atom/target) + . = TRUE + // Start pre-cooldown so that the ability can't come up while the finish is happening + StartCooldown(finisher_time+finisher_delay+1) + addtimer(CALLBACK(src, PROC_REF(do_finisher)), finisher_delay) + +/datum/action/cooldown/necro/finish/proc/do_finisher() + var/mob/living/carbon/human/necromorph/finisher = owner + + actively_moving = FALSE + finisher.finishing = TRUE + RegisterSignal(finisher, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump)) + RegisterSignal(finisher, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) + RegisterSignal(finisher, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + finisher.setDir(get_dir(finisher, target_atom)) + do_finisher_indicator(target_atom) + + var/datum/move_loop/new_loop = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) + if(!new_loop) + UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED)) + return + RegisterSignal(new_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move)) + RegisterSignal(new_loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move)) + RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(finish_end)) + RegisterSignal(finisher, COMSIG_MOB_STATCHANGE, PROC_REF(stat_changed)) + RegisterSignal(finisher, COMSIG_LIVING_UPDATED_RESTING, PROC_REF(update_resting)) + + SEND_SIGNAL(finisher, COMSIG_STARTED_FINISH) + +/datum/action/cooldown/necro/finish/proc/on_target_loc_entered(atom/loc, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + SIGNAL_HANDLER + if(arrived != owner) + return + on_bump(owner, target_atom) + +/datum/action/cooldown/necro/finish/proc/pre_move(datum) + SIGNAL_HANDLER + actively_moving = TRUE + +/datum/action/cooldown/necro/finish/proc/post_move(datum) + SIGNAL_HANDLER + actively_moving = FALSE + +/datum/action/cooldown/necro/finish/proc/finish_end(datum/move_loop/source) + SIGNAL_HANDLER + var/mob/living/carbon/human/necromorph/finisher = source.moving + UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_STATCHANGE, COMSIG_LIVING_UPDATED_RESTING)) + finisher.charging = FALSE + finisher.remove_movespeed_modifier(/datum/movespeed_modifier/necro_finish) + StartCooldown() + SEND_SIGNAL(owner, COMSIG_FINISHED_FINISH) + + qdel(GetComponent(/datum/component/connect_loc_behalf)) + target_atom = null + +/datum/action/cooldown/necro/finish/proc/stat_changed(mob/source, new_stat, old_stat) + SIGNAL_HANDLER + if(new_stat > CONSCIOUS) + SSmove_manager.stop_looping(owner) + +/datum/action/cooldown/necro/finish/proc/do_finish_indicator(atom/finish_target) + return + +/datum/action/cooldown/necro/finish/proc/on_move(atom/source, atom/new_loc) + SIGNAL_HANDLER + if(!actively_moving) + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + +/datum/action/cooldown/necro/finish/proc/on_moved(atom/source) + SIGNAL_HANDLER + var/mob/living/carbon/human/necromorph/finisher = source + if(++valid_steps_taken <= max_steps_buildup) + finisher.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/necro_finish, TRUE, -FINISH_SPEED(src)) + + //Light shake with each step + shake_camera(source, 1.5, 0.5) + + return + +/datum/action/cooldown/necro/finish/proc/on_bump(atom/movable/source, atom/target) + SIGNAL_HANDLER + if(ismob(target) || target.uses_integrity) + hit_target(source, target) + SSmove_manager.stop_looping(owner) + +/datum/action/cooldown/necro/finish/proc/hit_target(mob/living/carbon/human/necromorph/source, mob/living/target) + target.attack_necromorph(source, dealt_damage = finish_damage) + if(isliving(target)) + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + if(human_target.check_shields(source, 0, "the [source.name]", attack_type = LEAP_ATTACK)) + source.Stun(6) + shake_camera(source, 4, 3) + shake_camera(target, 2, 1) + return + shake_camera(target, 4, 3) + shake_camera(source, 2, 3) + target.visible_message("[source] slams into [target]!", "[source] tramples you into the ground!") + target.Knockdown(6) + else + source.visible_message(span_danger("[source] smashes into [target]!")) + shake_camera(source, 4, 3) + source.Stun(6) + +/datum/action/cooldown/necro/finish/proc/update_resting(atom/movable/source, resting) + SIGNAL_HANDLER + if(resting) + SSmove_manager.stop_looping(source) + +/*<--------------------------------------------------------------------------------------------------------------------> + + +E X A M P L E O F F I N I S H E R + + +<--------------------------------------------------------------------------------------------------------------------> + +/*-------------------------------- + The Kiss of Death +--------------------------------*/ + + +/* + The tripod's execution move. + -Pins the target down with an impaling claw + -Screams + -Forces its huge tongue down the victim's throat (muting them at this point) + -Pulls the tongue out rapidly, tearing the victim's head off (finisher stage) + -Tear the victim in half at the waist (post finisher) + + Requires the target to be lying down in order to start + Requires us to have the tongue and at least one arm intact +*/ +/mob/living/carbon/human/proc/tripod_kiss(var/mob/living/carbon/human/target) + set name = "Finisher" + set desc = "A finisher against the weakened" + set category = "Abilities" + + if (!istype(target) || target.stat == DEAD || !target.lying) + target = null + var/list/possible_targets = get_valid_target(origin = src, + radius = 1, + valid_types = list(/mob/living/carbon/human), + allied = list(src, FALSE), + visualnet = null, + require_corruption = FALSE, + view_limit = TRUE, + LOS_block = FALSE, + num_required = 0, + special_check = null) + + for (var/mob/living/carbon/human/H in possible_targets) + if (H.stat == DEAD && H.lying) + target = H + break + + if (!target) + return + + if (target.is_necromorph()) + return + + perform_execution(/datum/extension/execution/tripod_kiss, target) + + + + + + +/datum/extension/execution/tripod_kiss + name = "Kiss of Death" + base_type = /datum/extension/execution/tripod_kiss + cooldown = 1 MINUTE + + reward_biomass = 50 + reward_energy = 150 + reward_heal = 40 + + all_stages = list(/datum/execution_stage/tripod_claw_pin, + /datum/execution_stage/tripod_scream, + /datum/execution_stage/tripod_tongue_force, + /datum/execution_stage/finisher/tripod_tongue_pull, + /datum/execution_stage/tripod_bisect) + + + statmods = list(STATMOD_EVASION = -100, STATMOD_VIEW_RANGE = -6, STATMOD_INCOMING_DAMAGE_MULTIPLICATIVE = EXECUTION_DAMAGE_VULNERABILITY) + + +/datum/extension/execution/tripod_kiss/interrupt() + .=..() + user.play_species_audio(src, SOUND_PAIN, VOLUME_MID, 1, 2) + +/datum/extension/execution/tripod_kiss/can_start() + //Lets check that we have what we need + + //The victim must be lying on the floor + if (!victim.lying) + return FALSE + + //We need our tongue still attached + var/obj/item/organ/external/tongue = user.get_organ(BP_HEAD) + if (!LAZYLIMB(tongue)) + return FALSE + + //We require at least one arm intact + var/obj/item/organ/external/arm/left = user.get_organ(BP_L_ARM) + var/obj/item/organ/external/arm/right = user.get_organ(BP_R_ARM) + if (!LAZYLIMB(left) && !LAZYLIMB(right)) + return FALSE + + .=..() + +/datum/extension/execution/tripod_kiss/acquire_target() + + .=..() + if (.) + //We must face sideways to perform this move. + if (victim.x > user.x) + user.facedir(EAST) + else + user.facedir(WEST) + + //We extend our tongue indefinitely + var/obj/item/organ/external/arm/tentacle/tripod_tongue/E = user.get_organ(BP_HEAD) + if (!istype(E) || E.is_stump()) + return + E.extend() + + +/datum/extension/execution/tripod_kiss/stop() + .=..() + //Once we're done, we'll retract the tongue after some time + var/obj/item/organ/external/arm/tentacle/tripod_tongue/E = user.get_organ(BP_HEAD) + if (!istype(E) || E.is_stump()) + return + //We call extend_for even though its already extended, this will set a timer to retract it + E.extend_for(TONGUE_EXTEND_TIME) + + + + + +//Claw pin: Deals some heavy damage and stuns the victim +//---------------------------------------------------- +/datum/execution_stage/tripod_claw_pin + duration = 3 SECOND + +//Rises up into the air then comes down upon the victim fast +/datum/execution_stage/tripod_claw_pin/enter() + .=..() + animate(host.user, pixel_y = host.user.pixel_y + 16, time = duration * 0.7) + animate(pixel_y = host.user.pixel_y - 18, time = duration * 0.3, easing = BACK_EASING) + spawn(duration*0.9) + + //After a delay we must redo safety checks + if (host.safety_check() == EXECUTION_CONTINUE) + //Okay lets hit 'em + host.victim.apply_damage(25, BRUTE, BP_GROIN, 0, DAM_SHARP, host.user) + host.victim.Stun(8) + host.victim.Weaken(8) //Lets make sure they stay down + host.user.visible_message(SPAN_EXECUTION("[host.user] impales [host.victim] through the groin with a vast claw, pinning them to the floor!")) + playsound(host.victim, 'sound/weapons/slice.ogg', VOLUME_MID, 1) + + +/datum/execution_stage/tripod_claw_pin/interrupt() + + host.victim.stunned = 0 + host.victim.weakened = 0 + + + + + +//Scream: Just calls shout_long, no stun to self +//---------------------------------------------------- +/datum/execution_stage/tripod_scream + duration = 2 SECOND + +/datum/execution_stage/tripod_scream/enter() + .=..() + host.user.do_shout(SOUND_SHOUT_LONG, FALSE) + + + + + +//Tongue Force: Slowly forces the tongue into the victim's mouth +//Animation makes the user go down and tilt forward +//---------------------------------------------------- +/datum/execution_stage/tripod_tongue_force + duration = 5 SECOND + +/datum/execution_stage/tripod_tongue_force/enter() + .=..() + //We will gradually tilt forward + var/angle = 30 + if (host.user.dir & WEST) + angle *= -1 + animate(host.user, pixel_y = host.user.pixel_y - 16, transform = turn(host.user.get_default_transform(), angle), time = duration) + + //You can't speak with a massive sword-like tongue down your throat + host.victim.silent += 10 + + host.user.visible_message(SPAN_EXECUTION("[host.user] starts forcing its tongue down [host.victim]'s throat!")) + spawn(8) + var/tonguesound = pick(list('sound/effects/creatures/necromorph/tripod/tripod_tongueforce_1.ogg', + 'sound/effects/creatures/necromorph/tripod/tripod_tongueforce_2.ogg', + 'sound/effects/creatures/necromorph/tripod/tripod_tongueforce_3.ogg')) + playsound(host.victim, tonguesound, VOLUME_LOUD, TRUE) + + +/datum/execution_stage/tripod_tongue_force/interrupt() + + host.victim.silent =0 + +// https://bigmemes.funnyjunk.com/pictures/Long+boi_073bf6_7722185.jpg + + +//Tongue Pull: Rips the tongue out sharply, victim's head is torn off +//Animation makes the user go down and tilt forward +//---------------------------------------------------- +/datum/execution_stage/finisher/tripod_tongue_pull + duration = 2 SECOND + +/datum/execution_stage/finisher/tripod_tongue_pull/enter() + .=..() + var/angle = -55 + if (host.user.dir & WEST) + angle *= -1 + + //Swing back and up like a shampoo advert + animate(host.user, pixel_y = host.user.pixel_y + 12, transform = turn(host.user.get_default_transform(), angle*0.3), time = 6, easing = BACK_EASING) + animate(pixel_y = host.user.pixel_y + 12, transform = turn(host.user.get_default_transform(), angle*0.6), time = 6,) + + spawn(4) + var/obj/item/organ/external/head = host.victim.get_organ(BP_HEAD) + if (istype(head)) + head.droplimb(cutter = host.user) + host.user.visible_message(SPAN_EXECUTION("[host.user] whips back, violently tearing [host.victim]'s head off!")) + + var/sound_effect = pick(list('sound/effects/organic/flesh_tear_1.ogg', + 'sound/effects/organic/flesh_tear_2.ogg', + 'sound/effects/organic/flesh_tear_3.ogg',)) + playsound(host.victim, sound_effect, VOLUME_MID, TRUE) + + + + .=..() + + + + +//Tongue Pull: Rips the tongue out sharply, victim's head is torn off +//Animation makes the user go down and tilt forward +//---------------------------------------------------- +/datum/execution_stage/tripod_bisect + duration = 5 SECOND + +/datum/execution_stage/tripod_bisect/enter() + .=..() + var/x_offset = -48 + var/angle = 30 + if (host.user.dir & WEST) + angle *= -1 + x_offset *= -1 + + var/slamtime = 8 + //Slam down one last time + animate(host.user, pixel_y = host.user.default_pixel_y - 8, transform = turn(host.user.get_default_transform(), angle*-0.2), time = slamtime, easing = BACK_EASING) + animate(host.user, pixel_y = host.user.default_pixel_y - 8, transform = turn(host.user.get_default_transform(), angle*1.2), time = slamtime) + + //Pause briefly + animate(time = 6) + //And then pull back to tear off the lower body + animate(pixel_x = host.user.pixel_x + x_offset, time = 10, easing = CIRCULAR_EASING) + + spawn(slamtime+6) + if (host.safety_check() == EXECUTION_CONTINUE) + var/obj/item/organ/external/groin = host.victim.get_organ(BP_GROIN) + if (istype(groin)) + groin.droplimb(cutter = host.user) + host.user.visible_message(SPAN_EXECUTION("[host.user] drags its massive claw backwards, brutally tearing [host.victim] in half!")) + var/sound_effect = pick(list('sound/effects/organic/flesh_tear_1.ogg', + 'sound/effects/organic/flesh_tear_2.ogg', + 'sound/effects/organic/flesh_tear_3.ogg',)) + playsound(host.victim, sound_effect, VOLUME_HIGH, TRUE) + +/datum/species/necromorph/tripod/make_scary(mob/living/carbon/human/H) + //H.set_traumatic_sight(TRUE, 5) //All necrmorphs are scary. Some are more scary than others though +*/ From 999611c3424fa196f275dc7fb38586c1708cca42 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Thu, 28 Sep 2023 01:45:04 +0200 Subject: [PATCH 02/13] mess4later --- .../code/necromorph/abilities/finisher.dm | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index dc842500b0c..887a6dee304 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -11,14 +11,28 @@ var/finisher_time = 4 SECONDS /// The initial damage the finisher does to the head limb trying to rip it off var/finisher_damage = 50 - // If the finisher fails to keep the victim in their clutches - var/finisher_stagger = 2 SECONDS + /// If the victim breaks out of the finisher clutches + var/finisher_stagger = 4 SECONDS /// If the current move is being triggered by us or not var/actively_moving = FALSE var/valid_steps_taken = 0 - + var/max_steps_buildup = 2 var/atom/target_atom + + var/force_time = 0 //How long are we forced to stay curled up? There should always be a minimum on this to prevent spam. It shouldn't be + var/automatic = FALSE //Did we curl up manually or automatically + var/animtime = 1 SECOND //How long the animation to curl/uncurl actually takes + + //Extra runtime vars + var/started_at = 0 //When did we curl up + var/stopped_at = 0 //When did we uncurl + var/cached_pixels_x + var/cached_pixels_y + var/matrix/cached_transform + var/force_cooldown_timer + var/force_notify_timer + /datum/action/cooldown/necro/finisher/PreActivate(atom/target) var/turf/T = get_turf(target) if(!T) @@ -139,6 +153,19 @@ var/turf/T = get_turf(target) shake_camera(source, 4, 3) source.Stun(6) + + + +/datum/action/cooldown/necro/finish/proc/finishing() + + .=..() + if (.) + //We must face sideways to perform this move. + if (source.x > source.x) + source.facedir(EAST) + else + source.facedir(WEST) + /datum/action/cooldown/necro/finish/proc/update_resting(atom/movable/source, resting) SIGNAL_HANDLER if(resting) From b1e5d7f0847d5db601cfaaaa2c882c8eb3ddf646 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Fri, 29 Sep 2023 05:48:26 +0200 Subject: [PATCH 03/13] making things call things properly --- .../code/necromorph/abilities/finisher.dm | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 887a6dee304..ac6a71a2a5b 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -1,7 +1,7 @@ -/datum/action/cooldown/necro/finish - name = "Finish" +/datum/action/cooldown/necro/finisher + name = "finisher" desc = "Allows you to deal extraordinary amounts of damage to weakened humans, guarantees death of its victims upon completion." cooldown_time = 2 SECONDS click_to_activate = TRUE @@ -51,11 +51,11 @@ var/turf/T = get_turf(target) /datum/action/cooldown/necro/finisher/Activate(atom/target) . = TRUE - // Start pre-cooldown so that the ability can't come up while the finish is happening + // Start pre-cooldown so that the ability can't come up while the finisher is happening StartCooldown(finisher_time+finisher_delay+1) addtimer(CALLBACK(src, PROC_REF(do_finisher)), finisher_delay) -/datum/action/cooldown/necro/finish/proc/do_finisher() +/datum/action/cooldown/necro/finisher/proc/do_finisher() var/mob/living/carbon/human/necromorph/finisher = owner actively_moving = FALSE @@ -72,70 +72,70 @@ var/turf/T = get_turf(target) return RegisterSignal(new_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move)) RegisterSignal(new_loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move)) - RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(finish_end)) + RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(finisher_end)) RegisterSignal(finisher, COMSIG_MOB_STATCHANGE, PROC_REF(stat_changed)) RegisterSignal(finisher, COMSIG_LIVING_UPDATED_RESTING, PROC_REF(update_resting)) SEND_SIGNAL(finisher, COMSIG_STARTED_FINISH) -/datum/action/cooldown/necro/finish/proc/on_target_loc_entered(atom/loc, atom/movable/arrived, atom/old_loc, list/atom/old_locs) +/datum/action/cooldown/necro/finisher/proc/on_target_loc_entered(atom/loc, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER if(arrived != owner) return on_bump(owner, target_atom) -/datum/action/cooldown/necro/finish/proc/pre_move(datum) +/datum/action/cooldown/necro/finisher/proc/pre_move(datum) SIGNAL_HANDLER actively_moving = TRUE -/datum/action/cooldown/necro/finish/proc/post_move(datum) +/datum/action/cooldown/necro/finisher/proc/post_move(datum) SIGNAL_HANDLER actively_moving = FALSE -/datum/action/cooldown/necro/finish/proc/finish_end(datum/move_loop/source) +/datum/action/cooldown/necro/finisher/proc/finisher_end(datum/move_loop/source) SIGNAL_HANDLER var/mob/living/carbon/human/necromorph/finisher = source.moving UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_STATCHANGE, COMSIG_LIVING_UPDATED_RESTING)) finisher.charging = FALSE - finisher.remove_movespeed_modifier(/datum/movespeed_modifier/necro_finish) + finisher.remove_movespeed_modifier(/datum/movespeed_modifier/necro_finisher) StartCooldown() SEND_SIGNAL(owner, COMSIG_FINISHED_FINISH) qdel(GetComponent(/datum/component/connect_loc_behalf)) target_atom = null -/datum/action/cooldown/necro/finish/proc/stat_changed(mob/source, new_stat, old_stat) +/datum/action/cooldown/necro/finisher/proc/stat_changed(mob/source, new_stat, old_stat) SIGNAL_HANDLER if(new_stat > CONSCIOUS) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finish/proc/do_finish_indicator(atom/finish_target) +/datum/action/cooldown/necro/finisher/proc/do_finish_indicator(atom/finisher_target) return -/datum/action/cooldown/necro/finish/proc/on_move(atom/source, atom/new_loc) +/datum/action/cooldown/necro/finisher/proc/on_move(atom/source, atom/new_loc) SIGNAL_HANDLER if(!actively_moving) return COMPONENT_MOVABLE_BLOCK_PRE_MOVE -/datum/action/cooldown/necro/finish/proc/on_moved(atom/source) +/datum/action/cooldown/necro/finisher/proc/on_moved(atom/source) SIGNAL_HANDLER var/mob/living/carbon/human/necromorph/finisher = source if(++valid_steps_taken <= max_steps_buildup) - finisher.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/necro_finish, TRUE, -FINISH_SPEED(src)) + finisher.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/necro_finisher, TRUE, -FINISH_SPEED(src)) //Light shake with each step shake_camera(source, 1.5, 0.5) return -/datum/action/cooldown/necro/finish/proc/on_bump(atom/movable/source, atom/target) +/datum/action/cooldown/necro/finisher/proc/on_bump(atom/movable/source, atom/target) SIGNAL_HANDLER if(ismob(target) || target.uses_integrity) hit_target(source, target) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finish/proc/hit_target(mob/living/carbon/human/necromorph/source, mob/living/target) - target.attack_necromorph(source, dealt_damage = finish_damage) +/datum/action/cooldown/necro/finisher/proc/hit_target(mob/living/carbon/human/necromorph/source, mob/living/target) + target.attack_necromorph(source, dealt_damage = finisher_damage) if(isliving(target)) if(ishuman(target)) var/mob/living/carbon/human/human_target = target @@ -156,7 +156,7 @@ var/turf/T = get_turf(target) -/datum/action/cooldown/necro/finish/proc/finishing() +/datum/action/cooldown/necro/finisher/proc/finishing() .=..() if (.) @@ -166,7 +166,7 @@ var/turf/T = get_turf(target) else source.facedir(WEST) -/datum/action/cooldown/necro/finish/proc/update_resting(atom/movable/source, resting) +/datum/action/cooldown/necro/finisher/proc/update_resting(atom/movable/source, resting) SIGNAL_HANDLER if(resting) SSmove_manager.stop_looping(source) From 19f8414e52a8f49d7bcfb7ee3e42cbfe6ee2193e Mon Sep 17 00:00:00 2001 From: Greedycore Date: Sun, 1 Oct 2023 04:17:37 +0200 Subject: [PATCH 04/13] finishing a finisher needs it to be finished --- .../code/necromorph/abilities/finisher.dm | 61 ++++++++++++------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index ac6a71a2a5b..16586caf807 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -1,4 +1,4 @@ - +/* This is a finisher, it's supposed to be used against vulnurable survivors that are incapable of resisting the onslaught of necromorphs*/ /datum/action/cooldown/necro/finisher name = "finisher" @@ -6,33 +6,33 @@ cooldown_time = 2 SECONDS click_to_activate = TRUE /// Delay before the finisher actually occurs - var/finisher_delay = 2 SECONDS - /// The maximum amount of time we can finisher - var/finisher_time = 4 SECONDS - /// The initial damage the finisher does to the head limb trying to rip it off - var/finisher_damage = 50 + var/finisher_delay = 1 SECOND + /// The time when we started finishing the target for a finisher + var/finisher_start + /// The maximum amount of time we're finishing the target for a finisher + var/finisher_end + /// Every second the target hasn't broken out of the finisher grapple, this amount of damage is dealt to the cranium + var/finisher_damage = 30 /// If the victim breaks out of the finisher clutches - var/finisher_stagger = 4 SECONDS + var/finisher_stagger = 3 SECONDS /// If the current move is being triggered by us or not var/actively_moving = FALSE var/valid_steps_taken = 0 + var/speed_per_step = 0.50 var/max_steps_buildup = 2 var/atom/target_atom - - var/force_time = 0 //How long are we forced to stay curled up? There should always be a minimum on this to prevent spam. It shouldn't be - var/automatic = FALSE //Did we curl up manually or automatically - var/animtime = 1 SECOND //How long the animation to curl/uncurl actually takes - - //Extra runtime vars - var/started_at = 0 //When did we curl up - var/stopped_at = 0 //When did we uncurl + var/exegrab_anim = 0.5 SECOND //How long the animation to initiate an execution grapple + var/started_at = 0 //When did we start the execution grapple + var/stopped_at = 0 //When did we stop execution grapple var/cached_pixels_x var/cached_pixels_y var/matrix/cached_transform var/force_cooldown_timer var/force_notify_timer + var/exe_animtime = 1 SECOND //How long the animation to execute actually takes + /datum/action/cooldown/necro/finisher/PreActivate(atom/target) var/turf/T = get_turf(target) if(!T) @@ -47,6 +47,16 @@ var/turf/T = get_turf(target) to_chat(owner, span_notice("You can't peform an execution on a necromorph!")) return FALSE + target_atom = target + + if(isturf(target)) + RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_target_loc_entered)) + else + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(on_target_loc_entered), + ) + AddComponent(/datum/component/connect_loc_behalf, target, loc_connections) + return ..() /datum/action/cooldown/necro/finisher/Activate(atom/target) @@ -59,20 +69,20 @@ var/turf/T = get_turf(target) var/mob/living/carbon/human/necromorph/finisher = owner actively_moving = FALSE - finisher.finishing = TRUE + finisher.moving = TRUE RegisterSignal(finisher, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump)) RegisterSignal(finisher, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) RegisterSignal(finisher, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) finisher.setDir(get_dir(finisher, target_atom)) do_finisher_indicator(target_atom) - var/datum/move_loop/new_loop = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) + var/datum/finisher/finishing = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) if(!new_loop) UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED)) return RegisterSignal(new_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move)) RegisterSignal(new_loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move)) - RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(finisher_end)) + RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(move_end)) RegisterSignal(finisher, COMSIG_MOB_STATCHANGE, PROC_REF(stat_changed)) RegisterSignal(finisher, COMSIG_LIVING_UPDATED_RESTING, PROC_REF(update_resting)) @@ -92,11 +102,11 @@ var/turf/T = get_turf(target) SIGNAL_HANDLER actively_moving = FALSE -/datum/action/cooldown/necro/finisher/proc/finisher_end(datum/move_loop/source) +/datum/action/cooldown/necro/finisher/proc/move_end(datum/move_loop/source) SIGNAL_HANDLER var/mob/living/carbon/human/necromorph/finisher = source.moving UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_STATCHANGE, COMSIG_LIVING_UPDATED_RESTING)) - finisher.charging = FALSE + finisher.moving = FALSE finisher.remove_movespeed_modifier(/datum/movespeed_modifier/necro_finisher) StartCooldown() SEND_SIGNAL(owner, COMSIG_FINISHED_FINISH) @@ -146,8 +156,15 @@ var/turf/T = get_turf(target) return shake_camera(target, 4, 3) shake_camera(source, 2, 3) - target.visible_message("[source] slams into [target]!", "[source] tramples you into the ground!") - target.Knockdown(6) + target.visible_message("[source] clasps [target] in its grasp! Teeth digging into the neck!", "[source] clasps you in its arms!
You feel a sharp pain coming from your neck!
") + + finister_start = world.time + finisher_end = world.time + 4 + + if(finisher_start >= finisher_end) + + + else source.visible_message(span_danger("[source] smashes into [target]!")) shake_camera(source, 4, 3) From dff4d3c992b1c0cb3c8edfc7919b2b231d90f68b Mon Sep 17 00:00:00 2001 From: Greedycore Date: Sun, 1 Oct 2023 23:17:11 +0200 Subject: [PATCH 05/13] do_finisher, renaming stuff, descriptions --- .../code/necromorph/abilities/finisher.dm | 73 ++++++++----------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 16586caf807..19f068d23d7 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -1,17 +1,18 @@ /* This is a finisher, it's supposed to be used against vulnurable survivors that are incapable of resisting the onslaught of necromorphs*/ + + /// Every second the target hasn't broken out of the finisher grapple, this amount of damage is dealt to the cranium +#define FINISHER_DAMAGE_PER_SECOND 50 /datum/action/cooldown/necro/finisher name = "finisher" desc = "Allows you to deal extraordinary amounts of damage to weakened humans, guarantees death of its victims upon completion." cooldown_time = 2 SECONDS click_to_activate = TRUE - /// Delay before the finisher actually occurs - var/finisher_delay = 1 SECOND - /// The time when we started finishing the target for a finisher - var/finisher_start - /// The maximum amount of time we're finishing the target for a finisher + /// Delay before the finisher does a rush towards its target to force a grapple + var/rush_delay = 2 SECONDS + /// The maximum amount of time we're rushing the target for a finisher var/finisher_end - /// Every second the target hasn't broken out of the finisher grapple, this amount of damage is dealt to the cranium + /// Initial damage dealt to the target's head when starting the finisher var/finisher_damage = 30 /// If the victim breaks out of the finisher clutches var/finisher_stagger = 3 SECONDS @@ -22,21 +23,15 @@ var/max_steps_buildup = 2 var/atom/target_atom - var/exegrab_anim = 0.5 SECOND //How long the animation to initiate an execution grapple - var/started_at = 0 //When did we start the execution grapple - var/stopped_at = 0 //When did we stop execution grapple - var/cached_pixels_x - var/cached_pixels_y - var/matrix/cached_transform - var/force_cooldown_timer - var/force_notify_timer - - var/exe_animtime = 1 SECOND //How long the animation to execute actually takes + //How long the animation to initiate a finisher grapple + var/exegrab_anim = 0.5 SECONDS + //How long the animation to finish actually takes + var/exe_animtime = 1 SECONDS /datum/action/cooldown/necro/finisher/PreActivate(atom/target) var/turf/T = get_turf(target) if(!T) - to_chat(owner, span_notice("You must target a human to execute them!")) + to_chat(owner, span_notice("You must target a human to finish them!")) return FALSE if(!ishuman(target)) for(var/mob/living/carbon/human/hummie in view(1, T)) @@ -44,7 +39,7 @@ var/turf/T = get_turf(target) target = hummie break if(target == owner || isnecromorph(target)) - to_chat(owner, span_notice("You can't peform an execution on a necromorph!")) + to_chat(owner, span_notice("You can't peform a finisher on a necromorph!")) return FALSE target_atom = target @@ -62,10 +57,10 @@ var/turf/T = get_turf(target) /datum/action/cooldown/necro/finisher/Activate(atom/target) . = TRUE // Start pre-cooldown so that the ability can't come up while the finisher is happening - StartCooldown(finisher_time+finisher_delay+1) - addtimer(CALLBACK(src, PROC_REF(do_finisher)), finisher_delay) + StartCooldown(finisher_time+rush_delay+1) + addtimer(CALLBACK(src, PROC_REF(do_rush)), rush_delay) -/datum/action/cooldown/necro/finisher/proc/do_finisher() +/datum/action/cooldown/necro/finisher/proc/do_rush() var/mob/living/carbon/human/necromorph/finisher = owner actively_moving = FALSE @@ -74,9 +69,9 @@ var/turf/T = get_turf(target) RegisterSignal(finisher, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) RegisterSignal(finisher, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) finisher.setDir(get_dir(finisher, target_atom)) - do_finisher_indicator(target_atom) + do_rush_indicator(target_atom) - var/datum/finisher/finishing = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) + var/datum/finisher/rushing = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) if(!new_loop) UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED)) return @@ -154,35 +149,29 @@ var/turf/T = get_turf(target) shake_camera(source, 4, 3) shake_camera(target, 2, 1) return + ///? Do a grab + RegisterSignal(finisher, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher)) + RegisterSignal(target, COMSIG_LIVING_GET_PULLED, PROC_REF(get_finished)) + shake_camera(target, 4, 3) shake_camera(source, 2, 3) - target.visible_message("[source] clasps [target] in its grasp! Teeth digging into the neck!", "[source] clasps you in its arms!
You feel a sharp pain coming from your neck!
") - - finister_start = world.time - finisher_end = world.time + 4 - - if(finisher_start >= finisher_end) - - + target.visible_message("[source] clasps [target] in its grasp! Teeth ripping into the base of [target]'s neck!", "[source] clasps you in its arms! You feel a sharp pain coming from your neck as [source] digs in!") else source.visible_message(span_danger("[source] smashes into [target]!")) shake_camera(source, 4, 3) source.Stun(6) + ///? Finisher deals progressive damage +/datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, delta_time) + if(target.stat != DEAD || target.health > target.maxHealth * 0.1) + target.adjustBruteLoss(FINISHER_DAMAGE_PER_SECOND * delta_time, TRUE) + return + else +/datum/action/cooldown/necro/finisher/proc/get_finished(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source) + if(target) - -/datum/action/cooldown/necro/finisher/proc/finishing() - - .=..() - if (.) - //We must face sideways to perform this move. - if (source.x > source.x) - source.facedir(EAST) - else - source.facedir(WEST) - /datum/action/cooldown/necro/finisher/proc/update_resting(atom/movable/source, resting) SIGNAL_HANDLER if(resting) From 522d11149813f4021603ab3055bd96db5d9f229e Mon Sep 17 00:00:00 2001 From: Greedycore Date: Tue, 3 Oct 2023 11:45:19 +0200 Subject: [PATCH 06/13] Inspection time help --- .../code/necromorph/abilities/finisher.dm | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 19f068d23d7..282848df6b1 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -7,6 +7,7 @@ name = "finisher" desc = "Allows you to deal extraordinary amounts of damage to weakened humans, guarantees death of its victims upon completion." cooldown_time = 2 SECONDS + rush_time = 4 SECONDS click_to_activate = TRUE /// Delay before the finisher does a rush towards its target to force a grapple var/rush_delay = 2 SECONDS @@ -26,7 +27,7 @@ //How long the animation to initiate a finisher grapple var/exegrab_anim = 0.5 SECONDS //How long the animation to finish actually takes - var/exe_animtime = 1 SECONDS + var/exe_anim = 1 SECONDS /datum/action/cooldown/necro/finisher/PreActivate(atom/target) var/turf/T = get_turf(target) @@ -57,7 +58,7 @@ var/turf/T = get_turf(target) /datum/action/cooldown/necro/finisher/Activate(atom/target) . = TRUE // Start pre-cooldown so that the ability can't come up while the finisher is happening - StartCooldown(finisher_time+rush_delay+1) + StartCooldown(rush_time+rush_delay+1) addtimer(CALLBACK(src, PROC_REF(do_rush)), rush_delay) /datum/action/cooldown/necro/finisher/proc/do_rush() @@ -114,7 +115,7 @@ var/turf/T = get_turf(target) if(new_stat > CONSCIOUS) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finisher/proc/do_finish_indicator(atom/finisher_target) +/datum/action/cooldown/necro/finisher/proc/do_finish_indicator(atom/rush_target) return /datum/action/cooldown/necro/finisher/proc/on_move(atom/source, atom/new_loc) @@ -150,28 +151,32 @@ var/turf/T = get_turf(target) shake_camera(target, 2, 1) return ///? Do a grab - RegisterSignal(finisher, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher)) - RegisterSignal(target, COMSIG_LIVING_GET_PULLED, PROC_REF(get_finished)) - + target.set_pulledby(source) + target.setGrabState(GRAB_AGGRESSIVE) shake_camera(target, 4, 3) shake_camera(source, 2, 3) target.visible_message("[source] clasps [target] in its grasp! Teeth ripping into the base of [target]'s neck!", "[source] clasps you in its arms! You feel a sharp pain coming from your neck as [source] digs in!") - + RegisterSignal(finisher, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher)) else source.visible_message(span_danger("[source] smashes into [target]!")) shake_camera(source, 4, 3) source.Stun(6) ///? Finisher deals progressive damage -/datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, delta_time) - if(target.stat != DEAD || target.health > target.maxHealth * 0.1) - target.adjustBruteLoss(FINISHER_DAMAGE_PER_SECOND * delta_time, TRUE) +/datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source, delta_time) + if(target.pulledby.grab_state == GRAB_AGGRESSIVE && target.stat != DEAD) + ///? do exegrab_anim to grab + finisher_end = world.time + 3 SECONDS + while(world.time <= finisher_end) + target.adjustBruteLoss(FINISHER_DAMAGE_PER_SECOND * delta_time, TRUE)++ + shake_camera(target, 4, 3) + shake_camera(source, 2, 3) return + if(world.time >= finisher_end) + ///? do exe_anim to kill off the target else - -/datum/action/cooldown/necro/finisher/proc/get_finished(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source) - if(target) - - + shake_camera(source, 4, 3) + source.Stun(6) + UnregisterSignal(finisher, list(COMSIG_LIVING_START_PULL)) /datum/action/cooldown/necro/finisher/proc/update_resting(atom/movable/source, resting) SIGNAL_HANDLER if(resting) From 72e8de8d841835b58d146f1a512b71a9fe3f4656 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Tue, 3 Oct 2023 17:41:46 +0200 Subject: [PATCH 07/13] Update finisher.dm --- deadspace/code/necromorph/abilities/finisher.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 282848df6b1..0eb7c7b62bb 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -7,12 +7,11 @@ name = "finisher" desc = "Allows you to deal extraordinary amounts of damage to weakened humans, guarantees death of its victims upon completion." cooldown_time = 2 SECONDS - rush_time = 4 SECONDS click_to_activate = TRUE /// Delay before the finisher does a rush towards its target to force a grapple var/rush_delay = 2 SECONDS /// The maximum amount of time we're rushing the target for a finisher - var/finisher_end + var/rush_time = 3 SECONDS /// Initial damage dealt to the target's head when starting the finisher var/finisher_damage = 30 /// If the victim breaks out of the finisher clutches @@ -23,7 +22,8 @@ var/speed_per_step = 0.50 var/max_steps_buildup = 2 var/atom/target_atom - + /// How long the execution is going to take compared to world.time + var/finisher_end //How long the animation to initiate a finisher grapple var/exegrab_anim = 0.5 SECONDS //How long the animation to finish actually takes From 2059c3ad223abda5183f8c334cd6ba1ffef44306 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Tue, 3 Oct 2023 19:51:00 +0200 Subject: [PATCH 08/13] preparing slasher.dm --- .../necromorphs/subtypes/slasher.dm | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm b/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm index 14d688c3249..889adf08bf6 100644 --- a/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm +++ b/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm @@ -61,3 +61,27 @@ animate(source, transform = new_matrix, pixel_x = source.pixel_x + 5*shake_dir, time = 1) animate(transform = matrix(), pixel_x = source.pixel_x-5*shake_dir, time = 9, easing = ELASTIC_EASING) source.play_necro_sound(SOUND_SHOUT_LONG, VOLUME_HIGH, TRUE, 3) + +/datum/action/cooldown/necro/finisher/slasher + cooldown_time = 12 SECONDS + rush_delay = 2 SECONDS + rush_time = 4 SECONDS + +/datum/action/cooldown/necro/finisher/slasher/do_rush_indicator(atom/rush_target) + var/mob/living/carbon/human/necromorph/source = owner + var/matrix/new_matrix = matrix(source.transform) + var/shake_dir = pick(-1, 1) + new_matrix.Turn(16*shake_dir) + animate(source, transform = new_matrix, pixel_x = source.pixel_x + 5*shake_dir, time = 1) + animate(transform = matrix(), pixel_x = source.pixel_x-5*shake_dir, time = 9, easing = ELASTIC_EASING) + source.play_necro_sound(SOUND_SHOUT_LONG, VOLUME_HIGH, TRUE, 3) + +//bwuh, how +/datum/action/cooldown/necro/finisher/slasher/do_finisher_indicator(atom/finish_target) + var/mob/living/carbon/human/necromorph/source = owner + var/matrix/new_matrix = matrix(source.transform) + var/shake_dir = pick(-1, 1) + new_matrix.Turn(16*shake_dir) + animate(source, transform = new_matrix, pixel_x = source.pixel_x + 5*shake_dir, time = 1) + animate(transform = matrix(), pixel_x = source.pixel_x-5*shake_dir, time = 9, easing = ELASTIC_EASING) + source.play_necro_sound(SOUND_SHOUT_LONG, VOLUME_HIGH, TRUE, 3) From 555539ab28b9da0732367885652369f85bb8c168 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Wed, 4 Oct 2023 01:41:27 +0200 Subject: [PATCH 09/13] descriptions/comments/redecorating/small progress --- deadspace/code/necromorph/abilities/finisher.dm | 8 ++++---- deadspace/code/necromorph/necromorphs/subtypes/slasher.dm | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 0eb7c7b62bb..64e7532b184 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -115,7 +115,7 @@ var/turf/T = get_turf(target) if(new_stat > CONSCIOUS) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finisher/proc/do_finish_indicator(atom/rush_target) +/datum/action/cooldown/necro/finisher/proc/do_rush_indicator(atom/rush_target) return /datum/action/cooldown/necro/finisher/proc/on_move(atom/source, atom/new_loc) @@ -167,16 +167,16 @@ var/turf/T = get_turf(target) ///? do exegrab_anim to grab finisher_end = world.time + 3 SECONDS while(world.time <= finisher_end) + do_finisher_indicator(source, target) target.adjustBruteLoss(FINISHER_DAMAGE_PER_SECOND * delta_time, TRUE)++ - shake_camera(target, 4, 3) - shake_camera(source, 2, 3) return if(world.time >= finisher_end) ///? do exe_anim to kill off the target else + UnregisterSignal(finisher, COMSIG_LIVING_START_PULL) shake_camera(source, 4, 3) + target.visible_message("[target] writhes out of the grasp by [source]! [source] has lost its footing!", "You wriggle out of [source]'s restraint! Your neck relaxes as teeth of [source] are no longer in.") source.Stun(6) - UnregisterSignal(finisher, list(COMSIG_LIVING_START_PULL)) /datum/action/cooldown/necro/finisher/proc/update_resting(atom/movable/source, resting) SIGNAL_HANDLER if(resting) diff --git a/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm b/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm index 889adf08bf6..6405405a363 100644 --- a/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm +++ b/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm @@ -23,6 +23,7 @@ /datum/action/cooldown/necro/charge/slasher = COMSIG_KB_NECROMORPH_ABILITY_CHARGE_DOWN, /datum/action/cooldown/necro/dodge = COMSIG_KB_NECROMORPH_ABILITY_DODGE_DOWN, /datum/action/cooldown/necro/shout = COMSIG_KB_NECROMORPH_ABILITY_SHOUT_DOWN, + /datum/action/cooldown/necro/finisher = COMSIG_KB_NECROMORPH_ABILITY_FINISHER_DOWN, ) minimap_icon = "slasher" implemented = TRUE @@ -77,8 +78,9 @@ source.play_necro_sound(SOUND_SHOUT_LONG, VOLUME_HIGH, TRUE, 3) //bwuh, how -/datum/action/cooldown/necro/finisher/slasher/do_finisher_indicator(atom/finish_target) +/datum/action/cooldown/necro/finisher/slasher/do_finisher_indicator(atom/finish_target, atom/finish_source) var/mob/living/carbon/human/necromorph/source = owner + var/mob/living/carbon/human/target = target var/matrix/new_matrix = matrix(source.transform) var/shake_dir = pick(-1, 1) new_matrix.Turn(16*shake_dir) From 0e275835b76b579bb41d7c3135fc06236aff6cd9 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Wed, 4 Oct 2023 13:04:20 +0200 Subject: [PATCH 10/13] keybinding --- deadspace/code/__DEFINES/keybinding.dm | 1 + deadspace/code/datums/keybindingins/necromorph.dm | 7 +++++++ .../code/necromorph/necromorphs/subtypes/e_slasher.dm | 1 + 3 files changed, 9 insertions(+) diff --git a/deadspace/code/__DEFINES/keybinding.dm b/deadspace/code/__DEFINES/keybinding.dm index a3f4877b205..735406aca9f 100644 --- a/deadspace/code/__DEFINES/keybinding.dm +++ b/deadspace/code/__DEFINES/keybinding.dm @@ -5,6 +5,7 @@ #define COMSIG_KB_NECROMORPH_ABILITY_CHARGE_DOWN "keybinding_necromorph_ability_charge_down" #define COMSIG_KB_NECROMORPH_ABILITY_DODGE_DOWN "keybinding_necromorph_ability_dodge_down" #define COMSIG_KB_NECROMORPH_ABILITY_SHOUT_DOWN "keybinding_necromorph_ability_shout_down" +#define COMSIG_KB_NECROMORPH_ABILITY_FINISHER_DOWN "keybinding_necromorph_ability_finisher_down" #define COMSIG_KB_NECROMORPH_ABILITY_SHOUT_LONG_DOWN "keybinding_necromorph_ability_shout_long_down" #define COMSIG_KB_NECROMORPH_ABILITY_SCREAM_DOWN "keybinding_necromorph_ability_scream_down" #define COMSIG_KB_NECROMORPH_ABILITY_SENSE_DOWN "keybind_necromorph_ability_sense_down" diff --git a/deadspace/code/datums/keybindingins/necromorph.dm b/deadspace/code/datums/keybindingins/necromorph.dm index 966796d8bd7..a689210b905 100644 --- a/deadspace/code/datums/keybindingins/necromorph.dm +++ b/deadspace/code/datums/keybindingins/necromorph.dm @@ -25,6 +25,13 @@ description = "Shout to disorientate the enemy." keybind_signal = COMSIG_KB_NECROMORPH_ABILITY_SHOUT_DOWN +/datum/keybinding/necromorph/finisher + hotkey_keys = list("Unbound") + name = "use_finisher" + full_name = "Necromorph Finisher" + description = "Attempt a lethal takedown on the enemy." + keybind_signal = COMSIG_KB_NECROMORPH_ABILITY_FINISHER_DOWN + /datum/keybinding/necromorph/longshout hotkey_keys = list("Unbound") name = "use_long_shout" diff --git a/deadspace/code/necromorph/necromorphs/subtypes/e_slasher.dm b/deadspace/code/necromorph/necromorphs/subtypes/e_slasher.dm index d9eec9ecbc6..c72a84107b6 100644 --- a/deadspace/code/necromorph/necromorphs/subtypes/e_slasher.dm +++ b/deadspace/code/necromorph/necromorphs/subtypes/e_slasher.dm @@ -24,6 +24,7 @@ /datum/action/cooldown/necro/dodge/enhanced = COMSIG_KB_NECROMORPH_ABILITY_DODGE_DOWN, /datum/action/cooldown/necro/shout = COMSIG_KB_NECROMORPH_ABILITY_SHOUT_DOWN, /datum/action/cooldown/necro/scream = COMSIG_KB_NECROMORPH_ABILITY_SCREAM_DOWN, + /datum/action/cooldown/necro/finisher = COMSIG_KB_NECROMORPH_ABILITY_FINISHER_DOWN, ) minimap_icon = "e_slasher" implemented = TRUE From d5d6b5516aadbb651409f305f97351d5a5bef156 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Thu, 12 Oct 2023 23:43:10 +0200 Subject: [PATCH 11/13] fixed compiling issues --- daedalus.dme | 1 + .../code/necromorph/abilities/finisher.dm | 360 ++---------------- .../necromorphs/subtypes/slasher.dm | 11 +- 3 files changed, 48 insertions(+), 324 deletions(-) diff --git a/daedalus.dme b/daedalus.dme index 15f04f7c62a..55b6bbc0a1c 100644 --- a/daedalus.dme +++ b/daedalus.dme @@ -4825,6 +4825,7 @@ #include "deadspace\code\necromorph\living.dm" #include "deadspace\code\necromorph\abilities\ability.dm" #include "deadspace\code\necromorph\abilities\charge.dm" +#include "deadspace\code\necromorph\abilities\finisher.dm" #include "deadspace\code\necromorph\abilities\charge_exploder.dm" #include "deadspace\code\necromorph\abilities\curl.dm" #include "deadspace\code\necromorph\abilities\dodge.dm" diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 64e7532b184..6d0d8753f23 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -8,12 +8,12 @@ desc = "Allows you to deal extraordinary amounts of damage to weakened humans, guarantees death of its victims upon completion." cooldown_time = 2 SECONDS click_to_activate = TRUE - /// Delay before the finisher does a rush towards its target to force a grapple - var/rush_delay = 2 SECONDS - /// The maximum amount of time we're rushing the target for a finisher - var/rush_time = 3 SECONDS + /// Delay before the finisher does a charge towards its target to force a grapple + var/charge_delay = 2 SECONDS + /// The maximum amount of time we're delaying chargeing the target for a finisher + var/charge_time = 3 SECONDS /// Initial damage dealt to the target's head when starting the finisher - var/finisher_damage = 30 + var/charge_damage = 30 /// If the victim breaks out of the finisher clutches var/finisher_stagger = 3 SECONDS /// If the current move is being triggered by us or not @@ -23,19 +23,19 @@ var/max_steps_buildup = 2 var/atom/target_atom /// How long the execution is going to take compared to world.time - var/finisher_end + var/finisher_time = 3 SECONDS //How long the animation to initiate a finisher grapple var/exegrab_anim = 0.5 SECONDS //How long the animation to finish actually takes var/exe_anim = 1 SECONDS /datum/action/cooldown/necro/finisher/PreActivate(atom/target) -var/turf/T = get_turf(target) - if(!T) + var/turf/Tr = get_turf(target) + if(!Tr) to_chat(owner, span_notice("You must target a human to finish them!")) return FALSE if(!ishuman(target)) - for(var/mob/living/carbon/human/hummie in view(1, T)) + for(var/mob/living/carbon/human/hummie in view(1, Tr)) if(!isnecromorph(hummie)) target = hummie break @@ -47,9 +47,9 @@ var/turf/T = get_turf(target) if(isturf(target)) RegisterSignal(target, COMSIG_ATOM_ENTERED, PROC_REF(on_target_loc_entered)) - else - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_target_loc_entered), + else + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(on_target_loc_entered), ) AddComponent(/datum/component/connect_loc_behalf, target, loc_connections) @@ -58,31 +58,31 @@ var/turf/T = get_turf(target) /datum/action/cooldown/necro/finisher/Activate(atom/target) . = TRUE // Start pre-cooldown so that the ability can't come up while the finisher is happening - StartCooldown(rush_time+rush_delay+1) - addtimer(CALLBACK(src, PROC_REF(do_rush)), rush_delay) + StartCooldown(charge_time+charge_delay+1) + addtimer(CALLBACK(src, PROC_REF(do_charge)), charge_delay) -/datum/action/cooldown/necro/finisher/proc/do_rush() +/datum/action/cooldown/necro/finisher/proc/do_charge() var/mob/living/carbon/human/necromorph/finisher = owner actively_moving = FALSE - finisher.moving = TRUE + finisher.charging = TRUE RegisterSignal(finisher, COMSIG_MOVABLE_BUMP, PROC_REF(on_bump)) RegisterSignal(finisher, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) RegisterSignal(finisher, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) finisher.setDir(get_dir(finisher, target_atom)) do_rush_indicator(target_atom) - var/datum/finisher/rushing = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) + var/datum/move_loop/new_loop = SSmove_manager.move_towards(finisher, target_atom, priority = MOVEMENT_ABOVE_SPACE_PRIORITY) if(!new_loop) UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED)) return RegisterSignal(new_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move)) RegisterSignal(new_loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move)) - RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(move_end)) + RegisterSignal(new_loop, COMSIG_MOVELOOP_STOP, PROC_REF(charge_end)) RegisterSignal(finisher, COMSIG_MOB_STATCHANGE, PROC_REF(stat_changed)) RegisterSignal(finisher, COMSIG_LIVING_UPDATED_RESTING, PROC_REF(update_resting)) - SEND_SIGNAL(finisher, COMSIG_STARTED_FINISH) + SEND_SIGNAL(finisher, COMSIG_STARTED_CHARGE) /datum/action/cooldown/necro/finisher/proc/on_target_loc_entered(atom/loc, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER @@ -98,14 +98,14 @@ var/turf/T = get_turf(target) SIGNAL_HANDLER actively_moving = FALSE -/datum/action/cooldown/necro/finisher/proc/move_end(datum/move_loop/source) +/datum/action/cooldown/necro/finisher/proc/charge_end(datum/move_loop/source) SIGNAL_HANDLER var/mob/living/carbon/human/necromorph/finisher = source.moving UnregisterSignal(finisher, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_PRE_MOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_STATCHANGE, COMSIG_LIVING_UPDATED_RESTING)) - finisher.moving = FALSE - finisher.remove_movespeed_modifier(/datum/movespeed_modifier/necro_finisher) + finisher.charging = FALSE + finisher.remove_movespeed_modifier(/datum/movespeed_modifier/necro_charge) StartCooldown() - SEND_SIGNAL(owner, COMSIG_FINISHED_FINISH) + SEND_SIGNAL(owner, COMSIG_FINISHED_CHARGE) qdel(GetComponent(/datum/component/connect_loc_behalf)) target_atom = null @@ -115,7 +115,7 @@ var/turf/T = get_turf(target) if(new_stat > CONSCIOUS) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finisher/proc/do_rush_indicator(atom/rush_target) +/datum/action/cooldown/necro/finisher/proc/do_rush_indicator(atom/charge_target) return /datum/action/cooldown/necro/finisher/proc/on_move(atom/source, atom/new_loc) @@ -127,7 +127,7 @@ var/turf/T = get_turf(target) SIGNAL_HANDLER var/mob/living/carbon/human/necromorph/finisher = source if(++valid_steps_taken <= max_steps_buildup) - finisher.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/necro_finisher, TRUE, -FINISH_SPEED(src)) + finisher.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/necro_charge, TRUE, -CHARGE_SPEED(src)) //Light shake with each step shake_camera(source, 1.5, 0.5) @@ -141,7 +141,7 @@ var/turf/T = get_turf(target) SSmove_manager.stop_looping(owner) /datum/action/cooldown/necro/finisher/proc/hit_target(mob/living/carbon/human/necromorph/source, mob/living/target) - target.attack_necromorph(source, dealt_damage = finisher_damage) + target.attack_necromorph(source, dealt_damage = charge_damage) if(isliving(target)) if(ishuman(target)) var/mob/living/carbon/human/human_target = target @@ -156,310 +156,34 @@ var/turf/T = get_turf(target) shake_camera(target, 4, 3) shake_camera(source, 2, 3) target.visible_message("[source] clasps [target] in its grasp! Teeth ripping into the base of [target]'s neck!", "[source] clasps you in its arms! You feel a sharp pain coming from your neck as [source] digs in!") - RegisterSignal(finisher, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher)) + RegisterSignal(target, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher)) else source.visible_message(span_danger("[source] smashes into [target]!")) shake_camera(source, 4, 3) source.Stun(6) ///? Finisher deals progressive damage /datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source, delta_time) - if(target.pulledby.grab_state == GRAB_AGGRESSIVE && target.stat != DEAD) - ///? do exegrab_anim to grab - finisher_end = world.time + 3 SECONDS - while(world.time <= finisher_end) + if(target.pulledby.grab_state == GRAB_AGGRESSIVE) + var/finisher_end = world.time + finisher_time + var/obj/item/bodypart/target_head = target.get_bodypart(BODY_ZONE_HEAD) + if(world.time < finisher_end && target.stat != DEAD) + target.apply_damage(FINISHER_DAMAGE_PER_SECOND * delta_time, BRUTE, target_head) + ///? do exegrab_anim to grab do_finisher_indicator(source, target) - target.adjustBruteLoss(FINISHER_DAMAGE_PER_SECOND * delta_time, TRUE)++ - return - if(world.time >= finisher_end) - ///? do exe_anim to kill off the target + return + ///? do exe_anim to kill off the target + if(world.time >= finisher_end && target.stat != DEAD) + target.apply_damage(400, BRUTE, target_head) else - UnregisterSignal(finisher, COMSIG_LIVING_START_PULL) shake_camera(source, 4, 3) target.visible_message("[target] writhes out of the grasp by [source]! [source] has lost its footing!", "You wriggle out of [source]'s restraint! Your neck relaxes as teeth of [source] are no longer in.") source.Stun(6) + UnregisterSignal(source, COMSIG_LIVING_START_PULL) + +/datum/action/cooldown/necro/finisher/proc/do_finisher_indicator(atom/finisher_source, atom/finish_target) + return + /datum/action/cooldown/necro/finisher/proc/update_resting(atom/movable/source, resting) SIGNAL_HANDLER if(resting) SSmove_manager.stop_looping(source) - -/*<--------------------------------------------------------------------------------------------------------------------> - - -E X A M P L E O F F I N I S H E R - - -<--------------------------------------------------------------------------------------------------------------------> - -/*-------------------------------- - The Kiss of Death ---------------------------------*/ - - -/* - The tripod's execution move. - -Pins the target down with an impaling claw - -Screams - -Forces its huge tongue down the victim's throat (muting them at this point) - -Pulls the tongue out rapidly, tearing the victim's head off (finisher stage) - -Tear the victim in half at the waist (post finisher) - - Requires the target to be lying down in order to start - Requires us to have the tongue and at least one arm intact -*/ -/mob/living/carbon/human/proc/tripod_kiss(var/mob/living/carbon/human/target) - set name = "Finisher" - set desc = "A finisher against the weakened" - set category = "Abilities" - - if (!istype(target) || target.stat == DEAD || !target.lying) - target = null - var/list/possible_targets = get_valid_target(origin = src, - radius = 1, - valid_types = list(/mob/living/carbon/human), - allied = list(src, FALSE), - visualnet = null, - require_corruption = FALSE, - view_limit = TRUE, - LOS_block = FALSE, - num_required = 0, - special_check = null) - - for (var/mob/living/carbon/human/H in possible_targets) - if (H.stat == DEAD && H.lying) - target = H - break - - if (!target) - return - - if (target.is_necromorph()) - return - - perform_execution(/datum/extension/execution/tripod_kiss, target) - - - - - - -/datum/extension/execution/tripod_kiss - name = "Kiss of Death" - base_type = /datum/extension/execution/tripod_kiss - cooldown = 1 MINUTE - - reward_biomass = 50 - reward_energy = 150 - reward_heal = 40 - - all_stages = list(/datum/execution_stage/tripod_claw_pin, - /datum/execution_stage/tripod_scream, - /datum/execution_stage/tripod_tongue_force, - /datum/execution_stage/finisher/tripod_tongue_pull, - /datum/execution_stage/tripod_bisect) - - - statmods = list(STATMOD_EVASION = -100, STATMOD_VIEW_RANGE = -6, STATMOD_INCOMING_DAMAGE_MULTIPLICATIVE = EXECUTION_DAMAGE_VULNERABILITY) - - -/datum/extension/execution/tripod_kiss/interrupt() - .=..() - user.play_species_audio(src, SOUND_PAIN, VOLUME_MID, 1, 2) - -/datum/extension/execution/tripod_kiss/can_start() - //Lets check that we have what we need - - //The victim must be lying on the floor - if (!victim.lying) - return FALSE - - //We need our tongue still attached - var/obj/item/organ/external/tongue = user.get_organ(BP_HEAD) - if (!LAZYLIMB(tongue)) - return FALSE - - //We require at least one arm intact - var/obj/item/organ/external/arm/left = user.get_organ(BP_L_ARM) - var/obj/item/organ/external/arm/right = user.get_organ(BP_R_ARM) - if (!LAZYLIMB(left) && !LAZYLIMB(right)) - return FALSE - - .=..() - -/datum/extension/execution/tripod_kiss/acquire_target() - - .=..() - if (.) - //We must face sideways to perform this move. - if (victim.x > user.x) - user.facedir(EAST) - else - user.facedir(WEST) - - //We extend our tongue indefinitely - var/obj/item/organ/external/arm/tentacle/tripod_tongue/E = user.get_organ(BP_HEAD) - if (!istype(E) || E.is_stump()) - return - E.extend() - - -/datum/extension/execution/tripod_kiss/stop() - .=..() - //Once we're done, we'll retract the tongue after some time - var/obj/item/organ/external/arm/tentacle/tripod_tongue/E = user.get_organ(BP_HEAD) - if (!istype(E) || E.is_stump()) - return - //We call extend_for even though its already extended, this will set a timer to retract it - E.extend_for(TONGUE_EXTEND_TIME) - - - - - -//Claw pin: Deals some heavy damage and stuns the victim -//---------------------------------------------------- -/datum/execution_stage/tripod_claw_pin - duration = 3 SECOND - -//Rises up into the air then comes down upon the victim fast -/datum/execution_stage/tripod_claw_pin/enter() - .=..() - animate(host.user, pixel_y = host.user.pixel_y + 16, time = duration * 0.7) - animate(pixel_y = host.user.pixel_y - 18, time = duration * 0.3, easing = BACK_EASING) - spawn(duration*0.9) - - //After a delay we must redo safety checks - if (host.safety_check() == EXECUTION_CONTINUE) - //Okay lets hit 'em - host.victim.apply_damage(25, BRUTE, BP_GROIN, 0, DAM_SHARP, host.user) - host.victim.Stun(8) - host.victim.Weaken(8) //Lets make sure they stay down - host.user.visible_message(SPAN_EXECUTION("[host.user] impales [host.victim] through the groin with a vast claw, pinning them to the floor!")) - playsound(host.victim, 'sound/weapons/slice.ogg', VOLUME_MID, 1) - - -/datum/execution_stage/tripod_claw_pin/interrupt() - - host.victim.stunned = 0 - host.victim.weakened = 0 - - - - - -//Scream: Just calls shout_long, no stun to self -//---------------------------------------------------- -/datum/execution_stage/tripod_scream - duration = 2 SECOND - -/datum/execution_stage/tripod_scream/enter() - .=..() - host.user.do_shout(SOUND_SHOUT_LONG, FALSE) - - - - - -//Tongue Force: Slowly forces the tongue into the victim's mouth -//Animation makes the user go down and tilt forward -//---------------------------------------------------- -/datum/execution_stage/tripod_tongue_force - duration = 5 SECOND - -/datum/execution_stage/tripod_tongue_force/enter() - .=..() - //We will gradually tilt forward - var/angle = 30 - if (host.user.dir & WEST) - angle *= -1 - animate(host.user, pixel_y = host.user.pixel_y - 16, transform = turn(host.user.get_default_transform(), angle), time = duration) - - //You can't speak with a massive sword-like tongue down your throat - host.victim.silent += 10 - - host.user.visible_message(SPAN_EXECUTION("[host.user] starts forcing its tongue down [host.victim]'s throat!")) - spawn(8) - var/tonguesound = pick(list('sound/effects/creatures/necromorph/tripod/tripod_tongueforce_1.ogg', - 'sound/effects/creatures/necromorph/tripod/tripod_tongueforce_2.ogg', - 'sound/effects/creatures/necromorph/tripod/tripod_tongueforce_3.ogg')) - playsound(host.victim, tonguesound, VOLUME_LOUD, TRUE) - - -/datum/execution_stage/tripod_tongue_force/interrupt() - - host.victim.silent =0 - -// https://bigmemes.funnyjunk.com/pictures/Long+boi_073bf6_7722185.jpg - - -//Tongue Pull: Rips the tongue out sharply, victim's head is torn off -//Animation makes the user go down and tilt forward -//---------------------------------------------------- -/datum/execution_stage/finisher/tripod_tongue_pull - duration = 2 SECOND - -/datum/execution_stage/finisher/tripod_tongue_pull/enter() - .=..() - var/angle = -55 - if (host.user.dir & WEST) - angle *= -1 - - //Swing back and up like a shampoo advert - animate(host.user, pixel_y = host.user.pixel_y + 12, transform = turn(host.user.get_default_transform(), angle*0.3), time = 6, easing = BACK_EASING) - animate(pixel_y = host.user.pixel_y + 12, transform = turn(host.user.get_default_transform(), angle*0.6), time = 6,) - - spawn(4) - var/obj/item/organ/external/head = host.victim.get_organ(BP_HEAD) - if (istype(head)) - head.droplimb(cutter = host.user) - host.user.visible_message(SPAN_EXECUTION("[host.user] whips back, violently tearing [host.victim]'s head off!")) - - var/sound_effect = pick(list('sound/effects/organic/flesh_tear_1.ogg', - 'sound/effects/organic/flesh_tear_2.ogg', - 'sound/effects/organic/flesh_tear_3.ogg',)) - playsound(host.victim, sound_effect, VOLUME_MID, TRUE) - - - - .=..() - - - - -//Tongue Pull: Rips the tongue out sharply, victim's head is torn off -//Animation makes the user go down and tilt forward -//---------------------------------------------------- -/datum/execution_stage/tripod_bisect - duration = 5 SECOND - -/datum/execution_stage/tripod_bisect/enter() - .=..() - var/x_offset = -48 - var/angle = 30 - if (host.user.dir & WEST) - angle *= -1 - x_offset *= -1 - - var/slamtime = 8 - //Slam down one last time - animate(host.user, pixel_y = host.user.default_pixel_y - 8, transform = turn(host.user.get_default_transform(), angle*-0.2), time = slamtime, easing = BACK_EASING) - animate(host.user, pixel_y = host.user.default_pixel_y - 8, transform = turn(host.user.get_default_transform(), angle*1.2), time = slamtime) - - //Pause briefly - animate(time = 6) - //And then pull back to tear off the lower body - animate(pixel_x = host.user.pixel_x + x_offset, time = 10, easing = CIRCULAR_EASING) - - spawn(slamtime+6) - if (host.safety_check() == EXECUTION_CONTINUE) - var/obj/item/organ/external/groin = host.victim.get_organ(BP_GROIN) - if (istype(groin)) - groin.droplimb(cutter = host.user) - host.user.visible_message(SPAN_EXECUTION("[host.user] drags its massive claw backwards, brutally tearing [host.victim] in half!")) - var/sound_effect = pick(list('sound/effects/organic/flesh_tear_1.ogg', - 'sound/effects/organic/flesh_tear_2.ogg', - 'sound/effects/organic/flesh_tear_3.ogg',)) - playsound(host.victim, sound_effect, VOLUME_HIGH, TRUE) - -/datum/species/necromorph/tripod/make_scary(mob/living/carbon/human/H) - //H.set_traumatic_sight(TRUE, 5) //All necrmorphs are scary. Some are more scary than others though -*/ diff --git a/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm b/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm index 6405405a363..8a2ba5dcca4 100644 --- a/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm +++ b/deadspace/code/necromorph/necromorphs/subtypes/slasher.dm @@ -65,22 +65,21 @@ /datum/action/cooldown/necro/finisher/slasher cooldown_time = 12 SECONDS - rush_delay = 2 SECONDS - rush_time = 4 SECONDS + charge_delay = 2 SECONDS + charge_time = 4 SECONDS -/datum/action/cooldown/necro/finisher/slasher/do_rush_indicator(atom/rush_target) +/datum/action/cooldown/necro/finisher/slasher/do_rush_indicator(atom/charge_target) var/mob/living/carbon/human/necromorph/source = owner var/matrix/new_matrix = matrix(source.transform) - var/shake_dir = pick(-1, 1) + var/shake_dir = pick(-3, 2) new_matrix.Turn(16*shake_dir) animate(source, transform = new_matrix, pixel_x = source.pixel_x + 5*shake_dir, time = 1) animate(transform = matrix(), pixel_x = source.pixel_x-5*shake_dir, time = 9, easing = ELASTIC_EASING) source.play_necro_sound(SOUND_SHOUT_LONG, VOLUME_HIGH, TRUE, 3) //bwuh, how -/datum/action/cooldown/necro/finisher/slasher/do_finisher_indicator(atom/finish_target, atom/finish_source) +/datum/action/cooldown/necro/finisher/slasher/do_finisher_indicator(atom/finish_target) var/mob/living/carbon/human/necromorph/source = owner - var/mob/living/carbon/human/target = target var/matrix/new_matrix = matrix(source.transform) var/shake_dir = pick(-1, 1) new_matrix.Turn(16*shake_dir) From 6ca2f4dbabd0ed2f59bbc0c4058b9ffb0b30020b Mon Sep 17 00:00:00 2001 From: Greedycore Date: Sat, 14 Oct 2023 01:47:25 +0200 Subject: [PATCH 12/13] It worksn't :tm: actually executes something, obvious issue with it executing itself when shuffling on the target's tile? --- .../code/necromorph/abilities/finisher.dm | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 6d0d8753f23..0e4dfc359dc 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -137,10 +137,10 @@ /datum/action/cooldown/necro/finisher/proc/on_bump(atom/movable/source, atom/target) SIGNAL_HANDLER if(ismob(target) || target.uses_integrity) - hit_target(source, target) + start_finish(source, target) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finisher/proc/hit_target(mob/living/carbon/human/necromorph/source, mob/living/target) +/datum/action/cooldown/necro/finisher/proc/start_finish(mob/living/carbon/human/necromorph/source, mob/living/target) target.attack_necromorph(source, dealt_damage = charge_damage) if(isliving(target)) if(ishuman(target)) @@ -150,25 +150,25 @@ shake_camera(source, 4, 3) shake_camera(target, 2, 1) return - ///? Do a grab - target.set_pulledby(source) - target.setGrabState(GRAB_AGGRESSIVE) + ///? Do an aggro grab + target.grabbedby(source) + target.grippedby(source, instant = TRUE) + target.visible_message("[source] clasps [target] in its grasp! Teeth ripping into the base of [target]'s neck!", "[source] clasps you in its arms! You feel a sharp pain coming from your neck as [source] digs in!") shake_camera(target, 4, 3) shake_camera(source, 2, 3) - target.visible_message("[source] clasps [target] in its grasp! Teeth ripping into the base of [target]'s neck!", "[source] clasps you in its arms! You feel a sharp pain coming from your neck as [source] digs in!") - RegisterSignal(target, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher)) + do_finisher(source, target, 5) else source.visible_message(span_danger("[source] smashes into [target]!")) shake_camera(source, 4, 3) source.Stun(6) ///? Finisher deals progressive damage /datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source, delta_time) - if(target.pulledby.grab_state == GRAB_AGGRESSIVE) + if(target.grab_state == GRAB_AGGRESSIVE) var/finisher_end = world.time + finisher_time var/obj/item/bodypart/target_head = target.get_bodypart(BODY_ZONE_HEAD) if(world.time < finisher_end && target.stat != DEAD) target.apply_damage(FINISHER_DAMAGE_PER_SECOND * delta_time, BRUTE, target_head) - ///? do exegrab_anim to grab + ///? do slasher finisher animation do_finisher_indicator(source, target) return ///? do exe_anim to kill off the target @@ -178,7 +178,6 @@ shake_camera(source, 4, 3) target.visible_message("[target] writhes out of the grasp by [source]! [source] has lost its footing!", "You wriggle out of [source]'s restraint! Your neck relaxes as teeth of [source] are no longer in.") source.Stun(6) - UnregisterSignal(source, COMSIG_LIVING_START_PULL) /datum/action/cooldown/necro/finisher/proc/do_finisher_indicator(atom/finisher_source, atom/finish_target) return @@ -187,3 +186,7 @@ SIGNAL_HANDLER if(resting) SSmove_manager.stop_looping(source) + + +/// RegisterSignal(target, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher))???????????? +/// target.attack_necromorph(source, dealt_damage = charge_damage) From 4ad4eef86a5b4a6bc7314f671ebcd5279eaa9035 Mon Sep 17 00:00:00 2001 From: Greedycore Date: Sat, 14 Oct 2023 21:15:31 +0200 Subject: [PATCH 13/13] Test, Condensing Code --- .../code/necromorph/abilities/finisher.dm | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/deadspace/code/necromorph/abilities/finisher.dm b/deadspace/code/necromorph/abilities/finisher.dm index 0e4dfc359dc..c2f71fe5cf2 100644 --- a/deadspace/code/necromorph/abilities/finisher.dm +++ b/deadspace/code/necromorph/abilities/finisher.dm @@ -23,19 +23,19 @@ var/max_steps_buildup = 2 var/atom/target_atom /// How long the execution is going to take compared to world.time - var/finisher_time = 3 SECONDS + var/finisher_time = 5 SECONDS //How long the animation to initiate a finisher grapple var/exegrab_anim = 0.5 SECONDS //How long the animation to finish actually takes var/exe_anim = 1 SECONDS /datum/action/cooldown/necro/finisher/PreActivate(atom/target) - var/turf/Tr = get_turf(target) - if(!Tr) + var/turf/T = get_turf(target) + if(!T) to_chat(owner, span_notice("You must target a human to finish them!")) return FALSE if(!ishuman(target)) - for(var/mob/living/carbon/human/hummie in view(1, Tr)) + for(var/mob/living/carbon/human/hummie in view(1, T)) if(!isnecromorph(hummie)) target = hummie break @@ -140,7 +140,7 @@ start_finish(source, target) SSmove_manager.stop_looping(owner) -/datum/action/cooldown/necro/finisher/proc/start_finish(mob/living/carbon/human/necromorph/source, mob/living/target) +/datum/action/cooldown/necro/finisher/proc/start_finish(mob/living/carbon/human/necromorph/source, mob/living/target, delta_time) target.attack_necromorph(source, dealt_damage = charge_damage) if(isliving(target)) if(ishuman(target)) @@ -150,34 +150,34 @@ shake_camera(source, 4, 3) shake_camera(target, 2, 1) return - ///? Do an aggro grab + /// Do an aggro grab target.grabbedby(source) target.grippedby(source, instant = TRUE) target.visible_message("[source] clasps [target] in its grasp! Teeth ripping into the base of [target]'s neck!", "[source] clasps you in its arms! You feel a sharp pain coming from your neck as [source] digs in!") shake_camera(target, 4, 3) shake_camera(source, 2, 3) - do_finisher(source, target, 5) + /// + if(target.grab_state == GRAB_AGGRESSIVE) + var/finisher_end = world.time + finisher_time + var/obj/item/bodypart/target_head = target.get_bodypart(BODY_ZONE_HEAD) + if(finisher_end > world.time && target.stat != DEAD) + target.adjustBruteLoss(FINISHER_DAMAGE_PER_SECOND * delta_time, BRUTE, target_head) + /// do slasher finisher animation + do_finisher_indicator(source, target) + /// do exe_anim to kill off the target + if(finisher_end <= world.time && target.stat != DEAD) + target.apply_damage(400, BRUTE, target_head) + return + else + shake_camera(source, 4, 3) + target.visible_message("[target] writhes out of the grasp by [source]! [source] has lost its footing!", "You wriggle out of [source]'s restraint! Your neck relaxes as teeth of [source] are no longer in.") + source.Stun(6) + else source.visible_message(span_danger("[source] smashes into [target]!")) shake_camera(source, 4, 3) source.Stun(6) - ///? Finisher deals progressive damage -/datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source, delta_time) - if(target.grab_state == GRAB_AGGRESSIVE) - var/finisher_end = world.time + finisher_time - var/obj/item/bodypart/target_head = target.get_bodypart(BODY_ZONE_HEAD) - if(world.time < finisher_end && target.stat != DEAD) - target.apply_damage(FINISHER_DAMAGE_PER_SECOND * delta_time, BRUTE, target_head) - ///? do slasher finisher animation - do_finisher_indicator(source, target) - return - ///? do exe_anim to kill off the target - if(world.time >= finisher_end && target.stat != DEAD) - target.apply_damage(400, BRUTE, target_head) - else - shake_camera(source, 4, 3) - target.visible_message("[target] writhes out of the grasp by [source]! [source] has lost its footing!", "You wriggle out of [source]'s restraint! Your neck relaxes as teeth of [source] are no longer in.") - source.Stun(6) + /// Finisher deals progressive damage /datum/action/cooldown/necro/finisher/proc/do_finisher_indicator(atom/finisher_source, atom/finish_target) return @@ -190,3 +190,4 @@ /// RegisterSignal(target, COMSIG_LIVING_START_PULL, PROC_REF(do_finisher))???????????? /// target.attack_necromorph(source, dealt_damage = charge_damage) +/// /datum/action/cooldown/necro/finisher/proc/do_finisher(mob/living/carbon/human/target, mob/living/carbon/human/necromorph/source, delta_time)