Skip to content

Commit

Permalink
New Healer Drone Ability: Sacrifice, another go (#5173)
Browse files Browse the repository at this point in the history
# About the pull request

New healer drone skill — sacrifice. If things get really bad, the healer
can instantly transfer 75% of its current health, but for the great cost
of the healer’s own life.

The sacrifice ability is an emergency button. You don’t have to use it,
but at some point you may find that sacrifice is a right thing to do, so
it’s a nice option to have. I want to emphasize that this skill is not a
necessary part of the healer gameplay. You don’t have to trade your life
for the life of another xeno. But you can if you are willing to.

Also healer drones gets a counter of the health it has transferred. If
healer drone transfers at least 10 000 health points, it will be able to
respawn after using the sacrifice ability (like acid runner after
kaboom).

# Explain why it's good for the game

Saving fellow xenos is the most satisfying part of healer drone’s
gameplay. This ability allows to save others in really dire situations,
but for the great cost. It’s still fitting, because drone already can
use heal ability until it goes into crit or dies, in some situations
it’s a worthy risk. Also rewards long living healer drones with the
opportunity to use the ability without dying.

# Testing Photographs and Procedure
<details>
<summary>Screenshots & Videos</summary>

Put screenshots and videos here with an empty line between the
screenshots and the `<details>` tags.

</details>


# Changelog
:cl: ihatethisengine
balance: New healer drone ability — sacrifice. Healer drone can
instantly transfer 75% of its current health, but for the great cost of
the healer’s own life.
/:cl:

---------

Co-authored-by: ihatethisengine <[email protected]>
Co-authored-by: harryob <[email protected]>
Co-authored-by: Drathek <[email protected]>
  • Loading branch information
4 people authored Dec 23, 2023
1 parent 17cbbf5 commit bf41565
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@
action_type = XENO_ACTION_CLICK
ability_primacy = XENO_PRIMARY_ACTION_5

/datum/action/xeno_action/activable/place_construction/queen_macro //so it doesn't screw other macros up
/datum/action/xeno_action/activable/place_construction/not_primary //so it doesn't screw other macros up
ability_primacy = XENO_NOT_PRIMARY_ACTION

/datum/action/xeno_action/activable/xeno_spit
Expand Down
6 changes: 3 additions & 3 deletions code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
/datum/action/xeno_action/onclick/regurgitate,
/datum/action/xeno_action/watch_xeno,
/datum/action/xeno_action/activable/tail_stab,
/datum/action/xeno_action/activable/place_construction/queen_macro, //normally fifth macro but not as important for queen
/datum/action/xeno_action/activable/place_construction/not_primary, //normally fifth macro but not as important for queen
/datum/action/xeno_action/activable/corrosive_acid,
/datum/action/xeno_action/onclick/emit_pheromones,
/datum/action/xeno_action/onclick/queen_word,
Expand Down Expand Up @@ -325,7 +325,7 @@
/datum/action/xeno_action/onclick/regurgitate,
/datum/action/xeno_action/watch_xeno,
/datum/action/xeno_action/activable/tail_stab,
/datum/action/xeno_action/activable/place_construction/queen_macro, //normally fifth macro but not as important for queen
/datum/action/xeno_action/activable/place_construction/not_primary, //normally fifth macro but not as important for queen
/datum/action/xeno_action/activable/corrosive_acid,
/datum/action/xeno_action/onclick/emit_pheromones,
/datum/action/xeno_action/onclick/queen_word,
Expand Down Expand Up @@ -820,7 +820,7 @@
// These already have their placement locked in:
/datum/action/xeno_action/onclick/regurgitate,
/datum/action/xeno_action/watch_xeno,
/datum/action/xeno_action/activable/place_construction/queen_macro,
/datum/action/xeno_action/activable/place_construction/not_primary,
/datum/action/xeno_action/onclick/emit_pheromones,
/datum/action/xeno_action/onclick/queen_word,
/datum/action/xeno_action/onclick/psychic_whisper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
/datum/action/xeno_action/activable/secrete_resin,
/datum/action/xeno_action/onclick/choose_resin,
/datum/action/xeno_action/activable/transfer_plasma,
/datum/action/xeno_action/activable/place_construction, // so it doesn't use fifth macro
/datum/action/xeno_action/onclick/plant_weeds, // so it doesn't break order
)
mutator_actions_to_add = list(
/datum/action/xeno_action/activable/place_construction/not_primary, // so it doesn't use fifth macro
/datum/action/xeno_action/onclick/plant_weeds, // so it doesn't break order
/datum/action/xeno_action/onclick/plant_resin_fruit, // Second macro. Resin fruits belong to Gardener, but Healer has a minor variant.
/datum/action/xeno_action/activable/apply_salve, //Third macro, heal over time ability.
/datum/action/xeno_action/activable/transfer_plasma/healer, //Fourth macro, an improved plasma transfer.
/datum/action/xeno_action/activable/healer_sacrifice, //Fifth macro, the ultimate ability to sacrifice yourself
)
keystone = TRUE
behavior_delegate_type = /datum/behavior_delegate/drone_healer
Expand Down Expand Up @@ -137,8 +142,10 @@
to_chat(target_xeno, SPAN_XENOWARNING("[src] covers our wounds with a regenerative resin salve. We feel reinvigorated!"))
to_chat(src, SPAN_XENOWARNING("We regurgitate our vital fluids and some plasma to create a regenerative resin salve and apply it to [target_xeno]'s wounds. We feel weakened..."))
playsound(src, "alien_drool", 25)
var/datum/behavior_delegate/drone_healer/healer_delegate = src.behavior_delegate
var/datum/behavior_delegate/drone_healer/healer_delegate = behavior_delegate
healer_delegate.salve_applied_recently = TRUE
if(target_xeno.mutation_type != DRONE_HEALER && !isfacehugger(target_xeno)) // no cheap grinding
healer_delegate.modify_transferred(amount * damage_taken_mod)
update_icons()
addtimer(CALLBACK(healer_delegate, /datum/behavior_delegate/drone_healer/proc/un_salve), 10 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE)

