You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.1 KiB

  1. package effects
  2. import (
  3. "fmt"
  4. "git.aiterp.net/lucifer3/server/device"
  5. "math/rand"
  6. "time"
  7. )
  8. type Random struct {
  9. States []device.State `json:"states,omitempty"`
  10. Interpolate bool `json:"interpolate,omitempty"`
  11. AnimationMS int64 `json:"animationMs,omitempty"`
  12. }
  13. func (e Random) State(_, _, _, _ int) device.State {
  14. if len(e.States) == 0 {
  15. return device.State{}
  16. }
  17. indexFactor := rand.Float64()
  18. stateIncrement := 1.0 / float64(len(e.States)-1)
  19. for i := range e.States {
  20. a := float64(i) * stateIncrement
  21. if indexFactor >= a {
  22. si := e.States[i]
  23. sj := e.States[(i+1)%len(e.States)]
  24. f := (indexFactor - a) / stateIncrement
  25. if f < 0 || f > 1 {
  26. panic(f)
  27. }
  28. if e.Interpolate {
  29. return si.Interpolate(sj, f)
  30. } else if f < 0.5 {
  31. return si
  32. } else {
  33. return sj
  34. }
  35. }
  36. }
  37. return e.States[len(e.States)-1]
  38. }
  39. func (e Random) Frequency() time.Duration {
  40. return time.Duration(e.AnimationMS) * time.Millisecond
  41. }
  42. func (e Random) EffectDescription() string {
  43. return fmt.Sprintf("Random(states:%s, anim:%dms, int:%t)", statesDescription(e.States), e.AnimationMS, e.Interpolate)
  44. }