Skip to content

Commit

Permalink
Yautja Bracer Charging Rework (#3456)
Browse files Browse the repository at this point in the history
# About the pull request
Changes how bracers recharge, requiring drain from APC in the field.
Change made as atomisation from #3271 as part of an ongoing project to
make Yautja a more balanced role for what it is.
<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

# Explain why it's good for the game
Balances out power usage and makes things more dynamic. Will tie in with
cloak not using power but being more vulnerable to the methods to force
decloak.
# 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:
add: Yautja bracers can now be recharged from APCs.
remove: Yautja bracers no longer naturally recharge on the colony.
/:cl:

---------

Co-authored-by: harryob <[email protected]>
  • Loading branch information
realforest2001 and harryob committed Jul 24, 2023
1 parent c1a9ca7 commit 4ef3b9e
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 41 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@
#define COOLDOWN_COMM_CENTRAL 30 SECONDS
#define COOLDOWN_COMM_DESTRUCT 5 MINUTES

///Cooldown for pred recharge
#define COOLDOWN_BRACER_CHARGE 3 MINUTES

// magic value to use for indicating a proc slept
#define PROC_RETURN_SLEEP -1
29 changes: 25 additions & 4 deletions code/modules/cm_preds/yaut_bracers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
var/notification_sound = TRUE // Whether the bracer pings when a message comes or not
var/charge = 1500
var/charge_max = 1500
/// The amount charged per process
var/charge_rate = 30
/// Cooldown on draining power from APC
var/charge_cooldown = COOLDOWN_BRACER_CHARGE
var/cloaked = 0
var/cloak_timer = 0
var/cloak_malfunction = 0
Expand All @@ -41,6 +45,7 @@

var/mob/living/carbon/human/owner //Pred spawned on, or thrall given to.
var/obj/item/clothing/gloves/yautja/linked_bracer //Bracer linked to this one (thrall or mentor).
COOLDOWN_DECLARE(bracer_recharge)

/obj/item/clothing/gloves/yautja/equipped(mob/user, slot)
. = ..()
Expand Down Expand Up @@ -75,11 +80,27 @@
if(!ishuman(loc))
STOP_PROCESSING(SSobj, src)
return
var/mob/living/carbon/human/H = loc
var/mob/living/carbon/human/human_holder = loc

charge = min(charge + 30, charge_max)
var/perc_charge = (charge / charge_max * 100)
H.update_power_display(perc_charge)
if(charge < charge_max)
var/charge_increase = charge_rate
if(is_ground_level(human_holder.z))
charge_increase = charge_rate / 6
else if(is_mainship_level(human_holder.z))
charge_increase = charge_rate / 3

charge = min(charge + charge_increase, charge_max)
var/perc_charge = (charge / charge_max * 100)
human_holder.update_power_display(perc_charge)

//Non-Yautja have a chance to get stunned with each power drain
if(!cloaked)
return
if(human_holder.stat == DEAD)
decloak(human_holder, TRUE)
if(!HAS_TRAIT(human_holder, TRAIT_YAUTJA_TECH) && !human_holder.hunter_data.thralled && prob(15))
decloak(human_holder)
shock_user(human_holder)

/// handles decloaking only on HUNTER gloves
/obj/item/clothing/gloves/yautja/proc/decloak()
Expand Down
120 changes: 83 additions & 37 deletions code/modules/power/apc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -676,9 +676,9 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
var/turf/T = get_turf(src)
var/obj/structure/cable/N = T.get_cable_node()
if(prob(50) && electrocute_mob(usr, N, N))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start()
var/datum/effect_system/spark_spread/spark = new /datum/effect_system/spark_spread
spark.set_up(5, 1, src)
spark.start()
return
if(C.use(10))
user.visible_message(SPAN_NOTICE("[user] wires [src]'s frame."),
Expand All @@ -700,9 +700,9 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
to_chat(user, SPAN_WARNING("\The [src] lacks a terminal to remove."))
return
if (prob(50) && electrocute_mob(user, terminal.powernet, terminal))
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start()
var/datum/effect_system/spark_spread/spark = new /datum/effect_system/spark_spread
spark.set_up(5, 1, src)
spark.start()
return
new /obj/item/stack/cable_coil(loc,10)
user.visible_message(SPAN_NOTICE("[user] removes [src]'s wiring and terminal."),
Expand Down Expand Up @@ -798,41 +798,87 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(

//Human mob special interaction goes here.
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/mob/living/carbon/human/grabber = user

if(H.species.flags & IS_SYNTHETIC && H.a_intent == INTENT_GRAB)
if(H.action_busy)
return

if(!do_after(H, 20, INTERRUPT_ALL, BUSY_ICON_GENERIC))
return
if(grabber.a_intent == INTENT_GRAB)

playsound(src.loc, 'sound/effects/sparks2.ogg', 25, 1)
//Synthpack recharge
if((grabber.species.flags & IS_SYNTHETIC) && istype(grabber.back, /obj/item/storage/backpack/marine/smartpack))
var/obj/item/storage/backpack/marine/smartpack/s_pack = grabber.back
if(grabber.action_busy)
return

if(stat & BROKEN)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
to_chat(H, SPAN_DANGER("The APC's power currents surge eratically, damaging your chassis!"))
H.apply_damage(10,0, BURN)
else if(cell && cell.charge > 0)
if(!istype(H.back, /obj/item/storage/backpack/marine/smartpack))
if(!do_after(grabber, 20, INTERRUPT_ALL, BUSY_ICON_GENERIC))
return

var/obj/item/storage/backpack/marine/smartpack/S = H.back
if(S.battery_charge < SMARTPACK_MAX_POWER_STORED)
var/charge_to_use = min(cell.charge, SMARTPACK_MAX_POWER_STORED - S.battery_charge)
if(!(cell.use(charge_to_use)))
playsound(src.loc, 'sound/effects/sparks2.ogg', 25, 1)

if(stat & BROKEN)
var/datum/effect_system/spark_spread/spark = new()
spark.set_up(3, 1, src)
spark.start()
to_chat(grabber, SPAN_DANGER("The APC's power currents surge eratically, damaging your chassis!"))
grabber.apply_damage(10,0, BURN)
else if(cell && cell.charge > 0)
if(!istype(s_pack))
return
S.battery_charge += charge_to_use
to_chat(user, SPAN_NOTICE("You slot your fingers into the APC interface and siphon off some of the stored charge. [S.name] now has [S.battery_charge]/[SMARTPACK_MAX_POWER_STORED]"))
charging = APC_CHARGING

if(s_pack.battery_charge < SMARTPACK_MAX_POWER_STORED)
var/charge_to_use = min(cell.charge, SMARTPACK_MAX_POWER_STORED - s_pack.battery_charge)
if(!(cell.use(charge_to_use)))
return
s_pack.battery_charge += charge_to_use
to_chat(user, SPAN_NOTICE("You slot your fingers into the APC interface and siphon off some of the stored charge. [s_pack.name] now has [s_pack.battery_charge]/[SMARTPACK_MAX_POWER_STORED]"))
charging = APC_CHARGING
else
to_chat(user, SPAN_WARNING("[s_pack.name] is already fully charged."))
else
to_chat(user, SPAN_WARNING("[S.name] is already fully charged."))
else
to_chat(user, SPAN_WARNING("There is no charge to draw from that APC."))
return
else if(H.species.can_shred(H))
to_chat(user, SPAN_WARNING("There is no charge to draw from that APC."))
return

// Yautja Bracer Recharge
var/obj/item/clothing/gloves/yautja/bracer = grabber.gloves
if(istype(bracer))
if(grabber.action_busy)
return FALSE
if(!COOLDOWN_FINISHED(bracer, bracer_recharge))
to_chat(user, SPAN_WARNING("It is too soon for [bracer.name] to siphon power again. Wait [COOLDOWN_SECONDSLEFT(bracer, bracer_recharge)] seconds."))
return FALSE
to_chat(user, SPAN_NOTICE("You rest your bracer against the APC interface and begin to siphon off some of the stored energy."))
if(!do_after(grabber, 20, INTERRUPT_ALL, BUSY_ICON_HOSTILE))
return FALSE

if(stat & BROKEN)
var/datum/effect_system/spark_spread/spark = new()
spark.set_up(3, 1, src)
spark.start()
to_chat(grabber, SPAN_DANGER("The APC's power currents surge eratically, super-heating your bracer!"))
playsound(src.loc, 'sound/effects/sparks2.ogg', 25, 1)
grabber.apply_damage(10,0, BURN)
return FALSE
if(!cell || cell.charge <= 0)
to_chat(user, SPAN_WARNING("There is no charge to draw from that APC."))
return FALSE

if(bracer.charge_max <= bracer.charge)
to_chat(user, SPAN_WARNING("[bracer.name] is already fully charged."))
return FALSE

var/charge_to_use = min(cell.charge, bracer.charge_max - bracer.charge)
if(!(cell.use(charge_to_use)))
return FALSE
playsound(src.loc, 'sound/effects/sparks2.ogg', 25, 1)
bracer.charge += charge_to_use
COOLDOWN_START(bracer, bracer_recharge, bracer.charge_cooldown)
to_chat(grabber, SPAN_YAUTJABOLD("[icon2html(bracer)] \The <b>[bracer]</b> beep: Power siphon complete. Charge at [bracer.charge]/[bracer.charge_max]."))
if(bracer.notification_sound)
playsound(bracer.loc, 'sound/items/pred_bracer.ogg', 75, 1)
charging = APC_CHARGING
set_broken() // Breaks the APC

return TRUE

else if(grabber.species.can_shred(grabber))
var/allcut = TRUE
for(var/wire = 1; wire < length(get_wire_descriptions()); wire++)
if(!isWireCut(wire))
Expand Down Expand Up @@ -1011,9 +1057,9 @@ GLOBAL_LIST_INIT(apc_wire_descriptions, list(
smoke.set_up(1, 0, loc)
smoke.attach(src)
smoke.start()
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(1, 1, src)
s.start()
var/datum/effect_system/spark_spread/spark = new()
spark.set_up(1, 1, src)
spark.start()
visible_message(SPAN_WARNING("[src] suddenly lets out a blast of smoke and some sparks!"))

/obj/structure/machinery/power/apc/surplus()
Expand Down

0 comments on commit 4ef3b9e

Please sign in to comment.