Subversion Repositories DIN Is Noise

Rev

Rev 2097 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* ball_ops.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#include "ball_ops.h"
#include "ball.h"
#include "vector2d.h"
#include "mondrian.h"
#include "console.h"
#include "utils.h"
#include "chrono.h"
#include "ui_list.h"

extern char BUFFER[];
extern ui_clock ui_clk;
extern const float PI_BY_180;

int ball_op::eval (ball* b) {
  int ret = 0;
  if (alarm.active) {
    ret = alarm (ui_clk());
  }
  return ret;
}

turn::turn ()  {
  alarm.triggert = TRIGGERT;
  rd.set (-CLOCKWISE, ANTI_CLOCKWISE);
  vx = vy = 0;
  angle = 0;
}

void turn::gen_angle (ball* b) {
  vx = b->vx;
  vy = b->vy;
  angle = PI_BY_180 * rd ();
}

void turn::start (ball* b) {
  alarm.start ();
  gen_angle (b);
}

int turn::eval (ball* b) {
  if (alarm.active) {
    if (alarm (ui_clk())) {
      gen_angle (b);
    } else {
      b->vx = vx;
      b->vy = vy;
      rotate_vector (b->vx, b->vy, alarm () * angle);
      b->calc_velocity_slope ();
    }
  }
  return 1;
}

speed::speed () {
  max = 0.0f;
  alarm.triggert = TRIGGERT;
  rd.set (-BRAKE, ACCELERATE);
  start = delta = 0;
}

void speed::gen_delta (ball* b) {
  start = b->V;
  delta = rd ();
}

int speed::eval (ball* b) {
  if (alarm.active) {
    if (alarm (ui_clk())) {
      gen_delta (b);
    } else {
      float a = alarm ();
      float s = start + a * delta;
      clamp (0.0f, s, max);
      b->V = s;
    }
  }
  return 1;
}

teleport::teleport () : radius (MAX_RADIUS) {
  extern const float TWO_PI;
  rd.set (0, TWO_PI);
}

int teleport::eval (ball* b) {
  int boe = ball_op::eval ();
  if (boe) {
    float theta = rd ();
    b->x += (radius * cos (theta));
    b->y += (radius * sin (theta));
    mondrian0.locate_ball (b);
  }
  return boe;
}

Clone::Clone () {
  max = 1;
  n = max;
  clone_can_clone = 0;
  offset = 0;
  alarm.active = 0;
  alarm.triggert = 1.0f;
}

extern ui_list uis;
int Clone::eval (ball* b) {
  int boe = ball_op::eval ();
  if (boe) {
    if (b->op_clone.n) {
      if (mondrian0.num_balls > max_balls) {
        sprintf (BUFFER, "Cant clone no more :( Reached Max of %d balls", max_balls);
        cons << RED << BUFFER << eol;
      } else {
        mondrian0.clone_ball (b);
        b->op_clone.n--;
      }
    } else {
      n = max;
      alarm.stop ();
      MENU.cb_clone.set_state (0, 0);
      cons << GREEN << "Finished cloning ball" << eol;
    }
  }
  return boe;
}

Transform::Transform () {
  alarm.triggert = 5;
}

int Transform::eval (ball* b) {
  int boe = ball_op::eval ();
  if (boe) {
    int t = rules [b->type];
    if (t == ball::INVALID) {
      rnd<float> rd (ball::BOUNCER, ball::HEALER);
      t = int (rd () + 0.5f);
    }
    b->set_type (t);
  }
  return boe;
}