Example #1
0
int64_t az_baddie_point_value(az_baddie_kind_t kind) {
  assert(kind != AZ_BAD_NOTHING);
  switch (kind) {
    case AZ_BAD_NOTHING: AZ_ASSERT_UNREACHABLE();
    case AZ_BAD_BASILISK: return 500;
    case AZ_BAD_FAKER: return 750;
    case AZ_BAD_FORCER: return 1000;
    case AZ_BAD_GHOST: return 450;
    case AZ_BAD_GUARD: return 400;
    case AZ_BAD_TANK: return 300;
  }
  AZ_ASSERT_UNREACHABLE();
}
Example #2
0
static int baddie_hitpoints(az_baddie_kind_t kind) {
  assert(kind != AZ_BAD_NOTHING);
  switch (kind) {
    case AZ_BAD_NOTHING: AZ_ASSERT_UNREACHABLE();
    case AZ_BAD_BASILISK: return 2;
    case AZ_BAD_FAKER: return 3;
    case AZ_BAD_FORCER: return 2;
    case AZ_BAD_GHOST: return 1;
    case AZ_BAD_GUARD: return 4;
    case AZ_BAD_TANK: return 1;
  }
  AZ_ASSERT_UNREACHABLE();
}
Example #3
0
static bool parse_directive(az_load_planet_t *loader) {
  switch (az_rgetc(loader->reader)) {
    case 'H': parse_hint_directive(loader); return true;
    case 'T': parse_paragraph_directive(loader); return true;
    case 'Z': parse_zone_directive(loader); return true;
    case EOF: return false;
    default: FAIL();
  }
  AZ_ASSERT_UNREACHABLE();
}
Example #4
0
static void draw_baddie_internal(const az_baddie_t *baddie, az_clock_t clock) {
  const float flare = baddie->armor_flare;
  const float frozen = (baddie->frozen <= 0.0 ? 0.0 :
                        baddie->frozen >= 0.2 ? 0.5 + 0.5 * baddie->frozen :
                        az_clock_mod(3, 2, clock) < 2 ? 0.6 : 0.0);
  if (baddie->frozen > 0.0) clock = 0;
  switch (baddie->kind) {
    case AZ_BAD_NOTHING: AZ_ASSERT_UNREACHABLE();
    case AZ_BAD_MARKER:
      glColor3f(1, 0, 1); // magenta
      glBegin(GL_LINE_STRIP); {
        glVertex2f(-20, 0); glVertex2f(20, 0); glVertex2f(0, 20);
        glVertex2f(0, -20); glVertex2f(20, 0);
      } glEnd();
      break;
    case AZ_BAD_NORMAL_TURRET:
      az_draw_bad_normal_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_ZIPPER:
      az_draw_bad_zipper(baddie, frozen, clock);
      break;
    case AZ_BAD_BOUNCER:
      az_draw_bad_bouncer(baddie, frozen, clock);
      break;
    case AZ_BAD_ATOM:
      az_draw_bad_atom(baddie, frozen, clock);
      break;
    case AZ_BAD_SPINER:
      az_draw_bad_spiner(baddie, frozen, clock);
      break;
    case AZ_BAD_BOX:
      assert(frozen == 0.0);
      draw_box(baddie, false, flare);
      break;
    case AZ_BAD_ARMORED_BOX:
      assert(frozen == 0.0);
      draw_box(baddie, true, flare);
      break;
    case AZ_BAD_CLAM:
      az_draw_bad_clam(baddie, frozen, clock);
      break;
    case AZ_BAD_NIGHTBUG:
      az_draw_bad_nightbug(baddie, frozen, clock);
      break;
    case AZ_BAD_SPINE_MINE:
      az_draw_bad_spine_mine(baddie, frozen, clock);
      break;
    case AZ_BAD_BROKEN_TURRET:
      az_draw_bad_broken_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_ZENITH_CORE:
      az_draw_bad_zenith_core(baddie, clock);
      break;
    case AZ_BAD_ARMORED_TURRET:
      az_draw_bad_armored_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_DRAGONFLY:
      az_draw_bad_dragonfly(baddie, frozen, clock);
      break;
    case AZ_BAD_CAVE_CRAWLER:
      az_draw_bad_cave_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_CRAWLING_TURRET:
      az_draw_bad_crawling_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_HORNET:
      az_draw_bad_hornet(baddie, frozen, clock);
      break;
    case AZ_BAD_BEAM_SENSOR:
      az_draw_bad_beam_sensor(baddie, frozen, clock);
      break;
    case AZ_BAD_BEAM_SENSOR_INV:
      az_draw_bad_beam_sensor_inv(baddie, frozen, clock);
      break;
    case AZ_BAD_ROCKWYRM:
      az_draw_bad_rockwyrm(baddie);
      break;
    case AZ_BAD_WYRM_EGG:
      az_draw_bad_wyrm_egg(baddie, frozen, clock);
      break;
    case AZ_BAD_WYRMLING:
      az_draw_bad_wyrmling(baddie, frozen);
      break;
    case AZ_BAD_TRAPDOOR:
      glBegin(GL_TRIANGLE_FAN); {
        glColor3f(0.8f - 0.8f * frozen, 0.5, 0.5f + 0.5f * frozen);
        glVertex2f(0, 0);
        glColor3f(0.4f - 0.4f * frozen, 0.2, 0.2f + 0.3f * frozen);
        const az_polygon_t polygon = baddie->data->main_body.polygon;
        for (int i = polygon.num_vertices - 1, j = 0;
             i < polygon.num_vertices; i = j++) {
          glVertex2d(polygon.vertices[i].x, polygon.vertices[i].y);
        }
      } glEnd();
      glPushMatrix(); {
        assert(!az_vnonzero(baddie->components[0].position));
        glRotated(AZ_RAD2DEG(baddie->components[0].angle), 0, 0, 1);
        glBegin(GL_POLYGON); {
          const az_component_data_t *data = &baddie->data->components[0];
          glColor3f(0.5f - 0.1f * frozen, 0.5, 0.5f + 0.1f * frozen);
          for (int i = 0; i < data->polygon.num_vertices; ++i) {
            if (i == 2) glColor3f(0.4f - 0.1f * frozen, 0.3,
                                  0.3f + 0.1f * frozen);
            glVertex2d(data->polygon.vertices[i].x,
                       data->polygon.vertices[i].y);
          }
        } glEnd();
      } glPopMatrix();
      break;
    case AZ_BAD_CAVE_SWOOPER:
      az_draw_bad_cave_swooper(baddie, frozen, clock);
      break;
    case AZ_BAD_ICE_CRAWLER:
      az_draw_bad_ice_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_BEAM_TURRET:
      az_draw_bad_beam_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_CRAB_1:
    case AZ_BAD_OTH_CRAB_2:
      az_draw_bad_oth_crab(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_ORB_1:
    case AZ_BAD_OTH_ORB_2:
      az_draw_bad_oth_orb(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_SNAPDRAGON:
      az_draw_bad_oth_snapdragon(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_RAZOR_1:
      az_draw_bad_oth_razor_1(baddie, frozen, clock);
      break;
    case AZ_BAD_GUN_SENSOR:
      az_draw_bad_gun_sensor(baddie, frozen, clock);
      break;
    case AZ_BAD_SECURITY_DRONE:
      az_draw_bad_security_drone(baddie, frozen, clock);
      break;
    case AZ_BAD_SMALL_TRUCK:
      az_draw_bad_small_truck(baddie, frozen, clock);
      break;
    case AZ_BAD_HEAT_RAY:
      az_draw_bad_heat_ray(baddie, frozen, clock);
      break;
    case AZ_BAD_NUCLEAR_MINE:
      draw_mine_arms(18, flare, frozen);
      // Body:
      glBegin(GL_POLYGON); {
        glColor3f(0.65 + 0.3 * flare - 0.3 * frozen, 0.65 - 0.3 * flare,
                  0.5 - 0.3 * flare + 0.5 * frozen);
        for (int i = 0; i <= 360; i += 60) {
          glVertex2d(8 * cos(AZ_DEG2RAD(i)), 8 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      glBegin(GL_QUAD_STRIP); {
        for (int i = 0; i <= 360; i += 60) {
          glColor3f(0.65 + 0.3 * flare - 0.3 * frozen, 0.65 - 0.3 * flare,
                    0.5 - 0.3 * flare + 0.5 * frozen);
          glVertex2d(8 * cos(AZ_DEG2RAD(i)), 8 * sin(AZ_DEG2RAD(i)));
          glColor3f(0.35f + 0.3f * flare, 0.35f, 0.15f + 0.3f * frozen);
          glVertex2d(12 * cos(AZ_DEG2RAD(i)), 12 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      // Radiation symbol:
      if (baddie->state == 1 && az_clock_mod(2, 3, clock)) glColor3f(1, 0, 0);
      else glColor3f(0, 0, 0.5f * frozen);
      glBegin(GL_TRIANGLE_FAN); {
        glVertex2d(0, 0);
        for (int i = 0; i <= 360; i += 30) {
          glVertex2d(1.5 * cos(AZ_DEG2RAD(i)), 1.5 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      for (int j = 60; j < 420; j += 120) {
        glBegin(GL_QUAD_STRIP); {
          for (int i = j - 30; i <= j + 30; i += 10) {
            glVertex2d(3 * cos(AZ_DEG2RAD(i)), 3 * sin(AZ_DEG2RAD(i)));
            glVertex2d(8 * cos(AZ_DEG2RAD(i)), 8 * sin(AZ_DEG2RAD(i)));
          }
        } glEnd();
      }
      break;
    case AZ_BAD_BEAM_WALL:
      glBegin(GL_QUADS); {
        // Interior:
        glColor3f(0.3, 0.3, 0.3);
        glVertex2f(50, 15); glVertex2f(-50, 15);
        glVertex2f(-50, -15); glVertex2f(50, -15);
        // Diagonal struts:
        for (int i = 0; i < 3; ++i) {
          const float x = -50 + 32 * i;
          for (int j = 0; j < 2; ++j) {
            const float y = (j ? -12 : 12);
            glColor3f(0.75 + 0.25 * flare, 0.75, 0.75);
            glVertex2f(x, y); glVertex2f(x + 32, -y);
            glColor3f(0.35 + 0.35 * flare, 0.4, 0.35);
            glVertex2f(x + 32 + 4, -y); glVertex2f(x + 4, y);
          }

        }
        // Top and bottom struts:
        for (int y = -10; y <= 15; y += 25) {
          glColor3f(0.75 + 0.25 * flare, 0.75, 0.75);
          glVertex2f(52, y); glVertex2f(-52, y);
          glColor3f(0.35 + 0.35 * flare, 0.4, 0.35);
          glVertex2f(-52, y - 5); glVertex2f(52, y - 5);
        }
      } glEnd();
      break;
    case AZ_BAD_SPARK:
      glBegin(GL_TRIANGLE_FAN); {
        glColor4f(1, 1, 1, 0.8);
        glVertex2f(0, 0);
        glColor4f(0, 1, 0, 0);
        for (int i = 0; i <= 360; i += 45) {
          const double radius =
            (i % 2 ? 1.0 : 0.5) * (8.0 + 0.25 * az_clock_zigzag(8, 3, clock));
          const double theta = AZ_DEG2RAD(i + 7 * az_clock_mod(360, 1, clock));
          glVertex2d(radius * cos(theta), radius * sin(theta));
        }
      } glEnd();
      break;
    case AZ_BAD_MOSQUITO:
      az_draw_bad_mosquito(baddie, frozen, clock);
      break;
    case AZ_BAD_ARMORED_ZIPPER:
      az_draw_bad_armored_zipper(baddie, frozen, clock);
      break;
    case AZ_BAD_FORCEFIEND:
      az_draw_bad_forcefiend(baddie);
      break;
    case AZ_BAD_CHOMPER_PLANT:
      az_draw_bad_chomper_plant(baddie, frozen, clock);
      break;
    case AZ_BAD_COPTER_HORZ:
    case AZ_BAD_COPTER_VERT:
      az_draw_bad_copter(baddie, frozen, clock);
      break;
    case AZ_BAD_URCHIN:
      az_draw_bad_urchin(baddie, frozen, clock);
      break;
    case AZ_BAD_BOSS_DOOR:
      az_draw_bad_boss_door(baddie, frozen, clock);
      break;
    case AZ_BAD_ROCKET_TURRET:
      az_draw_bad_rocket_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_MINI_ARMORED_ZIPPER:
      az_draw_bad_mini_armored_zipper(baddie, frozen, clock);
      break;
    case AZ_BAD_SPINED_CRAWLER:
      az_draw_bad_spined_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_DEATH_RAY:
      az_draw_bad_death_ray(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_GUNSHIP:
      az_draw_bad_oth_gunship(baddie, frozen, clock);
      break;
    case AZ_BAD_FIREBALL_MINE:
      glPushMatrix(); {
        glScalef(1, 1.07, 1);
        const GLfloat blink =
          fmax(flare, (baddie->state == 1 &&
                       az_clock_mod(2, 4, clock) == 0 ? 0.5 : 0.0));
        const double radius = baddie->data->main_body.bounding_radius;
        glBegin(GL_TRIANGLE_FAN); {
          glColor3f(0.6f + 0.4f * blink, 0.6f, 0.6f);
          glVertex2d(-0.15 * radius, 0.2 * radius);
          glColor3f(0.2f + 0.3f * blink, 0.2f, 0.2f);
          for (int i = 0; i <= 360; i += 15) {
            glVertex2d(radius * cos(AZ_DEG2RAD(i)),
                       radius * sin(AZ_DEG2RAD(i)));
          }
        } glEnd();
        const double hurt = (baddie->data->max_health - baddie->health) /
          baddie->data->max_health;
        for (int i = 0; i < 5; ++i) {
          const double angle = AZ_DEG2RAD(20) + i * AZ_DEG2RAD(72);
          az_draw_cracks(az_vpolar(-radius, angle), angle,
                         5 * hurt * (1.5 - 0.33 * ((3 * i) % 5)));
        }
        for (int i = 0; i < 10; ++i) {
          glBegin(GL_TRIANGLE_FAN); {
            glColor3f(0.4f + 0.3f * blink, 0.4f, 0.4f);
            glVertex2d(radius - 4, 0);
            glColor3f(0.2f + 0.3f * blink, 0.2f, 0.2f);
            glVertex2d(radius - 1, 2); glVertex2d(radius + 6, 0);
            glVertex2d(radius - 1, -2);
          } glEnd();
          glRotatef(36, 0, 0, 1);
        }
        glRotatef(18, 0, 0, 1);
        for (int i = 0; i < 5; ++i) {
          glBegin(GL_TRIANGLE_FAN); {
            glColor3f(0.6f + 0.4f * blink, 0.6f, 0.6f);
            glVertex2d(radius - 9, 0);
            glColor3f(0.4f + 0.3f * blink, 0.4f, 0.4f);
            glVertex2d(radius - 8, 2); glVertex2d(radius - 3, 0);
            glVertex2d(radius - 8, -2);
          } glEnd();
          glRotatef(72, 0, 0, 1);
        }
      } glPopMatrix();
      break;
    case AZ_BAD_LEAPER: {
      const double tilt_degrees =
        (baddie->state != 0 ? 0.0 :
         (1.0 - fmin(baddie->cooldown / 0.5, 1.0)) * 10.0 +
         az_clock_zigzag(3, 8, clock));
      // Legs:
      for (int flip = 0; flip < 2; ++flip) {
        glPushMatrix(); {
          if (flip) glScalef(1, -1, 1);
          // Upper leg:
          glPushMatrix(); {
            glTranslated(-0.5 * tilt_degrees, 0, 0);
            if (baddie->state == 0) glRotatef(48 - tilt_degrees, 0, 0, 1);
            else glRotatef(70, 0, 0, 1);
            glBegin(GL_QUAD_STRIP); {
              glColor3f(0, 0.2, 0.1); glVertex2d(0, 5); glVertex2d(21, 2);
              glColor3f(0, 0.3, 0.2); glVertex2d(0, 0); glVertex2d(23, 0);
              glColor3f(0, 0.2, 0.1); glVertex2d(0, -4); glVertex2d(21, -3);
            } glEnd();
          } glPopMatrix();
          // Lower leg:
          if (baddie->state == 0) {
            glTranslated(-20, 20 + az_clock_zigzag(3, 8, clock), 0);
            glRotated(-tilt_degrees, 0, 0, 1);
          } else {
            glTranslated(-30, 18, 0);
            glRotated(5, 0, 0, 1);
          }
          glBegin(GL_QUAD_STRIP); {
            glColor3f(0, 0.25, 0.1); glVertex2d(2, 5);
            glColor3f(0.25, 0.15, 0); glVertex2d(35, 4);
            glColor3f(0.5f * flare, 0.6, 0.4f + 0.6f * frozen);
            glVertex2d(0, 0);
            glColor3f(0.3f + 0.3f * flare, 0.2, frozen);
            glVertex2d(35, 0);
            glColor3f(0, 0.25, 0.1); glVertex2d(2, -6);
            glColor3f(0.25, 0.15, 0); glVertex2d(35, -4);
          } glEnd();
          glBegin(GL_QUAD_STRIP); {
            glColor3f(0, 0.25, 0.1); glVertex2d(18, 6); glVertex2d(35, 4);
            glColor3f(0.5f * flare, 0.6f + 0.4f * flare, 0.4f + 0.6f * frozen);
            glVertex2d(16, 0); glVertex2d(35, 0);
            glColor3f(0, 0.25, 0.1); glVertex2d(18, -6); glVertex2d(35, -4);
          } glEnd();
          // Foot:
          glBegin(GL_TRIANGLE_FAN); {
            glColor3f(0.5, 0.5, 0.5); glVertex2d(0, -1);
            glColor3f(0.2, 0.3, 0.3);
            for (int i = -105; i <= 105; i += 30) {
              glVertex2d(5 * cos(AZ_DEG2RAD(i)), 7 * sin(AZ_DEG2RAD(i)) - 1);
            }
          } glEnd();
          // Knee knob:
          glTranslatef(35, 0, 0);
          glBegin(GL_TRIANGLE_FAN); {
            glColor3f(0.5f * flare, 0.6, 0.4 + 0.6f * frozen);
            glVertex2d(0, 0);
            glColor3f(0, 0.25, 0.1);
            for (int i = -135; i <= 135; i += 30) {
              glVertex2d(6 * cos(AZ_DEG2RAD(i)), 5 * sin(AZ_DEG2RAD(i)));
            }
          } glEnd();
          // Knee spike:
          glBegin(GL_TRIANGLE_FAN); {
            glColor3f(0.5, 0.5, 0.5); glVertex2f(4, 0);
            glColor3f(0.25, 0.25, 0.25);
            glVertex2f(5, 2); glVertex2f(10, 0); glVertex2f(5, -2);
          } glEnd();
        } glPopMatrix();
      }
      glPushMatrix(); {
        glTranslated(-0.5 * tilt_degrees, 0, 0);
        // Teeth:
        const int x = (baddie->state == 0 ? 0 : 3);
        for (int y = -2; y <= 2; y += 4) {
          glBegin(GL_TRIANGLE_FAN); {
            glColor3f(0.5, 0.5, 0.5); glVertex2i(8 + x, y);
            glColor3f(0.25, 0.25, 0.25);
              glVertex2i(9 + x, 2 + y); glVertex2i(15 + x, y);
              glVertex2i(9 + x, -2 + y);
          } glEnd();
        }
        // Body:
        glBegin(GL_TRIANGLE_FAN); {
          glColor3f(flare, 0.9, 0.5f + 0.5f * frozen); glVertex2d(-3, 0);
          glColor3f(0.5f * flare, 0.25, 0.1f + 0.9f * frozen);
          glVertex2d(-10, 0);
          for (int i = -135; i <= 135; i += 30) {
            glVertex2d(12 * cos(AZ_DEG2RAD(i)), 9 * sin(AZ_DEG2RAD(i)));
          }
          glVertex2d(-10, 0);
        } glEnd();
        // Eye:
        glBegin(GL_POLYGON); {
          glColor4f(1, 0, 0, 0.4);
          glVertex2f(10, 1); glVertex2f(9, 2); glVertex2f(7, 0);
          glVertex2f(9, -2), glVertex2f(10, -1);
        } glEnd();
      } glPopMatrix();
    } break;
    case AZ_BAD_BOUNCER_90:
      az_draw_bad_bouncer_90(baddie, frozen, clock);
      break;
    case AZ_BAD_PISTON:
      az_draw_bad_piston(baddie, frozen, clock);
      break;
    case AZ_BAD_ARMORED_PISTON:
    case AZ_BAD_ARMORED_PISTON_EXT:
      az_draw_bad_armored_piston(baddie, frozen, clock);
      break;
    case AZ_BAD_INCORPOREAL_PISTON:
    case AZ_BAD_INCORPOREAL_PISTON_EXT:
      az_draw_bad_incorporeal_piston(baddie, frozen, clock);
      break;
    case AZ_BAD_CRAWLING_MORTAR:
      az_draw_bad_crawling_mortar(baddie, frozen, clock);
      break;
    case AZ_BAD_FIRE_ZIPPER:
      az_draw_bad_fire_zipper(baddie, frozen, clock);
      break;
    case AZ_BAD_SUPER_SPINER:
      az_draw_bad_super_spiner(baddie, frozen, clock);
      break;
    case AZ_BAD_HEAVY_TURRET:
      az_draw_bad_heavy_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_ECHO_SWOOPER:
      az_draw_bad_echo_swooper(baddie, frozen, clock);
      break;
    case AZ_BAD_SUPER_HORNET:
      az_draw_bad_super_hornet(baddie, frozen, clock);
      break;
    case AZ_BAD_KILOFUGE:
      az_draw_bad_kilofuge(baddie, clock);
      break;
    case AZ_BAD_ICE_CRYSTAL:
      az_draw_bad_ice_crystal(baddie);
      break;
    case AZ_BAD_SWITCHER:
      az_draw_bad_switcher(baddie, frozen, clock);
      break;
    case AZ_BAD_FAST_BOUNCER:
      az_draw_bad_fast_bouncer(baddie, frozen, clock);
      break;
    case AZ_BAD_PROXY_MINE:
      draw_mine_arms(15, flare, frozen);
      // Body:
      glBegin(GL_TRIANGLE_FAN); {
        glColor3f(0.65 + 0.35 * flare - 0.3 * frozen, 0.65 - 0.3 * flare,
                  0.65 - 0.3 * flare + 0.35 * frozen);
        glVertex2f(0, 0);
        glColor3f(0.35 + 0.3 * flare - 0.15 * frozen, 0.35 - 0.15 * flare,
                  0.35 - 0.15 * flare + 0.3 * frozen);
        for (int i = 0; i <= 360; i += 15) {
          glVertex2d(7 * cos(AZ_DEG2RAD(i)), 7 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      // Light bulb:
      glBegin(GL_TRIANGLE_FAN); {
        if (baddie->state == 1 && az_clock_mod(2, 3, clock)) {
          glColor3f(1, 0.6, 0.5);
        } else glColor3f(0.2, 0.2, 0.2);
        glVertex2f(0, 0);
        glColor3f(0, 0, 0);
        for (int i = 0; i <= 360; i += 20) {
          glVertex2d(3 * cos(AZ_DEG2RAD(i)), 3 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      break;
    case AZ_BAD_NIGHTSHADE:
      az_draw_bad_nightshade(baddie, frozen, clock);
      break;
    case AZ_BAD_AQUATIC_CHOMPER:
      az_draw_bad_aquatic_chomper(baddie, frozen, clock);
      break;
    case AZ_BAD_SMALL_FISH:
      az_draw_bad_small_fish(baddie, frozen, clock);
      break;
    case AZ_BAD_NOCTURNE:
      az_draw_bad_nocturne(baddie, clock);
      break;
    case AZ_BAD_MYCOFLAKKER:
      az_draw_bad_mycoflakker(baddie, frozen, clock);
      break;
    case AZ_BAD_MYCOSTALKER:
      az_draw_bad_mycostalker(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_CRAWLER:
      az_draw_bad_oth_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_FIRE_CRAWLER:
      az_draw_bad_fire_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_JUNGLE_CRAWLER:
      az_draw_bad_jungle_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_FORCE_EGG:
      az_draw_bad_force_egg(baddie);
      break;
    case AZ_BAD_FORCELING:
      az_draw_bad_forceling(baddie, frozen, clock);
      break;
    case AZ_BAD_JUNGLE_CHOMPER:
      az_draw_bad_jungle_chomper(baddie, frozen, clock);
      break;
    case AZ_BAD_SMALL_AUV:
      az_draw_bad_small_auv(baddie, frozen, clock);
      break;
    case AZ_BAD_SENSOR_LASER:
      az_draw_bad_sensor_laser(baddie, frozen, clock);
      break;
    case AZ_BAD_ERUPTION:
      draw_eruption_bubble(10.0, 47, clock);
      glPushMatrix(); {
        glTranslatef(0, -9, 0);
        draw_eruption_bubble(5.0, 23, clock);
      } glPopMatrix();
      glPushMatrix(); {
        glTranslatef(0, 8, 0);
        draw_eruption_bubble(6.0, 27, clock);
      } glPopMatrix();
      break;
    case AZ_BAD_PYROFLAKKER:
      az_draw_bad_pyroflakker(baddie, frozen, clock);
      break;
    case AZ_BAD_PYROSTALKER:
      az_draw_bad_pyrostalker(baddie, frozen, clock);
      break;
    case AZ_BAD_DEMON_SWOOPER:
      az_draw_bad_demon_swooper(baddie, frozen, clock);
      break;
    case AZ_BAD_FIRE_CHOMPER:
      az_draw_bad_fire_chomper(baddie, frozen, clock);
      break;
    case AZ_BAD_GRABBER_PLANT:
      az_draw_bad_grabber_plant(baddie, frozen, clock);
      break;
    case AZ_BAD_POP_OPEN_TURRET:
      az_draw_bad_pop_open_turret(baddie, frozen, clock);
      break;
    case AZ_BAD_GNAT:
      az_draw_bad_gnat(baddie, frozen, clock);
      break;
    case AZ_BAD_CREEPY_EYE:
      az_draw_bad_creepy_eye(baddie, frozen, clock);
      break;
    case AZ_BAD_BOMB_SENSOR:
      az_draw_bad_bomb_sensor(baddie, frozen, clock);
      break;
    case AZ_BAD_ROCKET_SENSOR:
      az_draw_bad_rocket_sensor(baddie, frozen, clock);
      break;
    case AZ_BAD_SPIKED_VINE:
      az_draw_bad_spiked_vine(baddie, frozen, clock);
      break;
    case AZ_BAD_MAGBEEST_HEAD:
      az_draw_bad_magbeest_head(baddie, clock);
      break;
    case AZ_BAD_MAGBEEST_LEGS_L:
      az_draw_bad_magbeest_legs_l(baddie, clock);
      break;
    case AZ_BAD_MAGBEEST_LEGS_R:
      az_draw_bad_magbeest_legs_r(baddie, clock);
      break;
    case AZ_BAD_MAGMA_BOMB:
      az_draw_bad_magma_bomb(baddie, clock);
      break;
    case AZ_BAD_OTH_BRAWLER:
      az_draw_bad_oth_brawler(baddie, frozen, clock);
      break;
    case AZ_BAD_LARGE_FISH:
      az_draw_bad_large_fish(baddie, frozen, clock);
      break;
    case AZ_BAD_CRAB_CRAWLER:
      az_draw_bad_crab_crawler(baddie, frozen, clock);
      break;
    case AZ_BAD_SCRAP_METAL:
      az_draw_bad_scrap_metal(baddie);
      break;
    case AZ_BAD_RED_ATOM:
      az_draw_bad_red_atom(baddie, frozen, clock);
      break;
    case AZ_BAD_REFLECTION:
      az_draw_bad_reflection(baddie, clock);
      break;
    case AZ_BAD_OTH_MINICRAB:
      az_draw_bad_oth_minicrab(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_RAZOR_2:
      az_draw_bad_oth_razor_2(baddie, frozen, clock);
      break;
    case AZ_BAD_OTH_SUPERGUNSHIP:
    case AZ_BAD_OTH_DECOY:
      az_draw_bad_oth_supergunship(baddie, frozen, clock);
      break;
    case AZ_BAD_CENTRAL_NETWORK_NODE:
      az_draw_bad_central_network_node(baddie, clock);
      break;
    case AZ_BAD_OTH_TENTACLE:
      az_draw_bad_oth_tentacle(baddie, frozen, clock);
      break;
  }
}
Example #5
0
void az_draw_particle(const az_particle_t *particle, az_clock_t clock) {
  assert(particle->kind != AZ_PAR_NOTHING);
  assert(particle->age <= particle->lifetime);
  switch (particle->kind) {
    case AZ_PAR_NOTHING: AZ_ASSERT_UNREACHABLE();
    case AZ_PAR_BOOM:
      glBegin(GL_TRIANGLE_FAN); {
        with_color_alpha(particle->color, 0);
        glVertex2d(0, 0);
        const double ratio = particle->age / particle->lifetime;
        with_color_alpha(particle->color, 1 - ratio * ratio);
        const double radius = particle->param1 * ratio;
        for (int i = 0; i <= 16; ++i) {
          glVertex2d(radius * cos(i * AZ_PI_EIGHTHS),
                     radius * sin(i * AZ_PI_EIGHTHS));
        }
      } glEnd();
      break;
    case AZ_PAR_BEAM: {
      const double alpha = (particle->lifetime <= 0.0 ? 1.0 :
                            1.0 - particle->age / particle->lifetime);
      glBegin(GL_QUAD_STRIP); {
        with_color_alpha(particle->color, 0);
        glVertex2d(0, particle->param2);
        glVertex2d(particle->param1, particle->param2);
        with_color_alpha(particle->color, alpha);
        glVertex2d(0, 0);
        glVertex2d(particle->param1, 0);
        with_color_alpha(particle->color, 0);
        glVertex2d(0, -particle->param2);
        glVertex2d(particle->param1, -particle->param2);
      } glEnd();
      glBegin(GL_TRIANGLE_FAN); {
        with_color_alpha(particle->color, alpha);
        glVertex2d(particle->param1, 0);
        with_color_alpha(particle->color, 0);
        for (int i = -90; i <= 90; i += 30) {
          glVertex2d(particle->param1 +
                     particle->param2 * cos(AZ_DEG2RAD(i)) * 0.75,
                     particle->param2 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
    } break;
    case AZ_PAR_CHARGED_BOOM: {
      const double factor = particle->age / particle->lifetime;
      const double major = sqrt(factor) * particle->param1;
      const double minor = (1 - factor) * particle->param2;
      const double alpha = 1 - factor;
      glBegin(GL_QUAD_STRIP); {
        const double outer = major + minor;
        for (int i = 0; i <= 360; i += 20) {
          with_color_alpha(particle->color, 0);
          glVertex2d(outer * cos(AZ_DEG2RAD(i)), outer * sin(AZ_DEG2RAD(i)));
          with_color_alpha(particle->color, alpha);
          glVertex2d(major * cos(AZ_DEG2RAD(i)), major * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      glBegin(GL_QUAD_STRIP); {
        const double inner = fmax(0, major - minor);
        const double beta = alpha * (1 - fmin(major, minor) / minor);
        for (int i = 0; i <= 360; i += 20) {
          with_color_alpha(particle->color, alpha);
          glVertex2d(major * cos(AZ_DEG2RAD(i)), major * sin(AZ_DEG2RAD(i)));
          with_color_alpha(particle->color, beta);
          glVertex2d(inner * cos(AZ_DEG2RAD(i)), inner * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
    } break;
    case AZ_PAR_EMBER:
      glBegin(GL_TRIANGLE_FAN); {
        with_color_alpha(particle->color, 1);
        glVertex2f(0, 0);
        with_color_alpha(particle->color, 0);
        const double radius =
          particle->param1 * (1.0 - particle->age / particle->lifetime);
        for (int i = 0; i <= 360; i += 30) {
          glVertex2d(radius * cos(AZ_DEG2RAD(i)), radius * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      break;
    case AZ_PAR_EXPLOSION:
      glBegin(GL_QUAD_STRIP); {
        const double tt = 1.0 - particle->age / particle->lifetime;
        const double inner_alpha = tt * tt;
        const double outer_alpha = tt;
        const double inner_radius = particle->param1 * (1.0 - tt * tt * tt);
        const double outer_radius = particle->param1;
        for (int i = 0; i <= 360; i += 6) {
          const double c = cos(AZ_DEG2RAD(i)), s = sin(AZ_DEG2RAD(i));
          with_color_alpha(particle->color, inner_alpha);
          glVertex2d(inner_radius * c, inner_radius * s);
          with_color_alpha(particle->color, outer_alpha);
          glVertex2d(outer_radius * c, outer_radius * s);
        }
      } glEnd();
      break;
    case AZ_PAR_FIRE_BOOM: {
      const int i_step = 10;
      const double liveness = 1.0 - particle->age / particle->lifetime;
      const double x_radius = particle->param1;
      const double y_radius = particle->param1 * liveness;
      for (int i = 0; i < 180; i += i_step) {
        glBegin(GL_TRIANGLE_STRIP); {
          const int limit = 180 * liveness;
          for (int j = 0; j < limit; j += 20) {
            glColor4f(1.0, 0.75 * j / limit, 0.0,
                      0.35 + 0.25 * sin(AZ_DEG2RAD(i)) * sin(AZ_DEG2RAD(j)) -
                      0.35 * j / limit);
            const double x = x_radius * cos(AZ_DEG2RAD(j));
            glVertex2d(x, y_radius * cos(AZ_DEG2RAD(i)) *
                       sin(AZ_DEG2RAD(j)));
            glVertex2d(x, y_radius * cos(AZ_DEG2RAD(i + i_step)) *
                       sin(AZ_DEG2RAD(j)));
          }
          glVertex2d(x_radius * cos(AZ_DEG2RAD(limit)),
                     y_radius * cos(AZ_DEG2RAD(i + i_step/2)) *
                     sin(AZ_DEG2RAD(limit)));
        } glEnd();
      }
    } break;
    case AZ_PAR_ICE_BOOM: {
      const double t0 = particle->age / particle->lifetime;
      const double t1 = 1.0 - t0;
      glBegin(GL_TRIANGLE_FAN); {
        with_color_alpha(particle->color, 0);
        glVertex2f(0, 0);
        with_color_alpha(particle->color, t1 * t1 * t1);
        for (int i = 0; i <= 360; i += 6) {
          glVertex2d(particle->param1 * cos(AZ_DEG2RAD(i)),
                     particle->param1 * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
      glPushMatrix(); {
        const double rx = 0.65 * particle->param1;
        const double ry = sqrt(3.0) * rx / 3.0;
        const double cx = fmin(1, 4 * t0) * rx;
        for (int i = 0; i < 6; ++i) {
          glBegin(GL_TRIANGLE_FAN); {
            with_color_alpha(particle->color, t1);
            glVertex2d(cx, 0);
            with_color_alpha(particle->color, t1 * t1);
            glVertex2d(cx + rx, 0); glVertex2d(cx,  ry);
            glVertex2d(cx - rx, 0); glVertex2d(cx, -ry);
            glVertex2d(cx + rx, 0);
          } glEnd();
          glRotatef(60, 0, 0, 1);
        }
      } glPopMatrix();
    } break;
    case AZ_PAR_LIGHTNING_BOLT:
      if (particle->age >= particle->param2) {
        const int num_steps = az_imax(2, round(particle->param1 / 10.0));
        const double step = particle->param1 / num_steps;
        az_random_seed_t seed = { clock / 5, 194821.0 * particle->angle };
        az_vector_t prev = {0, 0};
        for (int i = 1; i <= num_steps; ++i) {
          const az_vector_t next =
            (i == num_steps ? (az_vector_t){particle->param1, 0} :
             (az_vector_t){3.0 * az_rand_sdouble(&seed) + i * step,
                           10.0 * az_rand_sdouble(&seed)});
          const az_vector_t side =
            az_vwithlen(az_vrot90ccw(az_vsub(next, prev)), 4);
          glBegin(GL_TRIANGLE_STRIP); {
            with_color_alpha(particle->color, 0);
            az_gl_vertex(az_vadd(prev, side));
            az_gl_vertex(az_vadd(next, side));
            glColor4f(1, 1, 1, 0.5);
            az_gl_vertex(prev); az_gl_vertex(next);
            with_color_alpha(particle->color, 0);
            az_gl_vertex(az_vsub(prev, side));
            az_gl_vertex(az_vsub(next, side));
          } glEnd();
          prev = next;
        }
        draw_bolt_glowball(particle->color, particle->param1, clock);
      }
      draw_bolt_glowball(particle->color, 0, clock);
      break;
    case AZ_PAR_OTH_FRAGMENT:
      glRotated(particle->age * AZ_RAD2DEG(particle->param2), 0, 0, 1);
      glBegin(GL_TRIANGLES); {
        const double radius =
          (particle->param1 >= 0.0 ?
           particle->param1 * (1.0 - particle->age / particle->lifetime) :
           -particle->param1 * (particle->age / particle->lifetime));
        const az_color_t color = particle->color;
        for (int i = 0; i < 3; ++i) {
          const az_clock_t clk = clock + 2 * i;
          glColor4ub((az_clock_mod(6, 1, clk)     < 3 ? color.r : color.r / 4),
                     (az_clock_mod(6, 1, clk + 2) < 3 ? color.g : color.g / 4),
                     (az_clock_mod(6, 1, clk + 4) < 3 ? color.b : color.b / 4),
                     color.a);
          glVertex2d(radius * cos(AZ_DEG2RAD(i * 120)),
                     radius * sin(AZ_DEG2RAD(i * 120)));
        }
      } glEnd();
      break;
    case AZ_PAR_NPS_PORTAL: {
      const double progress = particle->age / particle->lifetime;
      const double scale = 1 - 2 * fabs(progress - 0.5);
      const double tscale = fmax(0, 1 - pow(2.25 * progress - 1.25, 2));
      // Tendrils:
      for (int i = 0; i < 10; ++i) {
        const double theta = AZ_DEG2RAD(i * 36);
        const az_vector_t tip =
          az_vadd(az_vpolar(1.1 * particle->param1 * tscale, theta),
                  az_vpolar(15 * tscale,
                            particle->age * AZ_DEG2RAD(180) * ((i % 3) + 1)));
        const az_vector_t ctrl1 =
          az_vadd(az_vpolar(0.8 * particle->param1 * tscale, theta),
                  az_vpolar(10 * sin(particle->age * AZ_DEG2RAD(400)),
                            theta + AZ_HALF_PI));
        const az_vector_t ctrl2 =
          az_vadd(az_vpolar(0.4 * particle->param1 * tscale, theta),
                  az_vpolar(10 * cos(particle->age * AZ_DEG2RAD(400)),
                            theta + AZ_HALF_PI));
        az_draw_oth_tendril(AZ_VZERO, ctrl1, ctrl2, tip, 5 * tscale,
                            1.0f, clock);
      }
      // Portal:
      glBegin(GL_TRIANGLE_FAN); {
        const GLfloat r = (az_clock_mod(6, 1, clock)     < 3 ? 1.0f : 0.25f);
        const GLfloat g = (az_clock_mod(6, 1, clock + 2) < 3 ? 1.0f : 0.25f);
        const GLfloat b = (az_clock_mod(6, 1, clock + 4) < 3 ? 1.0f : 0.75f);
        glColor4f(r, g, b, 1.0f);
        glVertex2f(0, 0);
        glColor4f(r, g, b, 0.15f);
        const double radius = particle->param1 * scale;
        for (int i = 0; i <= 360; i += 10) {
          glVertex2d(radius * cos(AZ_DEG2RAD(i)), radius * sin(AZ_DEG2RAD(i)));
        }
      } glEnd();
    } break;
    case AZ_PAR_ROCK:
      glScaled(particle->param1, particle->param1, 1);
      glRotated(particle->age * AZ_RAD2DEG(particle->param2), 0, 0, 1);
      glBegin(GL_TRIANGLE_FAN); {
        const double progress = particle->age / particle->lifetime;
        const az_color_t black = {0, 0, 0, 255};
        az_gl_color(az_transition_color(particle->color, black, progress));
        glVertex2f(0, 0);
        az_gl_color(az_transition_color(particle->color, black,
                                        0.7 + 0.3 * progress));
        glVertex2f(4, 0); glVertex2f(1, 4); glVertex2f(-1, 5);
        glVertex2f(-2, 0); glVertex2f(-1, -2); glVertex2f(1, -3);
        glVertex2f(4, 0);
      } glEnd();
      break;
    case AZ_PAR_SHARD:
      glScaled(particle->param1, particle->param1, 1);
      glRotated(particle->age * AZ_RAD2DEG(particle->param2), 0, 0, 1);
      glBegin(GL_TRIANGLES); {
        az_color_t color = particle->color;
        const double alpha = 1.0 - particle->age / particle->lifetime;
        with_color_alpha(color, alpha);
        glVertex2f(2, 3);
        color.r *= 0.6; color.g *= 0.6; color.b *= 0.6;
        with_color_alpha(color, alpha);
        glVertex2f(-2, 4);
        color.r *= 0.6; color.g *= 0.6; color.b *= 0.6;
        with_color_alpha(color, alpha);
        glVertex2f(0, -4);
      } glEnd();
      break;
    case AZ_PAR_SPARK:
      glBegin(GL_TRIANGLE_FAN); {
        glColor4f(1, 1, 1, 0.8);
        glVertex2f(0, 0);
        with_color_alpha(particle->color, 0);
        const double radius =
          particle->param1 * (1.0 - particle->age / particle->lifetime);
        const double theta_offset = particle->param2 * particle->age;
        for (int i = 0; i <= 360; i += 45) {
          const double rho = (i % 2 ? 1.0 : 0.5) * radius;
          const double theta = AZ_DEG2RAD(i) + theta_offset;
          glVertex2d(rho * cos(theta), rho * sin(theta));
        }
      } glEnd();
      break;
    case AZ_PAR_SPLOOSH:
      glBegin(GL_TRIANGLE_FAN); {
        with_color_alpha(particle->color, 1);
        glVertex2f(0, 0);
        with_color_alpha(particle->color, 0);
        const GLfloat height =
          particle->param1 * sin(AZ_PI * particle->age / particle->lifetime);
        const GLfloat semiwidth = particle->param2;
        glVertex2f(0, semiwidth);
        glVertex2f(0.3f * height, 0.5f * semiwidth);
        glVertex2f(height, 0);
        glVertex2f(0.3f * height, -0.5f * semiwidth);
        glVertex2f(0, -semiwidth);
        glVertex2f(-0.05f * height, 0);
        glVertex2f(0, semiwidth);
      } glEnd();
      break;
    case AZ_PAR_TRAIL: {
      const double scale = 1.0 - particle->age / particle->lifetime;
      const double alpha = scale * scale * scale;
      const double semiwidth = alpha * particle->param2;
      glBegin(GL_TRIANGLE_STRIP); {
        with_color_alpha(particle->color, 0);
        glVertex2d(0, semiwidth);
        glVertex2d(particle->param1, semiwidth);
        with_color_alpha(particle->color, alpha);
        glVertex2d(0, 0);
        glVertex2d(particle->param1, 0);
        with_color_alpha(particle->color, 0);
        glVertex2d(0, -semiwidth);
        glVertex2d(particle->param1, -semiwidth);
      } glEnd();
    } break;
  }
}
Example #6
0
int main(int argc, char **argv) {
  az_init_sound_datas();
  az_init_baddie_datas();
  az_init_wall_datas();
  az_register_gl_init_func(az_init_portrait_drawing);
  az_register_gl_init_func(az_init_wall_drawing);

  if (!load_scenario()) {
    printf("Failed to load scenario.\n");
    return EXIT_FAILURE;
  }
  az_load_preferences(&preferences);
  az_load_saved_games(&planet, &saved_games);
  az_init_gui(preferences.fullscreen_on_startup, true);
  az_set_global_music_volume(preferences.music_volume);
  az_set_global_sound_volume(preferences.sound_volume);

  az_controller_t controller = AZ_CONTROLLER_TITLE;
  az_title_intro_t title_intro = AZ_TI_SHOW_INTRO;
  int saved_game_slot_index = 0;
  while (true) {
    switch (controller) {
      case AZ_CONTROLLER_TITLE:
        {
          const az_title_action_t action =
            az_title_event_loop(&planet, &saved_games, &preferences,
                                title_intro);
          switch (action.kind) {
            case AZ_TA_QUIT:
              return EXIT_SUCCESS;
            case AZ_TA_START_GAME:
              controller = AZ_CONTROLLER_SPACE;
              saved_game_slot_index = action.slot_index;
              break;
          }
        }
        break;
      case AZ_CONTROLLER_SPACE:
        switch (az_space_event_loop(&planet, &saved_games, &preferences,
                                    saved_game_slot_index)) {
          case AZ_SA_EXIT_TO_TITLE:
            controller = AZ_CONTROLLER_TITLE;
            title_intro = AZ_TI_SKIP_INTRO;
            break;
          case AZ_SA_GAME_OVER:
            controller = AZ_CONTROLLER_GAME_OVER;
            break;
          case AZ_SA_VICTORY:
            controller = AZ_CONTROLLER_TITLE;
            title_intro = AZ_TI_PLANET_DEBRIS;
            break;
        }
        break;
      case AZ_CONTROLLER_GAME_OVER:
        switch (az_gameover_event_loop()) {
          case AZ_GOA_TRY_AGAIN:
            controller = AZ_CONTROLLER_SPACE;
            break;
          case AZ_GOA_RETURN_TO_TITLE:
            controller = AZ_CONTROLLER_TITLE;
            title_intro = AZ_TI_SKIP_INTRO;
            break;
          case AZ_GOA_QUIT:
            return EXIT_SUCCESS;
        }
        break;
    }
  }
  AZ_ASSERT_UNREACHABLE();
}