

#process "defender"
class auto_att_fwd;
class auto_att_right;
class auto_att_back;
class auto_att_left;

core_static_quad, 0, 
  {object_pulse:auto_att_fwd, 0},
  {object_pulse:auto_att_right, 0},
  {object_pulse:auto_att_back, 0},
  {object_pulse:auto_att_left, 0},
#code




// Targetting information
// Targetting memory allows processes to track targets (enemy or friend)
// The following enums are used as indices in the process' targetting memory
enum
{
  TARGET_PARENT, // a newly built process starts with its builder as entry 0
  TARGET_FRONT, // target of directional forward attack
  TARGET_LEFT, // target of directional left attack
  TARGET_RIGHT, // target of directional right attack
  TARGET_BACK, // target of directional backwards attack
};

int attacking_front; // is set to 1 if forward directional attack objects have a target
int attacking_left; // is set to 1 if left directional attack objects have a target
int attacking_right; // is set to 1 if right directional attack objects have a target
int attacking_back; // is set to 1 if backwards directional attack objects have a target

int other_target_x, other_target_y;

// Variable declaration and initialisation
//  (note that declaration and initialisation cannot be combined)
//  (also, variables retain their values between execution cycles)
int core_x, core_y; // location of core
core_x = get_core_x(); // location is updated each cycle
core_y = get_core_y();
int angle; // direction process is pointing
 // angles are in integer degrees from 0 to 8192, with 0 being right,
 // 2048 down, 4096 left and 6144 up.
angle = get_core_angle(); // angle is updated each cycle

int scan_result; // used to hold the results of a scan of nearby processes


// All that this process does is sit around and wait until something comes near, then attack it.


  if (attacking_front == 1)
  {
    other_target_x = process[TARGET_FRONT].get_core_x();
    other_target_y = process[TARGET_FRONT].get_core_y();
    if (other_target_x >= 0 // checks target visibility (will be <0 if target not visible)
     && process[TARGET_FRONT].distance_less(1000) // checks distance from this process to target
     && arc_length(angle, atan2(other_target_y - core_y, other_target_x - core_x)) <= 2500)
    {
      auto_att_fwd.fire_at(TARGET_FRONT, 0);
    }
      else
        {
          attacking_front = 0;
        }
  }
    else
      {
        scan_result = scan_for_threat(cos(angle, 400), sin(angle, 400), TARGET_FRONT);
        if (scan_result == 1)
        {
          attacking_front = 1;
          auto_att_fwd.aim_at(TARGET_FRONT, 0); // just aim for now. wait until next cycle to fire
        }
          else
            auto_att_fwd.no_target(); // returns object to its default angle
      }

if (attacking_left == 1)
{
  other_target_x = process[TARGET_LEFT].get_core_x();
  other_target_y = process[TARGET_LEFT].get_core_y();
  if (other_target_x >= 0 // checks target visibility (will be <0 if target not visible)
   && process[TARGET_LEFT].distance_less(1000) // checks distance from this process to target
   && arc_length(angle - 2048, atan2(other_target_y - core_y, other_target_x - core_x)) <= 2500)
  {
    auto_att_left.fire_at(TARGET_LEFT, 0);
  }
    else
      {
        attacking_left = 0;
      }
}
  else
    {
      scan_result = scan_for_threat(cos(angle - 2048, 400), sin(angle - 2048, 400), TARGET_LEFT);
      if (scan_result == 1)
      {
        attacking_left = 1;
        auto_att_left.aim_at(TARGET_LEFT, 0); // just aim for now. wait until next cycle to fire
      }
        else
          auto_att_left.no_target(); // returns object to its default angle
    }

if (attacking_right == 1)
{
  other_target_x = process[TARGET_RIGHT].get_core_x();
  other_target_y = process[TARGET_RIGHT].get_core_y();
  if (other_target_x >= 0 // checks target visibility (will be <0 if target not visible)
   && process[TARGET_RIGHT].distance_less(1000) // checks distance from this process to target
   && arc_length(angle + 2048, atan2(other_target_y - core_y, other_target_x - core_x)) <= 2500)
  {
    auto_att_right.fire_at(TARGET_RIGHT, 0);
  }
    else
      {
        attacking_right = 0;
      }
}
  else
    {
      scan_result = scan_for_threat(cos(angle + 2048, 400), sin(angle + 2048, 400), TARGET_RIGHT);
      if (scan_result == 1)
      {
        attacking_right = 1;
        auto_att_right.aim_at(TARGET_RIGHT, 0); // just aim for now. wait until next cycle to fire
      }
        else
          auto_att_right.no_target(); // returns object to its default angle
    }

if (attacking_back == 1)
{
  other_target_x = process[TARGET_BACK].get_core_x();
  other_target_y = process[TARGET_BACK].get_core_y();
  if (other_target_x >= 0 // checks target visibility (will be <0 if target not visible)
   && process[TARGET_BACK].distance_less(1000) // checks distance from this process to target
   && arc_length(angle + 4096, atan2(other_target_y - core_y, other_target_x - core_x)) <= 2500)
  {
    auto_att_back.fire_at(TARGET_BACK, 0);
  }
    else
      {
        attacking_back = 0;
      }
}
  else
    {
      scan_result = scan_for_threat(cos(angle + 4096, 400), sin(angle + 4096, 400), TARGET_BACK);
      if (scan_result == 1)
      {
        attacking_back = 1;
        auto_att_back.aim_at(TARGET_BACK, 0); // just aim for now. wait until next cycle to fire
      }
        else
          auto_att_back.no_target(); // returns object to its default angle
    }
