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

The Lightning-Factor #543

Open
wants to merge 34 commits into
base: master
Choose a base branch
from

Conversation

WarMechanic
Copy link
Contributor

@WarMechanic WarMechanic commented Jul 12, 2024

Description

So, the lightning system in the current back-end is actually a little bit smelly. Different levels of charge are determined by prototypes, and lightning targeting is hard fixated on ground rods. You can technically generate infinite power with a fork, a microwave, and a tesla coil, as tesla coils generate flat amounts of charge.

Another problem, is VM's obligation to emulate lightning effects rather than use a (eventually) cleaner lightning system due to a mixed-bag combination of the above described. I'm hoping that lightning changes could be used in the future to make any of the following possible:

  • Emperor Palpatine glimmerloose
  • Psionic slave power plants
  • Psionically induced EMP

This PR aims to improve the lightning system by first grounding it in reality. Lightning has an established charge that is absorbed by entities as it bounces, as well as implementing lightning forking behaviours. To accomplish this, lightning now pre-calculates a path before executing any effects (otherwise you would encounter anomalies like charge simply vanishing). Lightning has been made more unpredictable by swapping targeting priorities for probability weightings. If you have live sparks near machinery, you are probably doing something wrong.

This PR isn't done yet, I have yet to adjust the effects based on charge although the concept is implemented. Everything should eventually be overrideable with code, and even ignore the discharge system altogether.


TODO

Must-have

  • Rework the lightning system so behaviour may be configured in-code rather than in-prototype. Must be VM approved if Noospheric Chain-Lightning has even a slim chance of existing.
    • Function parameters should be able to parse functions for dynamic behaviour.
  • Adjust lightning targeting to use probability weightings, rather than a hard targeting priority.
    • Adjust LightningTarget on prototypes to use new probability weightings.
    • Balance grounding rods / tesla coils.
  • Implements forking lightning.
  • Implements the concept of lightning charge.
    • Allow tesla coils to generate power based on incoming charge, multiplied by some efficiency multiplier.
    • Scale lightning damage from a function of charge
  • Remove the electrified component from lightning prototypes, and use events to determine electrocute effects
  • Separate exploding behaviours from LightningTarget and have it trigger an explosive component instead (or something else?)
  • Test before review if a tesla can destroy a station without throwing a compiler error.
  • Fix electrocute parsing damage as an INTEGER
  • Make lightning functions available on Shared

Nice

  • Make sure the code is not shit.
  • Lightning can now be configured to disable looping (lightning chaining between two targets)
  • Fix lightning ball sprites being unshaded.
  • Add construction and machine boards for Tesla coils and Grounding rods

The future

  • Translate lightning charge to overvolt behaviours in a future overvoltage system.
  • Create a Static Discharger infrastructure that releases excess voltage in the form of dangerous lightning.
  • Find a connection between this lightning refactor and my other EMP overhaul.
  • Extend LightningTarget!
    • Allow metallic items to contribute to a player's lightning susceptibility.
    • Combine a shotgun and a tesla gun for fun.
  • Remake the Tesla Gun as a traitor item that anchors to the station power grid. Must use the half-life tau cannon sound or its dead to me.

Technical Details

Code changes from most complex to least complex

  • C.S/.../LightningSystem.cs is the big fish here, and is hardly recognisable from its original incarnation:

    • LightningSystem functions now use a 'charge' variable which can be used to calculate factors like damage.
    • A new LightningContext struct is used by LightningSystem which encapsulates the data of any given lightning bolt. LightningContext contains a list of every LightningArc that pertains to it, and iterates through them to execute lightning effects like creating a beam from one entity to another and dealing damage. LightningContexts are stored in a dictionary with a unique index, which functions like an array that effectively can expand infinitely.
    • LightningSystem has been reworked to support forking arcs, which requires each lightning step to be depth wise. Previously recursive behaviour wouldn't work as the lightning would continuously fork until it ran out of arcs, creating a chain. LightningArcs are a new type which are fed into a priority queue system and dequeued based on lowest arc depth. When the priority queue is empty, it immediately triggers lightning effects and cleans the LightningContext dictionary.
    • As an extension of the above, the entire path of any given lightning bolt is now calculated before any effects take place. This is useful for ensuring charge consistency such that a fired lightning bolt will not net positive charge after bouncing into tesla coils. Every time lightning arcs, an equal portion of charge is subtracted as a 'discharge' variable and used for damage calculations. The total charge may be modified afterwards by LightningTarget which reduces effect on subsequent targets.
    • Random target selection used by LightningSystem functions use a weighted probability dictionary rather than a sorted list. This makes lightning behaviour much more random, but still permits control over the general likelihood of one thing being targeted over another. This was done to make lightning more spectacular.
    • ShootLightning and ShootRandomLightning have been updated to support parsing of functions rather than values. This is extremely useful for dynamic/random behaviours.
    • HitByLightningEvent was renamed to LightningEffectEvent, and added LightningStageEvent. Some of the file diffs will mention this name change.
  • C.S/.../LightningTargetSystem.cs is adjacent and responsible for creating targets for lightning to arc toward.

    • LightningArcResistance has been extended into LightningArcReduction, LightningChargeReduction, LightningChargeMultiplier to encompass new lightning interactions.
    • Now uses ElectrocutionSystem to conditionally deal damage and apply the paralysed status effect, rather than relying on prototype physics collisions.
    • Communicates with the Explosive component to conditionally trigger it when struck by lightning.
  • C.S/.../LightningTargetComponent.cs has changes which reflect the above system changes. Additionally, all redundany explosive-related-vars have been culled as they should be used in Explosive.

  • C.S/.../ElectrocutionSystem.cs had some questionable logic fixed where some functions would return false depending on input parameters. Essentially, the effect of damage and stunning is independent. This allows machines to take damage from electrocute (finally putting electronic shock vulnerability to use!)

    • Also allowed parsing a damage specifier instead of an INT (???) for damage. This gives breathing room for creative reuse of the lightning system, like dealing cold or psychic damage. Instances of int were replaced with FixedPoint2.
  • C.Sh/.../ElectrocutionSystem.cs had an int changed to a DamageSpecifier.

