Einstein-Engines
Einstein-Engines copied to clipboard
The Lightning-Factor
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
- [x] 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.
-
- [x] Function parameters should be able to parse functions for dynamic behaviour.
- [X] Adjust lightning targeting to use probability weightings, rather than a hard targeting priority.
-
- [x] Adjust LightningTarget on prototypes to use new probability weightings.
-
- [x] Balance grounding rods / tesla coils.
- [X] Implements forking lightning.
- [X] Implements the concept of lightning charge.
-
- [X] Allow tesla coils to generate power based on incoming charge, multiplied by some efficiency multiplier.
-
- [x] Scale lightning damage from a function of charge
- [x] Remove the electrified component from lightning prototypes, and use events to determine electrocute effects
- [x] Separate exploding behaviours from LightningTarget and have it trigger an explosive component instead (or something else?)
- [x] Test before review if a tesla can destroy a station without throwing a compiler error.
- [x] Fix electrocute parsing damage as an INTEGER
- [x] Make lightning functions available on Shared
Nice
- [ ] Make sure the code is not shit.
- [X] Lightning can now be configured to disable looping (lightning chaining between two targets)
- [X] 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 byLightningSystem
which encapsulates the data of any given lightning bolt.LightningContext
contains a list of everyLightningArc
that pertains to it, and iterates through them to execute lightning effects like creating a beam from one entity to another and dealing damage.LightningContext
s are stored in a dictionary with a unique index, which functions like an array that effectively can expand infinitely.
- A new
-
-
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.LightningArc
s 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 theLightningContext
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.
- 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
-
- 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.
- Random target selection used by
-
-
ShootLightning
andShootRandomLightning
have been updated to support parsing of functions rather than values. This is extremely useful for dynamic/random behaviours.
-
-
-
HitByLightningEvent
was renamed toLightningEffectEvent
, and addedLightningStageEvent
. 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 intoLightningArcReduction
,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.
- Now uses
-
- Communicates with the
Explosive
component to conditionally trigger it when struck by lightning.
- Communicates with the
-
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 inExplosive
. -
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 withFixedPoint2
.
- 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
-
C.Sh/.../ElectrocutionSystem.cs
had anint
changed to aDamageSpecifier
.
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 thatLightningSystem
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 fromLightningSystem
rather than generating a flat amount of charge whenever hit by lightning. Also renamedHitByLightningEvent
. -
C.S/.../TeslaCoilComponent.cs
has ditto. -
C.S/.../ElectricalAnomalySystem.cs
hadShootRandomLightning
updated. -
C.S/.../MicrowaveSystem.cs
hadShootRandomLightning
updated. -
C.S/.../GlimmerReactiveSystem.cs
hadShootRandomLightning
updated. -
C.S/.../LightningSparkingSystem.cs
hadHitByLightningEvent
renamed.
For unique prototype changes
-
Resources/Prototypes/Entities/Effects/lightning.yml
had every instance ofElectrified
removed, sinceLightningSystem
usesElectrocutionSystem
instead. -
Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/energyball.yml
was updated to accomodate new changes toLightningArcShooter
, and also fixed a bug whereshader: unshaded
was not put in the correct location. -
Resources/Prototypes/Entities/Structures/Power/Generation/Tesla/coil.yml
Tesla coils get a target weighting of200
, and now have theShockAbsorber
damage modifier that zeroes incoming shock damage. Grounding rods get a target weighting of400
and also haveShockAbsorber
.
Every other prototype change from hereon is simply configuring either Explosive
or LightningTarget
components.
-
Resources/Prototypes/Entities/Mobs/base.yml
Mobs get a weighting of10
. -
Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml
Airlocks get a weighting of10
. -
Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml
Lights get a weight of2
. -
Resources/Prototypes/Entities/Structures/Machines/Computers/base_structurecomputers.yml
Computers get a small explosion, and get a weight of10
. -
Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml
Machines get a small explosion, and get a weight of20
. -
Resources/Prototypes/Entities/Structures/Power/apc.yml
APCs have a moderate explosion, and get a weight of25
. -
Resources/Prototypes/Entities/Structures/Power/smes.yml
SMESes have a moderate explosion, and get a weight of75
. -
Resources/Prototypes/Entities/Structures/Power/substation.yml
Both substations maintain their large explosion, and get a weight of50
.
Media
Changelog
:cl:
- tweak: Lightning has undergone a rework, allowing lightning to fork and act more randomly.