mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 06:00:16 +01:00
[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 🆑 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. /🆑 --------- Co-authored-by: san7890 <the@san7890.com>
This commit is contained in:
@@ -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 (7.5 SECONDS)
|
||||
/// 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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -286,12 +286,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 (120 SECONDS)
|
||||
@@ -435,7 +435,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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -29,19 +29,20 @@
|
||||
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)
|
||||
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)
|
||||
return
|
||||
stomach.drain_time = world.time + APC_DRAIN_TIME
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, balloon_alert), ethereal, "draining power"), alert_timer_duration)
|
||||
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)
|
||||
@@ -51,20 +52,19 @@
|
||||
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
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, balloon_alert), ethereal, "transfering power"), alert_timer_duration)
|
||||
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!")
|
||||
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!")
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
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_notice("You receive some charge from [src], wasting some in the process."))
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -946,7 +946,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)
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -46,12 +55,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)
|
||||
@@ -99,8 +107,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
|
||||
|
||||
Reference in New Issue
Block a user