diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index bed2ceeced7d..4464a0b16a1d 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -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 diff --git a/code/modules/cm_preds/yaut_bracers.dm b/code/modules/cm_preds/yaut_bracers.dm index b526e11d99bb..9642b4b9f5a5 100644 --- a/code/modules/cm_preds/yaut_bracers.dm +++ b/code/modules/cm_preds/yaut_bracers.dm @@ -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 @@ -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) . = ..() @@ -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() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 7247e9b87b16..e7a160095705 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -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."), @@ -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."), @@ -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 [bracer] 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)) @@ -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()