1 /*
2 * ball_ops.cc
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7 
8 #include "ball_ops.h"
9 #include "ball.h"
10 #include "vector2d.h"
11 #include "mondrian.h"
12 #include "console.h"
13 #include "utils.h"
14 #include "chrono.h"
15 #include "ui_list.h"
16 
17 extern char BUFFER[];
18 extern ui_clock ui_clk;
19 extern const float PI_BY_180;
20 
eval(ball * b)21 int ball_op::eval (ball* b) {
22 	int ret = 0;
23 	if (alarm.active) {
24 		ret = alarm (ui_clk());
25 	}
26 	return ret;
27 }
28 
turn()29 turn::turn ()  {
30 	alarm.triggert = TRIGGERT;
31 	rd.set (-CLOCKWISE, ANTI_CLOCKWISE);
32 	vx = vy = 0;
33 	angle = 0;
34 }
35 
gen_angle(ball * b)36 void turn::gen_angle (ball* b) {
37 	vx = b->vx;
38 	vy = b->vy;
39 	angle = PI_BY_180 * rd ();
40 }
41 
start(ball * b)42 void turn::start (ball* b) {
43 	alarm.start ();
44 	gen_angle (b);
45 }
46 
eval(ball * b)47 int turn::eval (ball* b) {
48 	if (alarm.active) {
49 		if (alarm (ui_clk())) {
50 			gen_angle (b);
51 		} else {
52 			b->vx = vx;
53 			b->vy = vy;
54 			rotate_vector (b->vx, b->vy, alarm () * angle);
55 			b->calc_velocity_slope ();
56 		}
57 	}
58 	return 1;
59 }
60 
speed()61 speed::speed () {
62 	max = 0.0f;
63 	alarm.triggert = TRIGGERT;
64 	rd.set (-BRAKE, ACCELERATE);
65 	start = delta = 0;
66 }
67 
gen_delta(ball * b)68 void speed::gen_delta (ball* b) {
69 	start = b->V;
70 	delta = rd ();
71 }
72 
eval(ball * b)73 int speed::eval (ball* b) {
74 	if (alarm.active) {
75 		if (alarm (ui_clk())) {
76 			gen_delta (b);
77 		} else {
78 			float a = alarm ();
79 			float s = start + a * delta;
80 			clamp (0.0f, s, max);
81 			b->V = s;
82 		}
83 	}
84 	return 1;
85 }
86 
teleport()87 teleport::teleport () : radius (MAX_RADIUS) {
88 	extern const float TWO_PI;
89 	rd.set (0, TWO_PI);
90 }
91 
eval(ball * b)92 int teleport::eval (ball* b) {
93 	int boe = ball_op::eval ();
94 	if (boe) {
95 		float theta = rd ();
96 		b->x += (radius * cos (theta));
97 		b->y += (radius * sin (theta));
98 		mondrian0.locate_ball (b);
99 	}
100 	return boe;
101 }
102 
Clone()103 Clone::Clone () {
104 	max = 1;
105 	n = max;
106 	clone_can_clone = 0;
107 	offset = 0;
108 	alarm.active = 0;
109 	alarm.triggert = 1.0f;
110 }
111 
112 extern ui_list uis;
eval(ball * b)113 int Clone::eval (ball* b) {
114 	int boe = ball_op::eval ();
115 	if (boe) {
116 		if (b->op_clone.n) {
117 			if (mondrian0.num_balls > max_balls) {
118 				sprintf (BUFFER, "Cant clone no more :( Reached Max of %d balls", max_balls);
119 				cons << RED << BUFFER << eol;
120 			} else {
121 				mondrian0.clone_ball (b);
122 				b->op_clone.n--;
123 			}
124 		} else {
125 			n = max;
126 			alarm.stop ();
127 			MENU.cb_clone.set_state (0, 0);
128 			cons << GREEN << "Finished cloning ball" << eol;
129 		}
130 	}
131 	return boe;
132 }
133 
Transform()134 Transform::Transform () {
135 	alarm.triggert = 5;
136 }
137 
eval(ball * b)138 int Transform::eval (ball* b) {
139 	int boe = ball_op::eval ();
140 	if (boe) {
141 		int t = rules [b->type];
142 		if (t == ball::INVALID) {
143 			rnd<float> rd (ball::BOUNCER, ball::HEALER);
144 			t = int (rd () + 0.5f);
145 		}
146 		b->set_type (t);
147 	}
148 	return boe;
149 }
150