not a beautiful or unique snowflake (nothings) wrote,
not a beautiful or unique snowflake

I just (re-)wrote an 80-line function, plus several smaller functions, all of which worked the first time. (The 80-line function had one syntax error, but the other code had several. So it didn't compile the first time, but it worked the first time it successfully compiled.)

static ObjID t_targets[MAX_AIS];

void update_turrets(float dt)
   int i,j;
   int num_targets;

   // zero all turret group regions
   for (j=1; j <= num_groups; ++j) {
      if (group[j].turret) {
         group[j].t_min.x = group[j].t_min.y =  100000.0;
         group[j].t_max.x = group[j].t_max.y = -100000.0;

   // for each turret, grow its turret-group's region
   for (i=0; i < num_ais; ++i) {
      if (!ais[i].active) continue;
      if (get_subtype(ais[i].obj) != S_TURRET) continue;
      int g = ais[i].group;
      vec3f loc;
      get_loc(ais[i].obj, &loc);
      float r = get_shot_speed(ais[i].obj) * get_shot_duration(ais[i].obj);
      if (loc.x-r < group[g].t_min.x) group[g].t_min.x = loc.x-r;
      if (loc.y-r < group[g].t_min.y) group[g].t_min.y = loc.y-r;
      if (loc.x+r > group[g].t_max.x) group[g].t_max.x = loc.x+r;
      if (loc.y+r > group[g].t_max.y) group[g].t_max.y = loc.y+r;

   // detect all objects which are in any turret group region
   num_targets = 0;
   t_targets[num_targets++] = pobj;  // @TODO: give player a dummy AI, remove this line
   for (i=0; i < num_ais; ++i) {
      if (!ais[i].active || ais[i].team > 1) continue; // @TODO: better test for neutrality
      for (j=1; j <= num_groups; ++j) {
         if (!group[j].turret) continue;
         if (ais[i].team != 1-group[j].team) continue;  // @TODO: better test for is-enemy
         vec3f loc;
         get_loc(ais[i].obj, &loc);
         if (loc.x >= group[j].t_min.x && loc.y >= group[j].t_min.y
           && loc.x <= group[j].t_max.x && loc.y <= group[j].t_max.y) {
            t_targets[num_targets++] = ais[i].obj;
            break; // exit j loop, do next i loop

   // now, iterate through all turrets, and look in t_targets
   // for candidate targets. t_targets should have very few entries--
   // five or six vehicles running around through turret fields; so
   // if we can afford the above num_ais * num_groups loop, we can
   // afford num_ais * num_targets

   for (i=0; i < num_ais; ++i) {
      if (!ais[i].active || get_subtype(ais[i].obj) != S_TURRET) continue;
      vec3f loc,loc2;
      get_loc(ais[i].obj, &loc);

      float r = get_shot_speed(ais[i].obj) * get_shot_duration(ais[i].obj);
      float best_d2 = r*r;
      ObjID best_t = OBJ_NULL;

      for (j=0; j < num_targets; ++j) {
         // don't bother with group range test (t_min/t_max)
         // since the radius test is faster
         get_loc(t_targets[j], &loc2);
         float d2 = vec3f_dist2(&loc, &loc2);
         if (d2 < best_d2) {
            best_d2 = d2;
            best_t  = t_targets[j];

      // stuff the AI state object with the best target, since
      // there's no easy way to communicate directly with the
      // turret-firing AI goal
      ais[i].state_obj = best_t;
Tags: programming
  • Post a new comment


    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.