Beyond the core logic, users of the LightningSystem were also changed to various degrees:

  • C.S/.../LightningArcShooterSystem.cs has been updated to use the new function parsing functionality that LightningSystem provides. Instead of shooting a random number of lightning bolts with a flat number of arcs, the system tallies a random number of bolts and a random number of arcs to fire. With extremely good(?) luck, you could roll 4 bolts each with only 1 arc. With quantum bad(?) luck, you could roll a singular bolt that extends a 16 arc long chain from tesla containment all the way to the Engineering substation, which proceeds to cut emitter power which then looses the tesla.

  • C.S/.../LightningArcShooterComponent.cs has variable changes that reflect the system changes.

  • C.S/.../TeslaCoilSystem.cs now uses discharge from LightningSystem rather than generating a flat amount of charge whenever hit by lightning. Also renamed HitByLightningEvent.

  • C.S/.../TeslaCoilComponent.cs has ditto.

  • C.S/.../ElectricalAnomalySystem.cs had ShootRandomLightning updated.

  • C.S/.../MicrowaveSystem.cs had ShootRandomLightning updated.

  • C.S/.../GlimmerReactiveSystem.cs had ShootRandomLightning updated.

  • C.S/.../LightningSparkingSystem.cs had HitByLightningEvent renamed.

For unique prototype changes

  • Resources/Prototypes/Entities/Effects/lightning.yml had every instance of Electrified removed, since LightningSystem uses ElectrocutionSystem instead.

  • Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml was updated to accomodate new changes to LightningArcShooter, and also fixed a bug where shader: unshaded was not put in the correct location.

  • Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml Tesla coils get a target weighting of 200, and now have the ShockAbsorber damage modifier that zeroes incoming shock damage. Grounding rods get a target weighting of 400 and also have ShockAbsorber.

Every other prototype change from hereon is simply configuring either Explosive or LightningTarget components.

  • Resources/Prototypes/Entities/Mobs/base.yml Mobs get a weighting of 10.

  • Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml Airlocks get a weighting of 10.

  • Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml Lights get a weight of 2.

  • Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml Computers get a small explosion, and get a weight of 10.

  • Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml Machines get a small explosion, and get a weight of 20.

  • Resources/Prototypes/Entities/Structures/Power/apc.yml APCs have a moderate explosion, and get a weight of 25.

  • Resources/Prototypes/Entities/Structures/Power/smes.yml SMESes have a moderate explosion, and get a weight of 75.

  • Resources/Prototypes/Entities/Structures/Power/substation.yml Both substations maintain their large explosion, and get a weight of 50.


Media

Example Media Embed


Changelog

🆑

  • tweak: Lightning has undergone a rework, allowing lightning to fork and act more randomly.

@github-actions github-actions bot added the Changes: C# Changes any cs files label Jul 12, 2024
@SimpleStation14 SimpleStation14 changed the title The Lightning-factor The Lightning-Factor Jul 12, 2024
@github-actions github-actions bot added the Changes: YML Changes any yml files label Jul 12, 2024
@WarMechanic WarMechanic marked this pull request as ready for review July 14, 2024 12:19
@WarMechanic
Copy link
Contributor Author

id like to say that this PR is relatively stable, ive run out of time to work on it so i can look at any reviews after im done with my trip :)

@github-actions github-actions bot added the Status: Merge Conflict FIX YOUR PR AAAGH label Jul 20, 2024
Copy link
Contributor

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the Status: Merge Conflict FIX YOUR PR AAAGH label Aug 24, 2024
@@ -203,6 +204,20 @@ private void OnElectrifiedInteractUsing(EntityUid uid, ElectrifiedComponent elec
TryDoElectrifiedAct(uid, args.User, siemens, electrified);
}

