From 0e59ca10d3c54af4fb65eb3f7f00d706d37bc8a4 Mon Sep 17 00:00:00 2001 From: MacBlaze1 <33578623+MacBlaze1@users.noreply.github.com> Date: Wed, 2 Feb 2022 22:54:52 -0500 Subject: [PATCH] fixed ethereals being unable to charge from APCs (#64547) This PR allows ethereals to receive and give charge to APCs again. I had to make some design choices due to the fact there is no clear solution with ethereals having an action with two possible outcomes. I moved ethereal APC charging to its own function called from the right click attack hand function. --- code/modules/power/apc.dm | 107 ++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 46 deletions(-) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 5dc6d471087..7581dd748fb 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -781,9 +781,69 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/power/apc/auto_name, APC_PIXEL_OFFSET return if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) return - togglelock(user) + if(!ishuman(user)) + return + else + var/mob/living/carbon/human/H = user + var/obj/item/organ/stomach/maybe_stomach = H.getorganslot(ORGAN_SLOT_STOMACH) + if(!istype(maybe_stomach, /obj/item/organ/stomach/ethereal)) + togglelock(user) + else + var/obj/item/organ/stomach/ethereal/stomach = maybe_stomach + if(stomach.crystal_charge >= ETHEREAL_CHARGE_NORMAL) + togglelock(user) + ethereal_interact(user,modifiers) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN +/obj/machinery/power/apc/proc/ethereal_interact(mob/living/user,list/modifiers) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + var/obj/item/organ/stomach/maybe_stomach = H.getorganslot(ORGAN_SLOT_STOMACH) + + if(!istype(maybe_stomach, /obj/item/organ/stomach/ethereal)) + return + var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - APC_POWER_GAIN + var/obj/item/organ/stomach/ethereal/stomach = maybe_stomach + if(!((stomach?.drain_time < world.time) && LAZYACCESS(modifiers, RIGHT_CLICK))) + return + if(H.combat_mode) + if(cell.charge <= (cell.maxcharge / 2)) // ethereals can't drain APCs under half charge, this is so that they are forced to look to alternative power sources if the station is running low + to_chat(H, span_warning("The APC's syphon safeties prevent you from draining power!")) + return + if(stomach.crystal_charge > charge_limit) + to_chat(H, span_warning("Your charge is full!")) + return + stomach.drain_time = world.time + APC_DRAIN_TIME + to_chat(H, span_notice("You start channeling some power through the APC into your body.")) + if(do_after(user, APC_DRAIN_TIME, target = src)) + if(cell.charge <= (cell.maxcharge / 2) || (stomach.crystal_charge > charge_limit)) + return + to_chat(H, span_notice("You receive some charge from the APC.")) + stomach.adjust_charge(APC_POWER_GAIN) + cell.charge -= APC_POWER_GAIN + return + else + if(cell.charge >= cell.maxcharge - APC_POWER_GAIN) + to_chat(H, span_warning("The APC can't receive anymore power!")) + return + if(stomach.crystal_charge < APC_POWER_GAIN) + to_chat(H, span_warning("Your charge is too low!")) + return + stomach.drain_time = world.time + APC_DRAIN_TIME + to_chat(H, span_notice("You start channeling power through your body into the APC.")) + if(do_after(user, APC_DRAIN_TIME, target = src)) + if((cell.charge >= (cell.maxcharge - APC_POWER_GAIN)) || (stomach.crystal_charge < APC_POWER_GAIN)) + to_chat(H, span_warning("You can't transfer power to the APC!")) + return + if(istype(stomach)) + to_chat(H, span_notice("You transfer some power to the APC.")) + stomach.adjust_charge(-APC_POWER_GAIN) + cell.charge += APC_POWER_GAIN + else + to_chat(H, span_warning("You can't transfer power to the APC!")) + return + /obj/machinery/power/apc/proc/togglelock(mob/living/user) if(obj_flags & EMAGGED) to_chat(user, span_warning("The interface is broken!")) @@ -853,51 +913,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/power/apc/auto_name, APC_PIXEL_OFFSET if(.) return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - var/obj/item/organ/stomach/maybe_stomach = H.getorganslot(ORGAN_SLOT_STOMACH) - - if(istype(maybe_stomach, /obj/item/organ/stomach/ethereal)) - var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - APC_POWER_GAIN - var/obj/item/organ/stomach/ethereal/stomach = maybe_stomach - if((stomach?.drain_time < world.time) && LAZYACCESS(modifiers, RIGHT_CLICK)) - if(H.combat_mode) - if(cell.charge <= (cell.maxcharge / 2)) // ethereals can't drain APCs under half charge, this is so that they are forced to look to alternative power sources if the station is running low - to_chat(H, span_warning("The APC's syphon safeties prevent you from draining power!")) - return - if(stomach.crystal_charge > charge_limit) - to_chat(H, span_warning("Your charge is full!")) - return - stomach.drain_time = world.time + APC_DRAIN_TIME - to_chat(H, span_notice("You start channeling some power through the APC into your body.")) - if(do_after(user, APC_DRAIN_TIME, target = src)) - if(cell.charge <= (cell.maxcharge / 2) || (stomach.crystal_charge > charge_limit)) - return - to_chat(H, span_notice("You receive some charge from the APC.")) - stomach.adjust_charge(APC_POWER_GAIN) - cell.charge -= APC_POWER_GAIN - return - else - if(cell.charge >= cell.maxcharge - APC_POWER_GAIN) - to_chat(H, span_warning("The APC can't receive anymore power!")) - return - if(stomach.crystal_charge < APC_POWER_GAIN) - to_chat(H, span_warning("Your charge is too low!")) - return - stomach.drain_time = world.time + APC_DRAIN_TIME - to_chat(H, span_notice("You start channeling power through your body into the APC.")) - if(do_after(user, APC_DRAIN_TIME, target = src)) - if((cell.charge >= (cell.maxcharge - APC_POWER_GAIN)) || (stomach.crystal_charge < APC_POWER_GAIN)) - to_chat(H, span_warning("You can't transfer power to the APC!")) - return - if(istype(stomach)) - to_chat(H, span_notice("You transfer some power to the APC.")) - stomach.adjust_charge(-APC_POWER_GAIN) - cell.charge += APC_POWER_GAIN - else - to_chat(H, span_warning("You can't transfer power to the APC!")) - return - if(opened && (!issilicon(user))) if(cell) user.visible_message(span_notice("[user] removes \the [cell] from [src]!"), span_notice("You remove \the [cell]."))