Skip to content

Commit

Permalink
[MIRROR] [NO GBP]Fixes ethereal charging and recharge station charge …
Browse files Browse the repository at this point in the history
…speed. (#2788)

* [NO GBP]Fixes ethereal charging and recharge station charge speed. (#82483)

## About The Pull Request
Fixes many instances of things not charging ethereals properly. Scales
all things that are meant for charging/taking from the ethereal stomach
by STANDARD_CELL_CHARGE, so we never run into this issue again. Ethereal
stomachs now store a cell inside them, and uses that for the charge
instead of tracking a variable. Fixes recharging stations not being able
to charge ethereal stomachs. The ethereal signal proc attempted to feed
a callback datum to adjust_charge(), which caused a runtime. Changes
that by invoking the charge_cell callback instead.

Also fixes recharge station charging speed. They weren't converted
correctly. Also formats their charging speed in their description, and
displays power rather than referencing cycles.
## Why It's Good For The Game
So ethereals charge properly.

Closes #82470
## Changelog
:cl:
fix: Fixes many instances of energy sources for ethereals supplying a
thousand times less energy than intended.
fix: Fixes recharging stations not being able to charge ethereals.
fix: Fixes recharge stations charging too fast.
qol: Recharge stations display their recharging speed in formatted
power, rather than unformatted energy per cycle.
/:cl:

---------



* [NO GBP]Fixes ethereal charging and recharge station charge speed.

---------

Co-authored-by: NovaBot <[email protected]>
Co-authored-by: Pickle-Coding <[email protected]>
Co-authored-by: san7890 <[email protected]>
  • Loading branch information
4 people authored Apr 9, 2024
1 parent b289a72 commit 5c79a4f
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 43 deletions.
2 changes: 1 addition & 1 deletion code/__DEFINES/apc_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
/// How long it takes an ethereal to drain or charge APCs. Also used as a spam limiter.
#define APC_DRAIN_TIME (3.5 SECONDS) //NOVA EDIT CHANGE - Ethereal Rework 2024 - Original: 7.5
/// How much power ethereals gain/drain from APCs.
#define APC_POWER_GAIN (200 KILO JOULES)
#define APC_POWER_GAIN (0.2 * STANDARD_CELL_CHARGE)

// Wires & EMPs:
/// The wire value used to reset the APCs wires after one's EMPed.
Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/lights.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
///Amount of time that takes an ethereal to take energy from the lights
#define LIGHT_DRAIN_TIME (2.5 SECONDS)
///Amount of charge the ethereal gain after the drain
#define LIGHT_POWER_GAIN 35
#define LIGHT_POWER_GAIN (0.035 * STANDARD_CELL_CHARGE)

///How many reagents the lights can hold
#define LIGHT_REAGENT_CAPACITY 20
Expand Down
14 changes: 7 additions & 7 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,12 @@

//Charge levels for Ethereals, in joules.
#define ETHEREAL_CHARGE_NONE 0
#define ETHEREAL_CHARGE_LOWPOWER (400 KILO JOULES)
#define ETHEREAL_CHARGE_NORMAL (1 MEGA JOULES)
#define ETHEREAL_CHARGE_ALMOSTFULL (1.5 MEGA JOULES)
#define ETHEREAL_CHARGE_FULL (2 MEGA JOULES)
#define ETHEREAL_CHARGE_OVERLOAD (2.5 MEGA JOULES)
#define ETHEREAL_CHARGE_DANGEROUS (3 MEGA JOULES)
#define ETHEREAL_CHARGE_LOWPOWER (0.4 * STANDARD_CELL_CHARGE)
#define ETHEREAL_CHARGE_NORMAL (1 * STANDARD_CELL_CHARGE)
#define ETHEREAL_CHARGE_ALMOSTFULL (1.5 * STANDARD_CELL_CHARGE)
#define ETHEREAL_CHARGE_FULL (2 * STANDARD_CELL_CHARGE)
#define ETHEREAL_CHARGE_OVERLOAD (2.5 * STANDARD_CELL_CHARGE)
#define ETHEREAL_CHARGE_DANGEROUS (3 * STANDARD_CELL_CHARGE)


#define CRYSTALIZE_COOLDOWN_LENGTH (5 MINUTES) //NOVA EDIT CHANGE - Ethereal Rework 2024 - Original: 120 SECONDS
Expand Down Expand Up @@ -449,7 +449,7 @@
#define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you

#define HUNGER_FACTOR 0.05 //factor at which mob nutrition decreases
#define ETHEREAL_DISCHARGE_RATE (0.8 KILO WATTS) // Rate at which ethereal stomach charge decreases
#define ETHEREAL_DISCHARGE_RATE (8e-4 * STANDARD_CELL_CHARGE) // Rate at which ethereal stomach charge decreases
/// How much nutrition eating clothes as moth gives and drains
#define CLOTHING_NUTRITION_GAIN 15
#define REAGENTS_METABOLISM 0.2 //How many units of reagent are consumed per second, by default.
Expand Down
6 changes: 3 additions & 3 deletions code/game/machinery/rechargestation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@
recharge_speed = 0
repairs = 0
for(var/datum/stock_part/capacitor/capacitor in component_parts)
recharge_speed += (capacitor.tier * STANDARD_CELL_CHARGE * 0.1)
recharge_speed += 5e-3 * capacitor.tier
for(var/datum/stock_part/servo/servo in component_parts)
repairs += servo.tier - 1
for(var/obj/item/stock_parts/cell/cell in component_parts)
recharge_speed *= (cell.maxcharge / STANDARD_CELL_CHARGE)
recharge_speed *= cell.maxcharge

/obj/machinery/recharge_station/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Recharging <b>[recharge_speed]J</b> per cycle.")
. += span_notice("The status display reads: Recharging: <b>[display_power(recharge_speed, convert = FALSE)]</b>.")
if(materials.silo)
. += span_notice("The ore silo link indicator is lit, and cyborg restocking can be toggled by <b>Right-Clicking</b> [src].")
if(repairs)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mod/mod_core.dm
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@

/obj/item/mod/core/ethereal/charge_amount()
var/obj/item/organ/internal/stomach/ethereal/charge_source = charge_source()
return charge_source?.crystal_charge || ETHEREAL_CHARGE_NONE
return charge_source?.cell.charge() || ETHEREAL_CHARGE_NONE

/obj/item/mod/core/ethereal/max_charge_amount()
return ETHEREAL_CHARGE_FULL
Expand Down
12 changes: 6 additions & 6 deletions code/modules/power/apc/apc_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
if(!istype(maybe_ethereal_stomach))
togglelock(user)
else
if(maybe_ethereal_stomach.crystal_charge >= ETHEREAL_CHARGE_NORMAL)
if(maybe_ethereal_stomach.cell.charge() >= ETHEREAL_CHARGE_NORMAL)
togglelock(user)
ethereal_interact(user, modifiers)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
Expand All @@ -29,14 +29,15 @@
return
var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - APC_POWER_GAIN
var/obj/item/organ/internal/stomach/ethereal/stomach = maybe_stomach
var/obj/item/stock_parts/cell/stomach_cell = stomach.cell
if(!((stomach?.drain_time < world.time) && LAZYACCESS(modifiers, RIGHT_CLICK)))
return
if(ethereal.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
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, balloon_alert), ethereal, "safeties prevent draining!"), alert_timer_duration)
ethereal.visible_message(span_notice("[src] displays a red X, sealing ports as 'safeties enabled' flashes across the screen!")) // NOVA EDIT ADDITION
return
if(stomach.crystal_charge > charge_limit)
if(stomach_cell.charge() > charge_limit)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, balloon_alert), ethereal, "charge is full!"), alert_timer_duration)
ethereal.visible_message(span_notice("[ethereal] drops [ethereal.p_their()] hand from [src], glowing at [ethereal.p_their()] zenith!")) // NOVA EDIT ADDITION
return
Expand All @@ -47,7 +48,7 @@
to_chat(ethereal, span_purple("You try to drain some of [src]'s energy into yourself..."))
//NOVA EDIT CHANGE END - Ethereal Rework 2024
while(do_after(user, APC_DRAIN_TIME, target = src))
if(cell.charge <= (cell.maxcharge / 2) || (stomach.crystal_charge > charge_limit))
if(cell.charge <= (cell.maxcharge / 2) || (stomach_cell.charge() > charge_limit))
return
balloon_alert(ethereal, "received charge")
stomach.adjust_charge(APC_POWER_GAIN)
Expand All @@ -57,7 +58,7 @@
if(cell.charge >= cell.maxcharge - APC_POWER_GAIN)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, balloon_alert), ethereal, "APC can't receive more power!"), alert_timer_duration)
return
if(stomach.crystal_charge < APC_POWER_GAIN)
if(stomach_cell.charge() < APC_POWER_GAIN)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, balloon_alert), ethereal, "charge is too low!"), alert_timer_duration)
return
stomach.drain_time = world.time + APC_DRAIN_TIME
Expand All @@ -68,14 +69,13 @@
// NOVA EDIT ADDITION END - Ethereal Rework 2024
if(!do_after(user, APC_DRAIN_TIME, target = src))
return
if((cell.charge >= (cell.maxcharge - APC_POWER_GAIN)) || (stomach.crystal_charge < APC_POWER_GAIN))
if((cell.charge >= (cell.maxcharge - APC_POWER_GAIN)) || (stomach_cell.charge() < APC_POWER_GAIN))
balloon_alert(ethereal, "can't transfer power!")
ethereal.visible_message(span_notice("[src] displays a red X across the screen, sealing ports and rejecting [ethereal]'s charge!")) //NOVA EDIT ADDITION - Ethereal Rework 2024
return
if(istype(stomach))
while(do_after(user, APC_DRAIN_TIME, target = src))
balloon_alert(ethereal, "transferred power")
stomach.adjust_charge(-APC_POWER_GAIN)
cell.give(-stomach.adjust_charge(-APC_POWER_GAIN))
else
balloon_alert(ethereal, "can't transfer power!")
Expand Down
37 changes: 33 additions & 4 deletions code/modules/power/cell.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define CELL_DRAIN_TIME 35
#define CELL_POWER_GAIN 60
#define CELL_POWER_DRAIN 750
#define CELL_POWER_GAIN (0.06 * STANDARD_CELL_CHARGE)
#define CELL_POWER_DRAIN (0.75 * STANDARD_CELL_CHARGE)

