1
0

singulo.m 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # This is a script to be loaded into GNU Octave.
  2. # - Notes -
  3. # + Be sure to check all parameters are up to date with game before use.
  4. # + The way things are tuned, only PA level 1 is stable on Saltern.
  5. # A singularity timestep is one second.
  6. # - Parameters -
  7. # It's expected that you dynamically modify these if relevant to your scenario.
  8. global pa_particle_energy_for_level_table pa_level pa_time_between_shots
  9. pa_particle_energy_for_level_table = [10, 30, 60, 100]
  10. # Note that level 0 is 1 here.
  11. pa_level = 1
  12. pa_time_between_shots = 6
  13. # Horizontal size (interior tiles) of mapped singulo cage
  14. global cage_area cage_pa1 cage_pa2 cage_pa3
  15. # __123__
  16. # +---+---+
  17. cage_area = 7
  18. cage_pa1 = 2.5
  19. cage_pa2 = 3.5
  20. cage_pa3 = 4.5
  21. global energy_drain_for_level_table
  22. energy_drain_for_level_table = [1, 2, 5, 10, 15, 20]
  23. function retval = level_for_energy (energy)
  24. retval = 1
  25. if energy >= 1500 retval = 6; return; endif
  26. if energy >= 1000 retval = 5; return; endif
  27. if energy >= 600 retval = 4; return; endif
  28. if energy >= 300 retval = 3; return; endif
  29. if energy >= 200 retval = 2; return; endif
  30. endfunction
  31. function retval = radius_for_level (level)
  32. retval = level - 0.5
  33. endfunction
  34. # - Simulator -
  35. global singulo_shot_timer
  36. singulo_shot_timer = 0
  37. function retval = singulo_step (energy)
  38. global energy_drain_for_level_table
  39. global pa_particle_energy_for_level_table pa_level pa_time_between_shots
  40. global cage_area cage_pa1 cage_pa2 cage_pa3
  41. global singulo_shot_timer
  42. level = level_for_energy(energy)
  43. energy_drain = energy_drain_for_level_table(level)
  44. energy -= energy_drain
  45. singulo_shot_timer += 1
  46. if singulo_shot_timer == pa_time_between_shots
  47. energy_gain_per_hit = pa_particle_energy_for_level_table(pa_level)
  48. # This is the bit that's complicated: the area and probability calculation.
  49. # Rather than try to work it out, let's do things by simply trying it.
  50. # This is the area of the singulo.
  51. singulo_area = radius_for_level(level) * 2
  52. # This is therefore the area in which it can move.
  53. effective_area = max(0, cage_area - singulo_area)
  54. # Assume it's at some random position within the area it can move.
  55. # (This is the weak point of the maths. It's not as simple as this really.)
  56. singulo_lpos = (rand() * effective_area)
  57. singulo_rpos = singulo_lpos + singulo_area
  58. # Check each of 3 points.
  59. n = 0.5
  60. if singulo_lpos < (cage_pa1 + n) && singulo_rpos > (cage_pa1 - n)
  61. energy += energy_gain_per_hit
  62. endif
  63. if singulo_lpos < (cage_pa2 + n) && singulo_rpos > (cage_pa2 - n)
  64. energy += energy_gain_per_hit
  65. endif
  66. if singulo_lpos < (cage_pa3 + n) && singulo_rpos > (cage_pa3 - n)
  67. energy += energy_gain_per_hit
  68. endif
  69. singulo_shot_timer = 0
  70. endif
  71. retval = energy
  72. endfunction
  73. # - Scenario -
  74. global scenario_energy
  75. scenario_energy = 100
  76. function retval = scenario (x)
  77. global scenario_energy
  78. sce = scenario_energy
  79. scenario_energy = singulo_step(sce)
  80. retval = scenario_energy
  81. endfunction
  82. # x is in seconds.
  83. x = 0:1:960
  84. plot(x, arrayfun(@scenario, x))