mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-18 13:43:27 +00:00
348 lines
14 KiB
Plaintext
348 lines
14 KiB
Plaintext
/datum/mutation/human/shock
|
|
name = "Shock Touch"
|
|
desc = "The affected can channel excess electricity through their hands without shocking themselves, allowing them to shock others."
|
|
quality = POSITIVE
|
|
locked = TRUE
|
|
difficulty = 16
|
|
text_gain_indication = span_notice("You feel power flow through your hands.")
|
|
text_lose_indication = span_notice("The energy in your hands subsides.")
|
|
power_path = /datum/action/cooldown/spell/touch/shock
|
|
instability = POSITIVE_INSTABILITY_MODERATE // bad stun baton
|
|
energy_coeff = 1
|
|
power_coeff = 1
|
|
|
|
/datum/mutation/human/shock/modify()
|
|
. = ..()
|
|
var/datum/action/cooldown/spell/touch/shock/to_modify =.
|
|
|
|
if(!istype(to_modify)) // null or invalid
|
|
return
|
|
|
|
if(GET_MUTATION_POWER(src) <= 1)
|
|
to_modify.chain = initial(to_modify.chain)
|
|
return
|
|
|
|
to_modify.chain = TRUE
|
|
|
|
/datum/action/cooldown/spell/touch/shock
|
|
name = "Shock Touch"
|
|
desc = "Channel electricity to your hand to shock people with."
|
|
button_icon_state = "zap"
|
|
sound = 'sound/items/weapons/zapbang.ogg'
|
|
cooldown_time = 12 SECONDS
|
|
invocation_type = INVOCATION_NONE
|
|
spell_requirements = NONE
|
|
antimagic_flags = NONE
|
|
|
|
//Vars for zaps made when power chromosome is applied, ripped and toned down from reactive tesla armor code.
|
|
///This var decides if the spell should chain, dictated by presence of power chromosome
|
|
var/chain = FALSE
|
|
///Affects damage, should do about 1 per limb
|
|
var/zap_power = 7.5 KILO JOULES
|
|
///Range of tesla shock bounces
|
|
var/zap_range = 7
|
|
///flags that dictate what the tesla shock can interact with, Can only damage mobs, Cannot damage machines or generate energy
|
|
var/zap_flags = ZAP_MOB_DAMAGE
|
|
|
|
hand_path = /obj/item/melee/touch_attack/shock
|
|
draw_message = span_notice("You channel electricity into your hand.")
|
|
drop_message = span_notice("You let the electricity from your hand dissipate.")
|
|
|
|
/datum/action/cooldown/spell/touch/shock/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/caster)
|
|
if(iscarbon(victim))
|
|
var/mob/living/carbon/carbon_victim = victim
|
|
if(carbon_victim.electrocute_act(15, caster, 1, SHOCK_NOGLOVES | SHOCK_NOSTUN))//doesn't stun. never let this stun
|
|
carbon_victim.dropItemToGround(carbon_victim.get_active_held_item())
|
|
carbon_victim.dropItemToGround(carbon_victim.get_inactive_held_item())
|
|
carbon_victim.adjust_confusion(15 SECONDS)
|
|
carbon_victim.visible_message(
|
|
span_danger("[caster] electrocutes [victim]!"),
|
|
span_userdanger("[caster] electrocutes you!"),
|
|
)
|
|
if(chain)
|
|
tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1 KILO JOULES, zap_flags = zap_flags)
|
|
carbon_victim.visible_message(span_danger("An arc of electricity explodes out of [victim]!"))
|
|
return TRUE
|
|
|
|
else if(isliving(victim))
|
|
var/mob/living/living_victim = victim
|
|
if(living_victim.electrocute_act(15, caster, 1, SHOCK_NOSTUN))
|
|
living_victim.visible_message(
|
|
span_danger("[caster] electrocutes [victim]!"),
|
|
span_userdanger("[caster] electrocutes you!"),
|
|
)
|
|
if(chain)
|
|
tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1 KILO JOULES, zap_flags = zap_flags)
|
|
living_victim.visible_message(span_danger("An arc of electricity explodes out of [victim]!"))
|
|
return TRUE
|
|
|
|
to_chat(caster, span_warning("The electricity doesn't seem to affect [victim]..."))
|
|
return TRUE
|
|
|
|
/obj/item/melee/touch_attack/shock
|
|
name = "\improper shock touch"
|
|
desc = "This is kind of like when you rub your feet on a shag rug so you can zap your friends, only a lot less safe."
|
|
icon = 'icons/obj/weapons/hand.dmi'
|
|
icon_state = "zapper"
|
|
inhand_icon_state = "zapper"
|
|
|
|
/datum/mutation/human/lay_on_hands
|
|
name = "Mending Touch"
|
|
desc = "The affected can lay their hands on other people to transfer a small amount of their injuries to themselves."
|
|
quality = POSITIVE
|
|
locked = FALSE
|
|
difficulty = 16
|
|
text_gain_indication = span_notice("Your hand feels blessed!")
|
|
text_lose_indication = span_notice("Your hand feels secular once more.")
|
|
power_path = /datum/action/cooldown/spell/touch/lay_on_hands
|
|
instability = POSITIVE_INSTABILITY_MAJOR
|
|
energy_coeff = 1
|
|
power_coeff = 1
|
|
synchronizer_coeff = 1
|
|
|
|
/datum/mutation/human/lay_on_hands/modify()
|
|
. = ..()
|
|
var/datum/action/cooldown/spell/touch/lay_on_hands/to_modify =.
|
|
|
|
if(!istype(to_modify)) // null or invalid
|
|
return
|
|
|
|
// Transfers more damage if strengthened. (1.5 with power chromosome)
|
|
to_modify.power_coefficient = GET_MUTATION_POWER(src)
|
|
// Halves transferred damage if synchronized. (0.5 with synchronizer chromosome)
|
|
to_modify.synchronizer_coefficient = GET_MUTATION_SYNCHRONIZER(src)
|
|
|
|
/datum/action/cooldown/spell/touch/lay_on_hands
|
|
name = "Mending Touch"
|
|
desc = "You can now lay your hands on other people to transfer a small amount of their physical injuries to yourself."
|
|
button_icon = 'icons/mob/actions/actions_genetic.dmi'
|
|
button_icon_state = "mending_touch"
|
|
sound = 'sound/effects/magic/staff_healing.ogg'
|
|
cooldown_time = 12 SECONDS
|
|
school = SCHOOL_RESTORATION
|
|
invocation_type = INVOCATION_NONE
|
|
spell_requirements = NONE
|
|
antimagic_flags = NONE
|
|
|
|
hand_path = /obj/item/melee/touch_attack/lay_on_hands
|
|
draw_message = span_notice("You ready your hand to transfer injuries to yourself.")
|
|
drop_message = span_notice("You lower your hand.")
|
|
/// Multiplies the amount healed.
|
|
var/heal_multiplier = 1
|
|
/// Multiplies the incoming pain from healing. (Halved with synchronizer chromosome)
|
|
var/pain_multiplier = 1
|
|
/// Icon used for beaming effect
|
|
var/beam_icon = "blood"
|
|
/// The mutation's power coefficient.
|
|
var/power_coefficient = 1
|
|
/// The mutation's synchronizer coefficient.
|
|
var/synchronizer_coefficient = 1
|
|
|
|
/datum/action/cooldown/spell/touch/lay_on_hands/create_hand(mob/living/carbon/cast_on)
|
|
. = ..()
|
|
if(!.)
|
|
return .
|
|
var/obj/item/bodypart/transfer_limb = cast_on.get_active_hand()
|
|
if(IS_ROBOTIC_LIMB(transfer_limb))
|
|
to_chat(cast_on, span_notice("You fail to channel your mending powers through your inorganic hand."))
|
|
return FALSE
|
|
|
|
return TRUE
|
|
|
|
/datum/action/cooldown/spell/touch/lay_on_hands/cast_on_hand_hit(obj/item/melee/touch_attack/hand, atom/victim, mob/living/carbon/mendicant)
|
|
|
|
var/mob/living/hurtguy = victim
|
|
|
|
heal_multiplier = initial(heal_multiplier) * power_coefficient
|
|
pain_multiplier = initial(pain_multiplier) * synchronizer_coefficient
|
|
|
|
// Message to show on a successful heal if the healer has a special pacifism interaction with the mutation.
|
|
var/peaceful_message = null
|
|
|
|
// Heal more, hurt a bit more.
|
|
// If you crunch the numbers it sounds crazy good,
|
|
// but I think that's a fair reward for combining the efforts of Genetics, Medbay, and Mining to reach a hidden mechanic.
|
|
if(HAS_TRAIT_FROM(mendicant, TRAIT_HIPPOCRATIC_OATH, HIPPOCRATIC_OATH_TRAIT))
|
|
heal_multiplier *= 2
|
|
pain_multiplier *= 0.5
|
|
peaceful_message = span_boldnotice("You can feel the magic of the Rod of Aesculapius aiding your efforts!")
|
|
beam_icon = "sendbeam"
|
|
var/obj/item/rod_of_asclepius/rod = locate() in mendicant.contents
|
|
if(rod)
|
|
rod.add_filter("cool_glow", 2, list("type" = "outline", "color" = COLOR_VERY_PALE_LIME_GREEN, "size" = 1.25))
|
|
addtimer(CALLBACK(rod, TYPE_PROC_REF(/datum, remove_filter), "cool_glow"), 6 SECONDS)
|
|
|
|
// If a normal pacifist, transfer more.
|
|
else if(HAS_TRAIT(mendicant, TRAIT_PACIFISM))
|
|
heal_multiplier *= 1.75
|
|
peaceful_message = span_boldnotice("Your peaceful nature helps you guide all the pain to yourself.")
|
|
|
|
var/success
|
|
if(iscarbon(hurtguy))
|
|
success = do_complicated_heal(mendicant, hurtguy, heal_multiplier, pain_multiplier)
|
|
else
|
|
success = do_simple_heal(mendicant, hurtguy, heal_multiplier, pain_multiplier)
|
|
|
|
// No healies in the end, cancel
|
|
if(!success)
|
|
return FALSE
|
|
|
|
if(peaceful_message)
|
|
to_chat(mendicant, peaceful_message)
|
|
|
|
// Both types can be ignited (technically at least), so we can just do this here.
|
|
if(hurtguy.fire_stacks > 0)
|
|
mendicant.set_fire_stacks(hurtguy.fire_stacks * pain_multiplier, remove_wet_stacks = TRUE)
|
|
if(hurtguy.on_fire)
|
|
mendicant.ignite_mob()
|
|
hurtguy.extinguish_mob()
|
|
|
|
mendicant.Beam(hurtguy, icon_state = beam_icon, time = 0.5 SECONDS)
|
|
beam_icon = initial(beam_icon)
|
|
|
|
hurtguy.update_damage_overlays()
|
|
mendicant.update_damage_overlays()
|
|
|
|
hurtguy.visible_message(span_notice("[mendicant] lays hands on [hurtguy]!"))
|
|
to_chat(hurtguy, span_boldnotice("[mendicant] lays hands on you, healing you!"))
|
|
new /obj/effect/temp_visual/heal(get_turf(hurtguy), COLOR_VERY_PALE_LIME_GREEN)
|
|
return success
|
|
|
|
/datum/action/cooldown/spell/touch/lay_on_hands/proc/do_simple_heal(mob/living/carbon/mendicant, mob/living/hurtguy, heal_multiplier, pain_multiplier)
|
|
// Did the transfer work?
|
|
. = FALSE
|
|
|
|
// Damage to heal
|
|
var/brute_to_heal = min(hurtguy.getBruteLoss(), 35 * heal_multiplier)
|
|
// no double dipping
|
|
var/burn_to_heal = min(hurtguy.getFireLoss(), (35 - brute_to_heal) * heal_multiplier)
|
|
|
|
// Get at least organic limb to transfer the damage to
|
|
var/list/mendicant_organic_limbs = list()
|
|
for(var/obj/item/bodypart/possible_limb in mendicant.bodyparts)
|
|
if(IS_ORGANIC_LIMB(possible_limb))
|
|
mendicant_organic_limbs += possible_limb
|
|
// None? Gtfo
|
|
if(!length(mendicant_organic_limbs))
|
|
mendicant.balloon_alert(mendicant, "no organic limbs!")
|
|
return .
|
|
|
|
// Try to use our active hand, otherwise pick at random
|
|
var/obj/item/bodypart/mendicant_transfer_limb = mendicant.get_active_hand()
|
|
if(!(mendicant_transfer_limb in mendicant_organic_limbs))
|
|
mendicant_transfer_limb = pick(mendicant_organic_limbs)
|
|
mendicant_transfer_limb.receive_damage(brute_to_heal * pain_multiplier, burn_to_heal * pain_multiplier, forced = TRUE, wound_bonus = CANT_WOUND)
|
|
|
|
if(brute_to_heal)
|
|
hurtguy.adjustBruteLoss(-brute_to_heal)
|
|
. = TRUE
|
|
|
|
if(burn_to_heal)
|
|
hurtguy.adjustFireLoss(-burn_to_heal)
|
|
. = TRUE
|
|
|
|
if(!.)
|
|
hurtguy.balloon_alert(mendicant, "unhurt!")
|
|
|
|
/datum/action/cooldown/spell/touch/lay_on_hands/proc/do_complicated_heal(mob/living/carbon/mendicant, mob/living/carbon/hurtguy, heal_multiplier, pain_multiplier)
|
|
|
|
// Did the transfer work?
|
|
. = FALSE
|
|
// Get the hurtguy's limbs and the mendicant's limbs to attempt a 1-1 transfer.
|
|
var/list/hurt_limbs = hurtguy.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC) + hurtguy.get_wounded_bodyparts(BODYTYPE_ORGANIC)
|
|
var/list/mendicant_organic_limbs = list()
|
|
for(var/obj/item/bodypart/possible_limb in mendicant.bodyparts)
|
|
if(IS_ORGANIC_LIMB(possible_limb))
|
|
mendicant_organic_limbs += possible_limb
|
|
|
|
// If we have no organic available limbs just give up.
|
|
if(!length(mendicant_organic_limbs))
|
|
mendicant.balloon_alert(mendicant, "no organic limbs!")
|
|
return .
|
|
if(!length(hurt_limbs))
|
|
hurtguy.balloon_alert(mendicant, "no damaged organic limbs!")
|
|
return .
|
|
|
|
// Counter to make sure we don't take too much from separate limbs
|
|
var/total_damage_healed = 0
|
|
// Transfer damage from one limb to the mendicant's counterpart.
|
|
for(var/obj/item/bodypart/affected_limb as anything in hurt_limbs)
|
|
var/obj/item/bodypart/mendicant_transfer_limb = mendicant.get_bodypart(affected_limb.body_zone)
|
|
// If the compared limb isn't organic, skip it and pick a random one.
|
|
if(!(mendicant_transfer_limb in mendicant_organic_limbs))
|
|
mendicant_transfer_limb = pick(mendicant_organic_limbs)
|
|
|
|
// Transfer at most 35 damage, by default.
|
|
var/brute_damage = min(affected_limb.brute_dam, 35 * heal_multiplier)
|
|
// no double dipping
|
|
var/burn_damage = min(affected_limb.burn_dam, (35 * heal_multiplier) - brute_damage)
|
|
if((brute_damage || burn_damage) && total_damage_healed < (35 * heal_multiplier))
|
|
total_damage_healed += brute_damage + burn_damage
|
|
. = TRUE
|
|
var/brute_taken = brute_damage * pain_multiplier
|
|
var/burn_taken = burn_damage * pain_multiplier
|
|
// Heal!
|
|
affected_limb.heal_damage(brute_damage, burn_damage, required_bodytype = BODYTYPE_ORGANIC)
|
|
// Hurt!
|
|
mendicant_transfer_limb.receive_damage(brute_taken, burn_taken, forced = TRUE, wound_bonus = CANT_WOUND)
|
|
|
|
// Force light wounds onto you.
|
|
for(var/datum/wound/iter_wound as anything in affected_limb.wounds)
|
|
switch(iter_wound.severity)
|
|
if(WOUND_SEVERITY_SEVERE) // half and half
|
|
if(prob(50 * heal_multiplier))
|
|
continue
|
|
if(WOUND_SEVERITY_CRITICAL)
|
|
if(heal_multiplier < 1.5) // need buffs to transfer crit wounds
|
|
continue
|
|
. = TRUE
|
|
iter_wound.remove_wound()
|
|
iter_wound.apply_wound(mendicant_transfer_limb)
|
|
|
|
if(HAS_TRAIT(mendicant, TRAIT_NOBLOOD))
|
|
return .
|
|
|
|
// 10% base
|
|
var/max_blood_transfer = (BLOOD_VOLUME_NORMAL * 0.10) * heal_multiplier
|
|
// Too little blood
|
|
if(hurtguy.blood_volume < BLOOD_VOLUME_NORMAL)
|
|
var/max_blood_to_hurtguy = min(mendicant.blood_volume, BLOOD_VOLUME_NORMAL - hurtguy.blood_volume)
|
|
var/blood_to_hurtguy = min(max_blood_transfer, max_blood_to_hurtguy)
|
|
if(!blood_to_hurtguy)
|
|
return .
|
|
// We ignore incompatibility here.
|
|
mendicant.transfer_blood_to(hurtguy, blood_to_hurtguy, forced = TRUE)
|
|
to_chat(mendicant, span_notice("Your veins (and brain) feel a bit lighter."))
|
|
. = TRUE
|
|
// Because we do our own spin on it!
|
|
if(hurtguy.get_blood_compatibility(mendicant) == FALSE)
|
|
hurtguy.adjustToxLoss((blood_to_hurtguy * 0.1) * pain_multiplier) // 1 dmg per 10 blood
|
|
to_chat(hurtguy, span_notice("Your veins feel thicker, but they itch a bit."))
|
|
else
|
|
to_chat(hurtguy, span_notice("Your veins feel thicker!"))
|
|
|
|
// Too MUCH blood
|
|
if(hurtguy.blood_volume > BLOOD_VOLUME_MAXIMUM)
|
|
var/max_blood_to_mendicant = BLOOD_VOLUME_EXCESS - hurtguy.blood_volume
|
|
var/blood_to_mendicant = min(max_blood_transfer, max_blood_to_mendicant)
|
|
// mender always gonna have blood
|
|
|
|
// We ignore incompatibility here.
|
|
hurtguy.transfer_blood_to(mendicant, hurtguy.blood_volume - BLOOD_VOLUME_EXCESS, forced = TRUE)
|
|
to_chat(hurtguy, span_notice("Your veins don't feel quite so swollen anymore."))
|
|
. = TRUE
|
|
// Because we do our own spin on it!
|
|
if(mendicant.get_blood_compatibility(hurtguy) == FALSE)
|
|
mendicant.adjustToxLoss((blood_to_mendicant * 0.1) * pain_multiplier) // 1 dmg per 10 blood
|
|
to_chat(mendicant, span_notice("Your veins swell and itch!"))
|
|
else
|
|
to_chat(mendicant, span_notice("Your veins swell!"))
|
|
|
|
/obj/item/melee/touch_attack/lay_on_hands
|
|
name = "mending touch"
|
|
desc = "Unlike in your favorite tabletop games, you sadly can't cast this on yourself, so you can't use that as a Scapegoat." // mayus is reference. if you get it you're cool
|
|
icon = 'icons/obj/weapons/hand.dmi'
|
|
icon_state = "greyscale"
|
|
color = COLOR_VERY_PALE_LIME_GREEN
|
|
inhand_icon_state = "greyscale"
|