Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] Converts arbitrary energy units to the joule. Fixes conservation of energy issues relating to charging cells. #2595

Merged
merged 2 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/guides/STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ deal_damage(10) // Fine! The proc name makes it obvious `10` is the damage...at
deal_damage(10, FIRE) // Also fine! `FIRE` makes it obvious the second parameter is damage type.
deal_damage(damage = 10) // Redundant, but not prohibited.
use_power(30) // Fine! `30` is obviously something like watts.
use_energy(30 JOULES) // Use energy in joules.
turn_on(30) // Not fine!
turn_on(power_usage = 30) // Fine!
Expand Down
2 changes: 1 addition & 1 deletion _maps/shuttles/emergency_medisim.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@
iron_cost = 0;
maximum_idle = 1;
name = "binoculars fabricator";
power_used = 0;
energy_used = 0;
starting_amount = 25000
},
/turf/open/floor/mineral/titanium/yellow,
Expand Down
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 (7.5 SECONDS)
/// How much power ethereals gain/drain from APCs.
#define APC_POWER_GAIN 200
#define APC_POWER_GAIN (200 KILO JOULES)

// Wires & EMPs:
/// The wire value used to reset the APCs wires after one's EMPed.
Expand Down
5 changes: 5 additions & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,8 @@ GLOBAL_LIST_INIT(arm_zones, list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
#define DEATHMATCH_NOT_PLAYING 0
#define DEATHMATCH_PRE_PLAYING 1
#define DEATHMATCH_PLAYING 2

/// The amount of energy needed to increase the burn force by 1 damage during electrocution.
#define JOULES_PER_DAMAGE (25 KILO JOULES)
/// Calculates the amount of burn force when applying this much energy to a mob via electrocution from an energy source.
#define ELECTROCUTE_DAMAGE(energy) (energy >= 1 KILO JOULES ? clamp(20 + round(energy / JOULES_PER_DAMAGE), 20, 195) + rand(-5,5) : 0)
4 changes: 2 additions & 2 deletions code/__DEFINES/devices.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#define INSPECTOR_PRINT_SOUND_MODE_FAFAFOGGY 4
#define BANANIUM_CLOWN_INSPECTOR_PRINT_SOUND_MODE_LAST 4
#define CLOWN_INSPECTOR_PRINT_SOUND_MODE_LAST 4
#define INSPECTOR_POWER_USAGE_HONK 15
#define INSPECTOR_POWER_USAGE_NORMAL 5
#define INSPECTOR_ENERGY_USAGE_HONK (15 KILO JOULES)
#define INSPECTOR_ENERGY_USAGE_NORMAL (5 KILO JOULES)
#define INSPECTOR_TIME_MODE_SLOW 1
#define INSPECTOR_TIME_MODE_FAST 2
#define INSPECTOR_TIME_MODE_HONK 3
Expand Down
7 changes: 4 additions & 3 deletions code/__DEFINES/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#define AREA_USAGE_STATIC_EQUIP 4
#define AREA_USAGE_STATIC_LIGHT 5
#define AREA_USAGE_STATIC_ENVIRON 6
#define AREA_USAGE_LEN AREA_USAGE_STATIC_ENVIRON // largest idx
#define AREA_USAGE_APC_CHARGE 7
#define AREA_USAGE_LEN AREA_USAGE_APC_CHARGE // largest idx

/// Index of the first dynamic usage channel
#define AREA_USAGE_DYNAMIC_START AREA_USAGE_EQUIP
Expand All @@ -27,8 +28,8 @@
#define ACTIVE_POWER_USE 2

///Base global power consumption for idling machines
#define BASE_MACHINE_IDLE_CONSUMPTION 100
///Base global power consumption for active machines
#define BASE_MACHINE_IDLE_CONSUMPTION (100 WATTS)
///Base global power consumption for active machines. The unit is ambiguous (joules or watts) depending on the use case for dynamic users.
#define BASE_MACHINE_ACTIVE_CONSUMPTION (BASE_MACHINE_IDLE_CONSUMPTION * 10)

/// Bitflags for a machine's preferences on when it should start processing. For use with machinery's `processing_flags` var.
Expand Down
14 changes: 7 additions & 7 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,14 @@
//Used as an upper limit for species that continuously gain nutriment
#define NUTRITION_LEVEL_ALMOST_FULL 535

//Charge levels for Ethereals
//Charge levels for Ethereals, in joules.
#define ETHEREAL_CHARGE_NONE 0
#define ETHEREAL_CHARGE_LOWPOWER 400
#define ETHEREAL_CHARGE_NORMAL 1000
#define ETHEREAL_CHARGE_ALMOSTFULL 1500
#define ETHEREAL_CHARGE_FULL 2000
#define ETHEREAL_CHARGE_OVERLOAD 2500
#define ETHEREAL_CHARGE_DANGEROUS 3000
#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 CRYSTALIZE_COOLDOWN_LENGTH (120 SECONDS)
Expand Down
4 changes: 2 additions & 2 deletions code/__DEFINES/mod.dm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// Default value for the max_complexity var on MODsuits
#define DEFAULT_MAX_COMPLEXITY 15

/// Default cell drain per process on MODsuits
#define DEFAULT_CHARGE_DRAIN 5
/// The default cell drain of a modsuit. The standard modsuit active power usage drains this much energy per modsuit second.
#define DEFAULT_CHARGE_DRAIN (0.005 * STANDARD_CELL_CHARGE) // A standard cell lasts 200 seconds with this on active power usage, while a high power one lasts 2,000 seconds.

/// Default time for a part to seal
#define MOD_ACTIVATION_STEP_TIME (2 SECONDS)
Expand Down
17 changes: 12 additions & 5 deletions code/__DEFINES/power.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@
#define SOLAR_TRACK_TIMED 1
#define SOLAR_TRACK_AUTO 2

///conversion ratio from joules to watts
#define WATTS / 0.002
///conversion ratio from watts to joules
#define JOULES * 0.002
///The watt is the standard unit of power for this codebase. Do not change this.
#define WATT 1
///The joule is the standard unit of energy for this codebase. Do not change this.
#define JOULE 1
///The watt is the standard unit of power for this codebase. You can use this with other defines to clarify that it will be multiplied by time.
#define WATTS * WATT
///The joule is the standard unit of energy for this codebase. You can use this with other defines to clarify that it will not be multiplied by time.
#define JOULES * JOULE

GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
///The amount of energy, in joules, a standard powercell has.
#define STANDARD_CELL_CHARGE (1 MEGA JOULES) // 1 MJ.

GLOBAL_VAR_INIT(CHARGELEVEL, 0.01) // Cap for how fast cells charge, as a percentage per second (.01 means cellcharge is capped to 1% per second)

// Converts cable layer to its human readable name
GLOBAL_LIST_INIT(cable_layer_to_name, list(
Expand Down
5 changes: 3 additions & 2 deletions code/__DEFINES/projectiles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,9 @@
#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED))
#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT))

/// The amount of energy that a standard energy weapon cell can hold
#define STANDARD_CELL_CHARGE 1000
///The self charging rate of energy guns that magically recharge themselves, in watts.
#define STANDARD_ENERGY_GUN_SELF_CHARGE_RATE (0.05 * STANDARD_CELL_CHARGE)

/// Macro to turn a number of laser shots into an energy cost, based on the above define
/// e.g. LASER_SHOTS(12, STANDARD_CELL_CHARGE) means 12 shots
#define LASER_SHOTS(X, MAX_CHARGE) (((100 * MAX_CHARGE) - ((100 * MAX_CHARGE) % X)) / (100 * X)) // I wish I could just use round, but it can't be used in datum members
4 changes: 4 additions & 0 deletions code/__DEFINES/robots.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@

/// Special value to reset cyborg's lamp_cooldown
#define BORG_LAMP_CD_RESET -1
/// How many watts per lamp power is consumed while the lamp is on.
#define BORG_LAMP_POWER_CONSUMPTION (1000 WATTS)
/// The minimum power consumption of a cyborg.
#define BORG_MINIMUM_POWER_CONSUMPTION (500 WATTS)

//Module slot define
///The third module slots is disabed.
Expand Down
21 changes: 21 additions & 0 deletions code/__DEFINES/si.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Prefix values.
#define QUECTO * 1e-30
#define RONTO * 1e-27
#define YOCTO * 1e-24
#define ZEPTO * 1e-21
#define ATTO * 1e-18
#define FEMPTO * 1e-15
#define PICO * 1e-12
#define NANO * 1e-9
#define MICRO * 1e-6
#define MILLI * 1e-3
#define KILO * 1e3
#define MEGA * 1e6
#define GIGA * 1e9
#define TERA * 1e12
#define PETA * 1e15
#define EXA * 1e18
#define ZETTA * 1e21
#define YOTTA * 1e24
#define RONNA * 1e27
#define QUETTA * 1e30
5 changes: 5 additions & 0 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@
#define SSEXPLOSIONS_MOVABLES 2
#define SSEXPLOSIONS_THROWS 3

// Machines subsystem subtasks.
#define SSMACHINES_APCS_EARLY 1
#define SSMACHINES_MACHINES 2
#define SSMACHINES_APCS_LATE 3

// Wardrobe subsystem tasks
#define SSWARDROBE_STOCK 1
#define SSWARDROBE_INSPECT 2
Expand Down
31 changes: 16 additions & 15 deletions code/__HELPERS/maths.dm
Original file line number Diff line number Diff line change
Expand Up @@ -154,27 +154,28 @@
var/prefix = prefixes[prefix_index]
. = list(SI_COEFFICIENT = coefficient, SI_UNIT = " [prefix][unit]")

///Format a power value in prefixed watts.
/proc/display_power(powerused)
return siunit(powerused, "W", 3)
/**Format a power value in prefixed watts.
* Converts from energy if convert is true.
* Args:
* - power: The value of power to format.
* - convert: Whether to convert this from joules.
* Returns: The string containing the formatted power.
*/
/proc/display_power(power, convert = TRUE)
power = convert ? energy_to_power(power) : power
return siunit(power, "W", 3)

///Format an energy value in prefixed joules.
/proc/display_joules(units)
/proc/display_energy(units)
return siunit(units, "J", 3)

/proc/joules_to_energy(joules)
///Converts the joule to the watt, assuming SSmachines tick rate.
/proc/energy_to_power(joules)
return joules * (1 SECONDS) / SSmachines.wait

/proc/energy_to_joules(energy_units)
return energy_units * SSmachines.wait / (1 SECONDS)

///Format an energy value measured in Power Cell units.
/proc/display_energy(units)
// APCs process every (SSmachines.wait * 0.1) seconds, and turn 1 W of
// excess power into watts when charging cells.
// With the current configuration of wait=20 and CELLRATE=0.002, this
// means that one unit is 1 kJ.
return display_joules(energy_to_joules(units) WATTS)
///Converts the watt to the joule, assuming SSmachines tick rate.
/proc/power_to_energy(watts)
return watts * SSmachines.wait / (1 SECONDS)

///chances are 1:value. anyprob(1) will always return true
/proc/anyprob(value)
Expand Down
60 changes: 48 additions & 12 deletions code/controllers/subsystem/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ SUBSYSTEM_DEF(machines)

var/list/processing = list()
var/list/currentrun = list()
var/list/apc_early_processing = list()
var/list/apc_late_processing = list()
var/current_part = SSMACHINES_APCS_EARLY
///List of all powernets on the server.
var/list/datum/powernet/powernets = list()

Expand Down Expand Up @@ -43,7 +46,7 @@ SUBSYSTEM_DEF(machines)
for(var/next_type in typesof(machine_type))
var/list/found_machines = machines_by_type[next_type]
if(found_machines)
machines += found_machines
machines += found_machines
return machines


Expand Down Expand Up @@ -79,19 +82,52 @@ SUBSYSTEM_DEF(machines)
if (!resumed)
for(var/datum/powernet/powernet as anything in powernets)
powernet.reset() //reset the power state.
current_part = SSMACHINES_APCS_EARLY
src.currentrun = apc_early_processing.Copy()

//APC early processing. Draws static power usages from their grids.
if(current_part == SSMACHINES_APCS_EARLY)
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/obj/machinery/power/apc/apc = currentrun[currentrun.len]
currentrun.len--
if(QDELETED(apc) || apc.early_process(wait * 0.1) == PROCESS_KILL)
apc_early_processing -= apc
apc.datum_flags &= ~DF_ISPROCESSING
if(MC_TICK_CHECK)
return
current_part = SSMACHINES_MACHINES
src.currentrun = processing.Copy()

//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun

while(currentrun.len)
var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len--
if(QDELETED(thing) || thing.process(wait * 0.1) == PROCESS_KILL)
processing -= thing
thing.datum_flags &= ~DF_ISPROCESSING
if (MC_TICK_CHECK)
return
//General machine processing. Their power usage can be dynamic and based on surplus power, so they come after static power usage have been applied.
if(current_part == SSMACHINES_MACHINES)
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/obj/machinery/thing = currentrun[currentrun.len]
currentrun.len--
if(QDELETED(thing) || thing.process(wait * 0.1) == PROCESS_KILL)
processing -= thing
thing.datum_flags &= ~DF_ISPROCESSING
if (MC_TICK_CHECK)
return
current_part = SSMACHINES_APCS_LATE
src.currentrun = apc_late_processing.Copy()

//APC late processing. APCs will use the remaining power on the grid to charge their cells if needed.
//This is applied at the end so charging APCs don't cause others to discharge by taking all the power from the grid before machines use power.
if(current_part == SSMACHINES_APCS_LATE)
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/obj/machinery/power/apc/apc = currentrun[currentrun.len]
currentrun.len--
if(QDELETED(apc) || apc.late_process(wait * 0.1) == PROCESS_KILL)
apc_late_processing -= apc
apc.datum_flags &= ~DF_ISPROCESSING
if(MC_TICK_CHECK)
return

/datum/controller/subsystem/machines/proc/setup_template_powernets(list/cables)
var/obj/structure/cable/PC
Expand Down
4 changes: 2 additions & 2 deletions code/datums/components/shell.dm
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@
if(attached_circuit)
remove_circuit()
return
location.use_power(power_to_use, AREA_USAGE_EQUIP)
location.apc?.terminal?.use_energy(power_to_use, channel = AREA_USAGE_EQUIP)
power_used_in_minute += power_to_use
COOLDOWN_START(src, power_used_cooldown, 1 MINUTES)
return COMPONENT_OVERRIDE_POWER_USAGE
Expand Down Expand Up @@ -327,7 +327,7 @@
else if(circuitboard.loc != parent_atom)
circuitboard.forceMove(parent_atom)
attached_circuit.set_shell(parent_atom)

// call after set_shell() sets on to true
if(shell_flags & SHELL_FLAG_REQUIRE_ANCHOR)
attached_circuit.set_on(parent_atom.anchored)
Expand Down
6 changes: 3 additions & 3 deletions code/datums/mutations/touch.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
///This var decides if the spell should chain, dictated by presence of power chromosome
var/chain = FALSE
///Affects damage, should do about 1 per limb
var/zap_power = 7500
var/zap_power = 7.5 KILO JOULES
///Range of tesla shock bounces
var/zap_range = 7
///flags that dictate what the tesla shock can interact with, Can only damage mobs, Cannot damage machines or generate energy
Expand All @@ -60,7 +60,7 @@
span_userdanger("[caster] electrocutes you!"),
)
if(chain)
tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1e3, zap_flags = zap_flags)
tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1 KILO JOULES, zap_flags = zap_flags)
carbon_victim.visible_message(span_danger("An arc of electricity explodes out of [victim]!"))
return TRUE

Expand All @@ -72,7 +72,7 @@
span_userdanger("[caster] electrocutes you!"),
)
if(chain)
tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1e3, zap_flags = zap_flags)
tesla_zap(source = victim, zap_range = zap_range, power = zap_power, cutoff = 1 KILO JOULES, zap_flags = zap_flags)
living_victim.visible_message(span_danger("An arc of electricity explodes out of [victim]!"))
return TRUE

Expand Down
Loading
Loading