Expand All @@ -148,6 +155,9 @@
var/salve_applied_recently = FALSE
var/mutable_appearance/salve_applied_icon

var/transferred_amount = 0
var/required_transferred_amount = 7500

/datum/behavior_delegate/drone_healer/on_update_icons()
if(!salve_applied_icon)
salve_applied_icon = mutable_appearance('icons/mob/xenos/drone_strain_overlays.dmi',"Healer Drone Walking")
Expand All @@ -173,3 +183,122 @@
/datum/behavior_delegate/drone_healer/proc/un_salve()
salve_applied_recently = FALSE
bound_xeno.update_icons()

/*
SACRIFICE
*/

/datum/behavior_delegate/drone_healer/proc/modify_transferred(amount)
transferred_amount += amount

/datum/behavior_delegate/drone_healer/append_to_stat()
. = list()
. += "Transferred health amount: [transferred_amount]/[required_transferred_amount]"
if(transferred_amount >= required_transferred_amount)
. += "Sacrifice will grant you new life."

/datum/behavior_delegate/drone_healer/on_life()
if(!bound_xeno)
return
if(bound_xeno.stat == DEAD)
return
var/image/holder = bound_xeno.hud_list[PLASMA_HUD]
holder.overlays.Cut()
var/percentage_transferred = min(round((transferred_amount / required_transferred_amount) * 100, 10), 100)
if(percentage_transferred)
holder.overlays += image('icons/mob/hud/hud.dmi', "xenoenergy[percentage_transferred]")

/datum/behavior_delegate/drone_healer/handle_death(mob/M)
var/image/holder = bound_xeno.hud_list[PLASMA_HUD]
holder.overlays.Cut()