/**
* # Power cell
Expand Down Expand Up @@ -186,6 +186,19 @@
explode()
return power_used

/**
* Changes the charge of the cell.
* Args:
* - amount: The energy to give to the cell (can be negative).
* Returns: The energy that was given to the cell (can be negative).
*/
/obj/item/stock_parts/cell/proc/change(amount)
var/energy_used = clamp(amount, -charge, maxcharge - charge)
charge += energy_used
if(rigged && energy_used)
explode()
return energy_used

/obj/item/stock_parts/cell/examine(mob/user)
. = ..()
if(rigged)
Expand Down Expand Up @@ -259,18 +272,19 @@

var/charge_limit = ETHEREAL_CHARGE_DANGEROUS - CELL_POWER_GAIN
var/obj/item/organ/internal/stomach/ethereal/stomach = maybe_stomach
var/obj/item/stock_parts/cell/stomach_cell = stomach.cell
if((stomach.drain_time > world.time) || !stomach)
return
if(charge < CELL_POWER_DRAIN)
to_chat(H, span_warning("[src] doesn't have enough power!"))
return
if(stomach.crystal_charge > charge_limit)
if(stomach_cell.charge() > charge_limit)
to_chat(H, span_warning("Your charge is full!"))
return
H.visible_message(span_notice("[user] hovers their fingers above [src], arcs forming from its surface!")) //NOVA EDIT CHANGE - Ethereal Rework 2024 - ORIGINAL: to_chat(H, span_notice("You begin clumsily channeling power from [src] into your body."))
stomach.drain_time = world.time + CELL_DRAIN_TIME
while(do_after(user, CELL_DRAIN_TIME, target = src))
if((charge < CELL_POWER_DRAIN) || (stomach.crystal_charge > charge_limit))
if((charge < CELL_POWER_DRAIN) || (stomach_cell.charge() > charge_limit))
return
if(istype(stomach))
to_chat(H, span_purple("You receive some charge from [src], wasting some in the process.")) // NOVA EDIT CHANGE - Ethereal Rework 2024 - Original: to_chat(H, span_notice("You receive some charge from [src], wasting some in the process."))
Expand Down Expand Up @@ -503,6 +517,21 @@
/obj/item/stock_parts/cell/inducer_supply
maxcharge = STANDARD_CELL_CHARGE * 5

