- touch = get_closest_bubble(nextbub);
- while (! null_bubble(touch)) {
- switch (merge_bubbles(nextbub, touch)) {
- case 2:
- /* touch ate nextbub and survived */
- nextbub = touch;
- break;
- case 1:
- /* nextbub ate touch and survived */
- break;
- case 0:
- /* somebody ate someone else but they exploded */
- nextbub = (Bubble *)NULL;
- break;
- default:
- /* something went wrong */
- fprintf(stderr, "Error occurred in insert_new_bubble()\n");
- exit(1);
- }
- /* Check to see if there are any other bubbles still in the area
- and if we need to do this all over again for them. */
- if (! null_bubble(nextbub))
- touch = get_closest_bubble(nextbub);
- else
- touch = (Bubble *)NULL;
+ touch = get_closest_bubble(st, nextbub);
+ if (null_bubble(touch))
+ return;
+
+ while (1) {
+
+ /* Merge all touching bubbles */
+ while (! null_bubble(touch)) {
+ switch (merge_bubbles(st, nextbub, touch)) {
+ case 2:
+ /* touch ate nextbub and survived */
+ nextbub = touch;
+ break;
+ case 1:
+ /* nextbub ate touch and survived */
+ break;
+ case 0:
+ /* somebody ate someone else but they exploded */
+ nextbub = (Bubble *)NULL;
+ break;
+ default:
+ /* something went wrong */
+ fprintf(stderr, "Error occurred in insert_new_bubble()\n");
+ exit(1);
+ }
+
+ /* Check to see if any bubble survived. */
+ if (null_bubble(nextbub))
+ break;
+
+ /* Check to see if there are any other bubbles still in the area
+ and if we need to do this all over again for them. */
+ touch = get_closest_bubble(st, nextbub);
+ }
+
+ if (null_bubble(nextbub))
+ break;
+
+ /* Shift bubble down. Break if we run off the screen. */
+ if (st->drop) {
+ if (drop_bubble( st, nextbub ) == -1)
+ break;
+ }
+
+ /* Check to see if there are any other bubbles still in the area
+ and if we need to do this all over again for them. */
+ touch = get_closest_bubble(st, nextbub);
+ if (null_bubble(touch)) {
+ /* We also continue every so often if we're dropping and the bubble is at max size */
+ if (st->drop) {
+ if (st->simple) {
+ if ((nextbub->area >= st->bubble_areas[st->bubble_max_radius - 1]) && (random() % 2 == 0))
+ continue;
+ }
+#ifdef FANCY_BUBBLES
+ else {
+ if ((nextbub->step >= st->num_bubble_pixmaps - 1) && (random() % 2 == 0))
+ continue;
+ }
+#endif /* FANCY_BUBBLES */
+ }
+ break;
+ }
+
+ }
+}
+
+
+static void
+leave_trail(struct state *st, Bubble *bb )
+{
+ Bubble *tmp;
+
+ tmp = new_bubble(st);
+ tmp->x = bb->x;
+ tmp->y = bb->y - ((bb->radius + 10) * st->drop_dir);
+ tmp->cell_index = pixel_to_mesh(st, tmp->x, tmp->y);
+ add_to_mesh(st, tmp);
+ insert_new_bubble(st, tmp);
+ show_bubble( st, tmp );
+}
+
+
+static int
+drop_bubble( struct state *st, Bubble *bb )
+{
+ int newmi;
+
+ hide_bubble( st, bb );
+
+ if (st->simple)
+ (bb->y) += (st->bubble_droppages[bb->radius] * st->drop_dir);
+#ifdef FANCY_BUBBLES
+ else
+ (bb->y) += (st->step_pixmaps[bb->step]->droppage * st->drop_dir);
+#endif /* FANCY_BUBBLES */
+ if ((bb->y < 0) || (bb->y > st->screen_height)) {
+ delete_bubble_in_mesh( st, bb, DELETE_BUBBLE );
+ return -1;
+ }
+
+ show_bubble( st, bb );
+
+ /* Now adjust locations and cells if need be */
+ newmi = pixel_to_mesh(st, bb->x, bb->y);
+ if (newmi != bb->cell_index) {
+ delete_bubble_in_mesh(st, bb, KEEP_BUBBLE);
+ bb->cell_index = newmi;
+ add_to_mesh(st, bb);