/datum/action/xeno_action/activable/healer_sacrifice
name = "Sacrifice"
action_icon_state = "screech"
ability_name = "sacrifice"
var/max_range = 1
var/transfer_mod = 0.75 // only transfers 75% of current healer's health
macro_path = /datum/action/xeno_action/verb/verb_healer_sacrifice
action_type = XENO_ACTION_CLICK
ability_primacy = XENO_PRIMARY_ACTION_5

/datum/action/xeno_action/verb/verb_healer_sacrifice()
set category = "Alien"
set name = "Sacrifice"
set hidden = TRUE
var/action_name = "Sacrifice"
handle_xeno_macro(src, action_name)

/datum/action/xeno_action/activable/healer_sacrifice/use_ability(atom/atom)
var/mob/living/carbon/xenomorph/xeno = owner
var/mob/living/carbon/xenomorph/target = atom

if(!istype(target))
return

if(target == xeno)
to_chat(xeno, "We can't heal ourself!")
return

if(isfacehugger(target) || islesserdrone(target))
to_chat(xeno, "It would be a waste...")
return

if(!xeno.check_state())
return

if(!xeno.can_not_harm(target)) //so we can heal only allies
to_chat(xeno, SPAN_WARNING("[target] is an enemy of our hive!"))
return

if(target.stat == DEAD)
to_chat(xeno, SPAN_WARNING("[target] is already dead!"))
return

if(target.health >= target.maxHealth)
to_chat(xeno, SPAN_WARNING("[target] is already at max health!"))
return

if(!isturf(xeno.loc))
to_chat(xeno, SPAN_WARNING("We cannot transfer health from here!"))
return

if(get_dist(xeno, target) > max_range)
to_chat(xeno, SPAN_WARNING("We need to be closer to [target]."))
return

xeno.say(";MY LIFE FOR THE QUEEN!!!")

target.gain_health(xeno.health * transfer_mod)
target.updatehealth()

target.xeno_jitter(1 SECONDS)
target.flick_heal_overlay(3 SECONDS, "#44253d")

target.visible_message(SPAN_XENONOTICE("[xeno] explodes in a deluge of regenerative resin salve, covering [target] in it!"))
xeno_message(SPAN_XENOANNOUNCE("[xeno] sacrifices itself to heal [target]!"), 2, target.hive.hivenumber)

var/datum/behavior_delegate/drone_healer/behavior_delegate = xeno.behavior_delegate
if(istype(behavior_delegate) && behavior_delegate.transferred_amount >= behavior_delegate.required_transferred_amount && xeno.client && xeno.hive)
var/datum/hive_status/hive_status = xeno.hive
var/turf/spawning_turf = get_turf(xeno)
if(!hive_status.hive_location)
addtimer(CALLBACK(xeno.hive, TYPE_PROC_REF(/datum/hive_status, respawn_on_turf), xeno.client, spawning_turf), 0.5 SECONDS)
else
addtimer(CALLBACK(xeno.hive, TYPE_PROC_REF(/datum/hive_status, free_respawn), xeno.client), 5 SECONDS)

xeno.gib(create_cause_data("sacrificing itself", src))

/datum/action/xeno_action/activable/healer_sacrifice/action_activate()
..()
var/mob/living/carbon/xenomorph/xeno = owner
if(xeno.selected_ability != src)
return
var/datum/behavior_delegate/drone_healer/behavior_delegate = xeno.behavior_delegate
if(!istype(behavior_delegate))
return
if(behavior_delegate.transferred_amount < behavior_delegate.required_transferred_amount)
to_chat(xeno, SPAN_HIGHDANGER("Warning: [name] is a last measure skill. Using it will kill us."))
else
to_chat(xeno, SPAN_HIGHDANGER("Warning: [name] is a last measure skill. Using it will kill us, but new life will be granted for our hard work for the hive."))

0 comments on commit bf41565

Please sign in to comment.