| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 | #include "modes.h"
#include "bait.h"
#include "scene.h"
#define BMODE_WAIT 	rand_real(10., 15.)
#define SMODE_WAIT	rand_real(10., 20.)
void bait_start_mode(Bait *b, int mode)
{
    b->mode_next = scene.bmodes.rand();
    b->mode_when = b->age + BMODE_WAIT;
    switch (mode) {
    case BMODE_NORMAL: // normal mode
	if (b->attractor) {
	    delete b->attractor;
	    b->attractor = 0;
	}
	b->bspeed = b->fuzz*scene.bspeed;
	b->baccel = b->fuzz*scene.baccel;
	b->fspeed = b->fuzz*scene.fspeed;
	b->faccel = b->fuzz*scene.faccel;
	b->hue_rate = b->fuzz*scene.hue_rate;
	break;
    case BMODE_STOP: // stop mode
	if (b->attractor || b->bspeed==0) // don't do it if we're already doing it
	    break;
	b->bspeed = 0;
	b->stop_timer.add(mode, b->age + rand_real(2., 3.));
	break;
    case BMODE_ATTRACTOR: // attractor
	if (b->attractor || b->bspeed==0) // don't do it if we're already doing it
	    break;
	b->attractor = new Vec3f(b->pos + rand_vec3(-10, 10));
	b->baccel = (b->bspeed*b->bspeed/20.0);
	b->stop_timer.add(mode, b->age + rand_real(5., 10.));
	break;
    case BMODE_RAINBOW: // rainbow mode
	b->hue_rate = rand_int(10, 15)*scene.hue_rate;
	b->stop_timer.add(mode, b->age + rand_real(10., 15.));
	break;
    case BMODE_GLOW: // glow mode
	b->glow = true;
	b->stop_timer.add(mode, b->age + rand_real(10., 20.));
	break;
    case BMODE_HYPERSPEED: // hyperspeed mode
	b->bspeed = 1.5*scene.bspeed;
	b->baccel = 1.5*scene.baccel;
	b->fspeed = 2*scene.fspeed;
	b->faccel = 3*scene.faccel;
	b->stop_timer.add(mode, b->age + rand_real(10., 20.));
	break;
    case BMODE_FADED: // faded color mode
	b->hsv[1] = rand_real(0.4, 0.6);
	b->stop_timer.add(mode, b->age + rand_real(10., 20.));
	break;
    }
#ifdef DEBUG
    cerr << "baitmode=" << mode << " for " 
	<< (b->stop_timer.events.empty() ? 0 : b->stop_timer.events[0].second-b->age)
	<< "s\tnext=" << b->mode_next << " in " << b->mode_when-b->age << "s" << endl;
#endif
}
void bait_stop_mode(Bait* b, int mode)
{
    switch (mode) {
    case BMODE_NOTHING:
    case BMODE_NORMAL:
	return;
	break;
    case BMODE_STOP: // anti stop mode
	b->bspeed = b->fuzz*scene.bspeed;
	break;
    case BMODE_ATTRACTOR: // anti attractor
	delete b->attractor;
	b->attractor = 0;
	b->baccel = b->fuzz*scene.baccel;
	break;
    case BMODE_RAINBOW: // anti rainbow mode
	b->hue_rate = b->fuzz*scene.hue_rate;
	break;
    case BMODE_GLOW: // anti glow mode
	b->glow = false;
	break;
    case BMODE_HYPERSPEED: // anti hyperspeed mode
	b->bspeed = b->fuzz*scene.bspeed;
	b->baccel = b->fuzz*scene.baccel;
	b->fspeed = b->fuzz*scene.fspeed;
	b->faccel = b->fuzz*scene.faccel;
	break;
    case BMODE_FADED:
	b->hsv[1] = 0.8;
	break;
    }
#ifdef DEBUG
    cerr << "\tstopped=" << mode << endl;
#endif
}
void scene_start_mode(int mode)
{
    scene.mode_next = scene.smodes.rand();
    scene.mode_when = scene.curtime + SMODE_WAIT;
    // negatives keep them off the modelist
    switch (mode) {
    case SMODE_SWARMS: { // all-swarm mode
	int bmode = scene.bmodes.rand();
	if (bmode < 0)
	    break;
	for (GLuint i = 0; i < scene.baits.size(); i++) {
	    scene.baits[i]->stop_timer.clear(); // clear out any stops
	    bait_start_mode(scene.baits[i], BMODE_NORMAL); // set default.
	    bait_start_mode(scene.baits[i], bmode);
	}
	break;
	    }
    case SMODE_FLYKILL: { // firefly go byebye
	if (scene.flies.size() <= scene.minflies) // not too few
	    break;
	int max = (scene.flies.size() - scene.minflies);
	int n = rand_int(max/3, max);
	scene.rem_flies(n);
#ifdef DEBUG
	cerr << "deleted " << n << " flies" << endl;
#endif
	break;
	    }
    case SMODE_FLYBIRTH: { // hello firefly
	if (scene.flies.size() >= scene.maxflies) // not too many
	    break;
	int max = (scene.maxflies - scene.flies.size());
	int n = rand_int(max/3, max);
	scene.add_flies(n);
#ifdef DEBUG
	cerr << "created " << n << " flies" << endl;
#endif
	break;
	    }
    case SMODE_WINDY: // it's getting windy in here!
	scene.wind_speed *= 3;
	scene.mode_next = -SMODE_WINDY;
	break;
    case -SMODE_WINDY: // calm the wind down
	scene.wind_speed /= 3;
	break;
    case SMODE_MATRIX: {// matrix mode
	scene.matrix = scene.curtime;
	scene.matrix_axis = Vec3f(rand_int(-1, 1), rand_int(-1, 1), rand_int(-1, 1));
	if (norm2(scene.matrix_axis) == 0)
	    scene.matrix_axis = Vec3f(0, 1, 0);
	unitize(scene.matrix_axis);
	scene.mode_next = -SMODE_MATRIX;
	scene.mode_when = scene.curtime + rand_real(4.0, 5.0);
	break;
	    }
    case -SMODE_MATRIX: // anti matrix
	scene.matrix = -1.0;
	break;
    case SMODE_SWARMSPLIT: { // split mode
	if (scene.baits.size() >= scene.maxbaits) // not too many
	    break;
	Bait *b1 = scene.baits[rand_int(0, scene.baits.size()-1)];
	Bait *b2 = new Bait();
	b2->pos = b1->pos;
	scene.baits.push_back(b2);
	double fpb = (double)scene.flies.size()/scene.baits.size();
	int n = rand_int((int)(fpb/4), (int)(fpb/2));
	for (GLuint i = 0; i < scene.flies.size() && n > 0; i++) {
	    if (scene.flies[i]->bait == b1) {
		scene.flies[i]->bait = b2;
		scene.flies[i]->age = 0.0;
		n--;
	    }
	}
	break;
	    }
    case SMODE_SWARMMERGE: { // merge mode
	if (scene.baits.size() <= scene.minbaits)
	    break;
	int i1 = rand_int(0, scene.baits.size()-1);
	int i2 = rand_other(0, scene.baits.size()-1, i1);
	Bait *b1 = scene.baits[i1];
	Bait *b2 = scene.baits[i2];
	
	for (GLuint i = 0; i < scene.flies.size(); i++) {
	    if (scene.flies[i]->bait == b2) {
		scene.flies[i]->bait = b1;
		scene.flies[i]->age = 0.0;
	    }
	}
	vector<Bait*>::iterator it = scene.baits.begin();
	for (; it != scene.baits.end(); it++) {
	    if ((*it) == b2) {
		scene.baits.erase(it);
		break;
	    }
	}
	delete b2;
	break;
	    }
    }
#ifdef DEBUG
    cerr << "scenemode=" << mode << ", next=" << scene.mode_next << " in "
	 << scene.mode_when-scene.curtime << endl;
#endif
}
 |