/obj/item/stock_parts/cell/ethereal
name = "ahelp it"
desc = "you sohuldn't see this"
maxcharge = ETHEREAL_CHARGE_DANGEROUS
charge = ETHEREAL_CHARGE_FULL
icon_state = null
charge_light_type = null
connector_type = null
custom_materials = null
grind_results = null

/obj/item/stock_parts/cell/ethereal/examine(mob/user)
. = ..()
CRASH("[src.type] got examined by [user]")

#undef CELL_DRAIN_TIME
#undef CELL_POWER_GAIN
#undef CELL_POWER_DRAIN
Original file line number Diff line number Diff line change
Expand Up @@ -2632,7 +2632,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
stomach.adjust_charge(reac_volume * 3)
stomach.adjust_charge(reac_volume * 0.003 * STANDARD_CELL_CHARGE)

/datum/reagent/consumable/ethanol/telepole
name = "Telepole"
Expand All @@ -2652,7 +2652,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
stomach.adjust_charge(reac_volume * 2)
stomach.adjust_charge(reac_volume * 0.002 * STANDARD_CELL_CHARGE)

/datum/reagent/consumable/ethanol/pod_tesla
name = "Pod Tesla"
Expand All @@ -2679,7 +2679,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
stomach.adjust_charge(reac_volume * 5)
stomach.adjust_charge(reac_volume * 0.005 * STANDARD_CELL_CHARGE)