/*
im pretty sure this was removed in a cherry-pick, but id like to keep it around for future overvoltage stuff
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
im pretty sure this was removed in a cherry-pick, but id like to keep it around for future overvoltage stuff
I'm pretty sure this was removed in a cherry-pick, but I'd like to keep it around for future overvoltage stuff

// A logarithm allows a curve of damage that grows quickly, but slows down dramatically past a value. This keeps the damage to a reasonable range.
const float DamageShift = 1.67f; // Shifts the curve for an overall higher or lower damage baseline
const float CeilingCoefficent = 1.35f; // Adjusts the approach to maximum damage, higher = Higher top damage
const float LogGrowth = 0.00001f; // Adjusts the growth speed of the curve
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be arguments on the function

@@ -13,60 +13,31 @@ namespace Content.Server.Lightning.Components;
public sealed partial class LightningTargetComponent : Component
{
/// <summary>
/// The probability that this target will not be ignored by a lightning strike. This is necessary for Tesla's balance.
/// The probability weighting of being stuck by lightning, compared against other nearby lightning targets.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The probability weighting of being stuck by lightning, compared against other nearby lightning targets.
/// The probability weighting of being struck by lightning, compared against other nearby lightning targets.

Comment on lines +25 to 26
/// For the love of god, do not make this number negative.
/// </summary>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// For the love of god, do not make this number negative.
/// </summary>
/// </summary>
/// <remarks>For the love of god, do not make this number negative.</remarks>

[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly IEntityManager _entMan = default!;

// a priority queue is required to iterate through Arcs of various depth
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// a priority queue is required to iterate through Arcs of various depth
// A priority queue is required to iterate through Arcs of various depth

Comment on lines +43 to +44
_lightning.ShootRandomLightnings(anomaly, range, anomaly.Comp.MaxBoltCount * 3, 100000f,
maxArcs: 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_lightning.ShootRandomLightnings(anomaly, range, anomaly.Comp.MaxBoltCount * 3, 100000f,
maxArcs: 3
_lightning.ShootRandomLightnings(anomaly, range, anomaly.Comp.MaxBoltCount * 3, 100000f, maxArcs: 3

@@ -287,7 +287,12 @@ private void OnMeleeThrowOnHitAttempt(Entity<SharedGlimmerReactiveComponent> ent
args.Cancelled = true;
args.Handled = true;

_lightning.ShootRandomLightnings(ent, 10, 2, "SuperchargedLightning", 2, false);
_lightning.ShootRandomLightnings(ent, 10f, 2, 50000f,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_lightning.ShootRandomLightnings(ent, 10f, 2, 50000f,
_lightning.ShootRandomLightnings(
ent,
10f,
2,
50000f,

@@ -9,42 +9,62 @@ namespace Content.Server.Tesla.Components;
[RegisterComponent, Access(typeof(LightningArcShooterSystem)), AutoGenerateComponentPause]
public sealed partial class LightningArcShooterComponent : Component
{
/// <summary>
/// The total number of arcs that an energy ball can create from any one shot
/// Increasing this value can lead to increasingly unpredictable ranges
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Increasing this value can lead to increasingly unpredictable ranges
/// Increasing this value can lead to increasingly unpredictable ranges
/// </summary>

/// Fires a lightning bolt from one entity to another
/// Only done serverside
/// </summary>
public virtual void ShootLightning(EntityUid user, EntityUid target, float totalCharge,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public virtual void ShootLightning(EntityUid user, EntityUid target, float totalCharge,
public virtual void ShootLightning(
EntityUid user,
EntityUid target,
float totalCharge,

/// Looks for objects with a LightningTarget component in the radius, and fire lightning at (weighted) random targets
/// Only done serverside
/// </summary>
public virtual void ShootRandomLightnings(EntityUid user, float lightningRadius, int lightningCount, float lightningChargePer, EntityCoordinates? queryPosition = null, bool lightningStacking = true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public virtual void ShootRandomLightnings(EntityUid user, float lightningRadius, int lightningCount, float lightningChargePer, EntityCoordinates? queryPosition = null, bool lightningStacking = true,
public virtual void ShootRandomLightnings(
EntityUid user,
float lightningRadius,
int lightningCount,
float lightningChargePer,
EntityCoordinates? queryPosition = null,
bool lightningStacking = true,

@FoxxoTrystan FoxxoTrystan added Priority: 4-Low Should be resolved at some point Size: 2-Large For large issues/PRs Type: Rework Large changes to a system, like a mix between the Balancing, Codebase, and Respace labels labels Sep 17, 2024
@FoxxoTrystan
Copy link
Member

Any updates on this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changes: C# Changes any cs files Changes: YML Changes any yml files Priority: 4-Low Should be resolved at some point Size: 2-Large For large issues/PRs Status: Needs Review Someone please review this Type: Rework Large changes to a system, like a mix between the Balancing, Codebase, and Respace labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants