Makes the singularity engine actually work stably. (#4068)
* Add GNU Octave script for tuning singularity engine. startsingularityengine is now properly tuned & sets up radiation collectors. FTLize RadiationCollectorComponent. * Fix bugs with radiation collectors producing infinite power. * Ensure singularities don't instantly annihilate other singularities (causing new singularities to instantly dissolve) Technically found by a "bug" where a singularity generator would make multiple singularities, but this renders that bug harmless. * Tune singularity shield emitters to hopefully randomly fail less, and add an Octave script for looking into that * Fix singularity shader * Map in an unfinished PA into Saltern * Correct PA particles being counted twice by singularity calculations, add singulo food component * Hopefully stop "level 1 singulo stuck in a corner" issues by freezing it when it goes to level 1 from any other level * Apply suggestions on 'jazz' PR
This commit is contained in:
95
Tools/singulo.m
Normal file
95
Tools/singulo.m
Normal file
@@ -0,0 +1,95 @@
|
||||
# This is a script to be loaded into GNU Octave.
|
||||
|
||||
# - Notes -
|
||||
# + Be sure to check all parameters are up to date with game before use.
|
||||
# + The way things are tuned, only PA level 1 is stable on Saltern.
|
||||
# A singularity timestep is one second.
|
||||
|
||||
# - Parameters -
|
||||
# It's expected that you dynamically modify these if relevant to your scenario.
|
||||
global pa_particle_energy_for_level_table pa_level pa_time_between_shots
|
||||
pa_particle_energy_for_level_table = [10, 30, 60, 100]
|
||||
# Note that level 0 is 1 here.
|
||||
pa_level = 1
|
||||
pa_time_between_shots = 6
|
||||
|
||||
# Horizontal size (interior tiles) of mapped singulo cage
|
||||
global cage_area cage_pa1 cage_pa2 cage_pa3
|
||||
# __123__
|
||||
# +---+---+
|
||||
cage_area = 7
|
||||
cage_pa1 = 2.5
|
||||
cage_pa2 = 3.5
|
||||
cage_pa3 = 4.5
|
||||
|
||||
global energy_drain_for_level_table
|
||||
energy_drain_for_level_table = [1, 2, 5, 10, 15, 20]
|
||||
function retval = level_for_energy (energy)
|
||||
retval = 1
|
||||
if energy >= 1500 retval = 6; return; endif
|
||||
if energy >= 1000 retval = 5; return; endif
|
||||
if energy >= 600 retval = 4; return; endif
|
||||
if energy >= 300 retval = 3; return; endif
|
||||
if energy >= 200 retval = 2; return; endif
|
||||
endfunction
|
||||
function retval = radius_for_level (level)
|
||||
retval = level - 0.5
|
||||
endfunction
|
||||
|
||||
# - Simulator -
|
||||
|
||||
global singulo_shot_timer
|
||||
singulo_shot_timer = 0
|
||||
|
||||
function retval = singulo_step (energy)
|
||||
global energy_drain_for_level_table
|
||||
global pa_particle_energy_for_level_table pa_level pa_time_between_shots
|
||||
global cage_area cage_pa1 cage_pa2 cage_pa3
|
||||
global singulo_shot_timer
|
||||
level = level_for_energy(energy)
|
||||
energy_drain = energy_drain_for_level_table(level)
|
||||
energy -= energy_drain
|
||||
singulo_shot_timer += 1
|
||||
if singulo_shot_timer == pa_time_between_shots
|
||||
energy_gain_per_hit = pa_particle_energy_for_level_table(pa_level)
|
||||
# This is the bit that's complicated: the area and probability calculation.
|
||||
# Rather than try to work it out, let's do things by simply trying it.
|
||||
# This is the area of the singulo.
|
||||
singulo_area = radius_for_level(level) * 2
|
||||
# This is therefore the area in which it can move.
|
||||
effective_area = max(0, cage_area - singulo_area)
|
||||
# Assume it's at some random position within the area it can move.
|
||||
# (This is the weak point of the maths. It's not as simple as this really.)
|
||||
singulo_lpos = (rand() * effective_area)
|
||||
singulo_rpos = singulo_lpos + singulo_area
|
||||
# Check each of 3 points.
|
||||
n = 0.5
|
||||
if singulo_lpos < (cage_pa1 + n) && singulo_rpos > (cage_pa1 - n)
|
||||
energy += energy_gain_per_hit
|
||||
endif
|
||||
if singulo_lpos < (cage_pa2 + n) && singulo_rpos > (cage_pa2 - n)
|
||||
energy += energy_gain_per_hit
|
||||
endif
|
||||
if singulo_lpos < (cage_pa3 + n) && singulo_rpos > (cage_pa3 - n)
|
||||
energy += energy_gain_per_hit
|
||||
endif
|
||||
singulo_shot_timer = 0
|
||||
endif
|
||||
retval = energy
|
||||
endfunction
|
||||
|
||||
# - Scenario -
|
||||
|
||||
global scenario_energy
|
||||
scenario_energy = 100
|
||||
|
||||
function retval = scenario (x)
|
||||
global scenario_energy
|
||||
sce = scenario_energy
|
||||
scenario_energy = singulo_step(sce)
|
||||
retval = scenario_energy
|
||||
endfunction
|
||||
|
||||
# x is in seconds.
|
||||
x = 0:1:960
|
||||
plot(x, arrayfun(@scenario, x))
|
||||
Reference in New Issue
Block a user