// Welcome to the Blue Room Bar and Grill, home to Mars' finest cocktails
/datum/reagent/consumable/ethanol/rice_beer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1258,4 +1258,4 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
stomach.adjust_charge(reac_volume * 3)
stomach.adjust_charge(reac_volume * 0.003 * STANDARD_CELL_CHARGE)
2 changes: 1 addition & 1 deletion code/modules/reagents/chemistry/reagents/food_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@
var/mob/living/carbon/exposed_carbon = exposed_mob
var/obj/item/organ/internal/stomach/ethereal/stomach = exposed_carbon.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
stomach.adjust_charge(reac_volume * 30)
stomach.adjust_charge(reac_volume * 0.03 * STANDARD_CELL_CHARGE)

/datum/reagent/consumable/liquidelectricity/enriched/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
Expand Down
8 changes: 4 additions & 4 deletions code/modules/religion/religion_sects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@
/datum/religion_sect/mechanical/sect_bless(mob/living/target, mob/living/chap)
if(iscyborg(target))
var/mob/living/silicon/robot/R = target
var/charge_amt = 50
var/charge_amount = 0.05 * STANDARD_CELL_CHARGE
if(target.mind?.holy_role == HOLY_ROLE_HIGHPRIEST)
charge_amt *= 2
R.cell?.charge += charge_amt
charge_amount *= 2
R.cell?.charge += charge_amount
R.visible_message(span_notice("[chap] charges [R] with the power of [GLOB.deity]!"))
to_chat(R, span_boldnotice("You are charged by the power of [GLOB.deity]!"))
R.add_mood_event("blessing", /datum/mood_event/blessing)
Expand All @@ -171,7 +171,7 @@
var/did_we_charge = FALSE
var/obj/item/organ/internal/stomach/ethereal/eth_stomach = blessed.get_organ_slot(ORGAN_SLOT_STOMACH)
if(istype(eth_stomach))
eth_stomach.adjust_charge(60)
eth_stomach.adjust_charge(0.06 * STANDARD_CELL_CHARGE)
did_we_charge = TRUE

//if we're not targeting a robot part we stop early
Expand Down
31 changes: 20 additions & 11 deletions code/modules/surgery/organs/internal/stomach/stomach_ethereal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
icon_state = "stomach-p" //Welp. At least it's more unique in functionaliy.
desc = "A crystal-like organ that stores the electric charge of ethereals."
organ_traits = list(TRAIT_NOHUNGER) // We have our own hunger mechanic.
///basically satiety but electrical
var/crystal_charge = ETHEREAL_CHARGE_FULL
/// Where the energy of the stomach is stored.
var/obj/item/stock_parts/cell/cell
///used to keep ethereals from spam draining power sources
var/drain_time = 0

/obj/item/organ/internal/stomach/ethereal/Initialize(mapload)
. = ..()
cell = new /obj/item/stock_parts/cell/ethereal(null)

/obj/item/organ/internal/stomach/ethereal/Destroy()
QDEL_NULL(cell)
return ..()

/obj/item/organ/internal/stomach/ethereal/on_life(seconds_per_tick, times_fired)
. = ..()
adjust_charge(-ETHEREAL_DISCHARGE_RATE * seconds_per_tick)
Expand All @@ -27,11 +35,12 @@
stomach_owner.clear_alert(ALERT_ETHEREAL_OVERCHARGE)

/obj/item/organ/internal/stomach/ethereal/handle_hunger_slowdown(mob/living/carbon/human/human)
human.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (1.5 * (1 - crystal_charge / 100)))
human.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (1.5 * (1 - cell.charge() / 100)))

/obj/item/organ/internal/stomach/ethereal/proc/charge(datum/source, amount, repairs)
/obj/item/organ/internal/stomach/ethereal/proc/charge(datum/source, datum/callback/charge_cell, seconds_per_tick)
SIGNAL_HANDLER
adjust_charge(amount / 3.5)

charge_cell.Invoke(cell, seconds_per_tick / 3.5) // Ethereals don't have NT designed charging ports, so they charge slower.

/obj/item/organ/internal/stomach/ethereal/proc/on_electrocute(datum/source, shock_damage, shock_source, siemens_coeff = 1, flags = NONE)
SIGNAL_HANDLER
Expand All @@ -47,12 +56,11 @@
* Returns: The amount of energy that actually got changed in joules.
**/
/obj/item/organ/internal/stomach/ethereal/proc/adjust_charge(amount)
var/amount_changed = clamp(amount, ETHEREAL_CHARGE_NONE - crystal_charge, ETHEREAL_CHARGE_DANGEROUS - crystal_charge)
crystal_charge = crystal_charge + amount
return amount_changed
var/amount_changed = clamp(amount, ETHEREAL_CHARGE_NONE - cell.charge(), ETHEREAL_CHARGE_DANGEROUS - cell.charge())
return cell.change(amount_changed)

/obj/item/organ/internal/stomach/ethereal/proc/handle_charge(mob/living/carbon/carbon, seconds_per_tick, times_fired)
switch(crystal_charge)
switch(cell.charge())
if(-INFINITY to ETHEREAL_CHARGE_NONE)
carbon.add_mood_event("charge", /datum/mood_event/decharged)
carbon.throw_alert(ALERT_ETHEREAL_CHARGE, /atom/movable/screen/alert/emptycell/ethereal)
Expand Down Expand Up @@ -106,8 +114,9 @@

playsound(carbon, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
carbon.cut_overlay(overcharge)
tesla_zap(source = carbon, zap_range = 2, power = crystal_charge * 2.5, cutoff = 1 KILO JOULES, zap_flags = ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN | ZAP_ALLOW_DUPLICATES)
adjust_charge(ETHEREAL_CHARGE_FULL - crystal_charge)
// Only a small amount of the energy gets discharged as the zap. The rest dissipates as heat. Keeps the damage and energy from the zap the same regardless of what STANDARD_CELL_CHARGE is.
var/discharged_energy = -adjust_charge(ETHEREAL_CHARGE_FULL - cell.charge()) * min(7500 / STANDARD_CELL_CHARGE, 1)
tesla_zap(source = carbon, zap_range = 2, power = discharged_energy, cutoff = 1 KILO JOULES, zap_flags = ZAP_OBJ_DAMAGE | ZAP_LOW_POWER_GEN | ZAP_ALLOW_DUPLICATES)
carbon.visible_message(span_danger("[carbon] violently discharges energy!"), span_warning("You violently discharge energy!"))

if(prob(10)) //chance of developing heart disease to dissuade overcharging oneself
Expand Down

0 comments on commit 5c79a4f

Please sign in to comment.