Goto https://www.stucuk.netGoto https://www.atlanticaonlinewiki.comGoto https://www.game-requirements.com


Menu


It is currently Wed Dec 12, 2018 1:26 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Double Laser Attack
PostPosted: Sun Feb 11, 2018 3:45 pm 
Offline
Soldier level 0
Soldier level 0

Joined: Wed Jun 18, 2014 6:59 pm
Posts: 42
Here's a function that is meant to work like ComAttackunit, but for a double laser to use their special attack.

LaserList - List of double laser units.
AllTargets - List of enemies.
Area - optional, double lasers will not go in that area. Could be of use because there's no other control of the lasers movements.
val - Defines preferred distance. At 0 they will surround the target as tightly as possible, 1 is middle distance (most reasonable), at 2 they will spread out as much as possible (may have trouble hitting human units).

The function automatically pairs up the lasers and assigns them to separate targets.

Note that it should be used continuously, unlike normal command function.

Code:
Function DoubleLaserAttack(LaserList, AllTargets, Area, val);
var Lasers, LaserGroups, L1, L2, Target, temp_target_list, TargetX, TargetY;
var hex_list1, hex_list2, hex1, hex2, temp_hex, choosen_hexes, temp_list_x, temp_list_y, chosen_list;
var i, j, un, temp, temp_list, dist, dist1, dist2, common_hex;
var dir0_x, dir0_y, dir1_x, dir1_y, dir2_x, dir2_y, dir3_x, dir3_y, dir4_x, dir4_y, dir5_x, dir5_y, dir6_x, dir6_y, dir7_x, dir7_y, dir8_x, dir8_y, dir9_x, dir9_y, dir10_x, dir10_y, dir11_x, dir11_y;
begin
     if AllTargets <= 0 then
        exit;

     temp_list = UnitFilter(LaserList, [f_not,[f_weapon,us_double_laser]]);

     if temp_list > 0 then                         
        ComAttackUnit(temp_list, AllTargets[1]);   //Non double-laser units in the LaserList will just get the command to attack

     Lasers = UnitFilter(LaserList, [f_weapon,us_double_laser]);

     if Lasers < 2 then
     begin                                         
          ComAttackUnit(Lasers, AllTargets[1]);    //Same for a single laser
          exit;
     end
     else
         begin
              LaserGroups = [];

              //Pair up the lasers. If there's one left it will just do the same as laser2 in the last pair
              while Lasers > 1 do
              begin
                   temp = [Lasers[1], Lasers[2]];
                   Lasers = Lasers diff temp;

                   if Lasers = 1 then
                      temp = temp ^ Lasers[1];

                   LaserGroups = LaserGroups ^ [temp];
              end;
         end;

     if val < 0 then
        val = 0;

     if val > 2 then
        val = 2;


     //For any given target (T), assume a set of relative hexes forming circles around it. There are 7 hexes going away from the target (2 hexes appart from each other) in 12 different directions
     //Dir0 here is the same as direction 0 in editor, Dir1 is between directions 0 and 1 in editor, Dir2 corresponds to direction 1 in editor and so on
     // *  *  *  *  *
     //   * * * * *
     //     *****
     // * * * T * * *
     //     *****
     //   * * * * *
     // *  *  *  *  *

     //Below are the coordinates relative to the target hex
     Dir0_X = [0, 0, 0, 0, 0, 0, 0];    Dir0_Y = [-3, -5, -7, -9, -11, -13, -15]; Dir1_X = [2, 3, 4, 5, 6, 7, 8];     Dir1_Y = [-2, -3, -4, -5, -6, -7, -8];
     Dir2_X = [3, 5, 7, 9, 11, 13, 15]; Dir2_Y = [0, 0, 0, 0, 0, 0, 0];           Dir3_X = [4, 6, 8, 10, 12, 14, 16]; Dir3_Y = [2, 3, 4, 5, 6, 7, 8];
     Dir4_X = [4, 5, 7, 9, 11, 13, 15]; Dir4_Y = [4, 5, 7, 9, 11, 13, 15];        Dir5_X = [2, 3, 4, 5, 6, 7, 8];     Dir5_Y = [4, 6, 8, 10, 12, 14, 16];
     Dir6_X = [0, 0, 0, 0, 0, 0, 0];    Dir6_Y = [3, 5, 7, 9, 11, 13, 15];        Dir7_X = [-2, -3, -4, -5, -6, -7, -8]; Dir7_Y = [2, 3, 4, 5, 6, 7, 8];
     Dir8_X = [-3, -5, -7, -9, -11, -13, -15]; Dir8_Y = [0, 0, 0, 0, 0, 0, 0];    Dir9_X = [-4, -6, -8, -10, -12, -14, -16]; Dir9_Y = [-2, -3, -4, -5, -6, -7, -8];
     Dir10_X = [-3, -5, -7, -9, -11, -13, -15]; Dir10_Y = [-3, -5, -7, -9, -11, -13, -15]; Dir11_X = [-2, -3, -4, -5, -6, -7, -8]; Dir11_Y = [-4, -6, -8, -10, -12, -14, -16];

     temp_list_x = [dir0_x, dir1_x, dir2_x, dir3_x, dir4_x, dir5_x, dir6_x, dir7_x, dir8_x, dir9_x, dir10_x, dir11_x];
     temp_list_y = [dir0_y, dir1_y, dir2_y, dir3_y, dir4_y, dir5_y, dir6_y, dir7_y, dir8_y, dir9_y, dir10_y, dir11_y];

     temp_target_list = 0;

     for un in LaserGroups do
     begin
          common_hex = [(GetX(un[1]) + GetX(un[2]))/2, (GetY(un[1]) + GetY(un[2]))/2];
          temp_list = [];

          if temp_target_list = 0 then
             temp_target_list = AllTargets;

          dist = 999;

          //Pick the closest target for a given pair.
          for i in temp_target_list do
          begin
               dist1 = GetDistUnits(i, un[1]);
               dist2 = GetDistUnits(i, un[2]);

               if dist1 > dist2 then
                  temp = dist1
               else temp = dist2;

               //A small threshhold (+3 here) is necessary to prevent them from switching to another target as soon as they move slightly toward one
               if temp + 3 < dist then
               begin
                    dist = temp;
                    Target = i;
               end;
          end;

          temp_target_list = temp_target_list diff Target;

          TargetX = GetX(Target);
          TargetY = GetY(Target);

          hex_list1 = [];
          hex_list2 = [];


          //Pick the first available hex from each direction, to form a single circle around the target
          //Check them in pairs - if a given direction doesn't have a single hex available, then the opposite of it is also disregerded
          for i = 1 to 6 do
          begin
               hex1 = [];
               hex2 = [];

               hex_list1 = hex_list1 ^ [hex1];
               hex_list2 = hex_list2 ^ [hex2];

               //Prioritize the closest, middle distance or the farthest hexes, as chosen on the top
               case val of
                    0: temp_list = [1,2,3,4,5,6,7];
                    1: temp_list = [4,5,3,6,2,7,1];
                    else
                        temp_list = [7,6,5,4,3,2,1];
               end;

               //Available hex is: A valid empty hex, not in the forbidden area, not a red slope or a terrain of: don't enter, don't enter water, don't enter rock
               for j in temp_list do
               begin
                    temp_hex = [TargetX + temp_list_x[i][j], TargetY + temp_list_y[i][j]];

                    if not ValidHex(temp_hex[1], temp_hex[2]) or ( HexInfo(temp_hex[1], temp_hex[2]) > 0 and not HexInfo(temp_hex[1], temp_hex[2]) in un ) then
                       continue;

                    if Area > 0 then
                       if InArea(temp_hex[1], temp_hex[2], Area) then
                          continue;

                    if GetHexInfo(temp_hex[1], temp_hex[2])[3] in [40,41,42,43,44,45,48,49,50,51,52,53] or GetHexInfo(temp_hex[1], temp_hex[2])[6] in [3,4,6] then
                       continue;

                    hex1 = temp_hex; //Hex picked
                    break;
               end;

               if hex1 = [] then
                  continue;

               //Repeat the same process for the opposite direction
               for j in temp_list do
               begin
                    temp_hex = [TargetX + temp_list_x[i+6][j], TargetY + temp_list_y[i+6][j]];

                    if not ValidHex(temp_hex[1], temp_hex[2]) or ( HexInfo(temp_hex[1], temp_hex[2]) > 0 and not HexInfo(temp_hex[1], temp_hex[2]) in un ) then
                       continue;

                    if Area > 0 then
                       if InArea(temp_hex[1], temp_hex[2], Area) then
                          continue;

                    if GetHexInfo(temp_hex[1], temp_hex[2])[3] in [40,41,42,43,44,45,48,49,50,51,52,53] or GetHexInfo(temp_hex[1], temp_hex[2])[6] in [3,4,6] then
                       continue;

                    hex2 = temp_hex;
                    break;
               end;

               if hex2 = [] then
                  continue;

               //These two sets compose a single circle of hexes around the target
               hex_list1 = Replace(hex_list1, i, hex1);
               hex_list2 = Replace(hex_list2, i, hex2);
          end;

          //If no available hexes found at all (unlikely), simply move toward the target and hope for the best
          if (hex_list1 diff 0) = 0 then
          begin
               ComMoveUnit(un, Target);
               exit;
          end;

          //Two sets of the same hexes (just opposite order) for convenience. One for each laser.
          hex_list1 = hex_list1 ^ hex_list2;
          hex_list2 = hex_list2 ^ hex_list1;

          temp_list = [];
          j = [1,2,3,4,5,6,7,8,9,10,11,12];


          //Select the closest pair of hexes to the lasers, from the determined circle
          //So later on the distances from all other hexes can be measured in correct order
          for i in j do
              temp_list = temp_list ^ GetDistXY(common_hex[1],common_hex[2], TargetX + temp_list_x[i][5],TargetY + temp_list_y[i][5]);

          i = WorstFromListByList(j,temp_list);


          case i of
               1,7: temp_list = [4,5,6,1,2,3];
               2,8: temp_list = [5,6,1,2,3,4];
               3,9: temp_list = [6,1,2,3,4,5];
               4,10: temp_list = [1,2,3,4,5,6];
               5,11: temp_list = [2,3,4,5,6,1];
               6,12: temp_list = [3,4,5,6,1,2];
          end;

          dist = 999;


          //2 attack modes: 1- If any laser is away from it's hex, then move just toward that pair of hexes
          //                2- If both are already in place, move simultaneously to the next hexes in the circle. Staying on the move may help them dodge enemy missiles
          for i in temp_list do
          begin
               if hex_list1[i] = [] then
                  continue;

               hex1 = hex_list1[i];
               hex2 = hex_list2[i];

               //Try to assign a laser to its closer hex of the two
               if GetDistUnitXY(un[1], hex1[1], hex1[2]) < GetDistUnitXY(un[2], hex1[1], hex1[2]) + 3 then
               begin
                    L1 = un[1];
                    L2 = un[2];
               end
               else
               begin
                    L1 = un[2];
                    L2 = un[1];
               end;

               dist1 = GetDistUnitXY(L1, hex1[1], hex1[2]);
               dist2 = GetDistUnitXY(L2, hex2[1], hex2[2]);


               //Attack 2: select the next 3 hexes in the circle for the lasers, to keep them moving
               if dist1 < [3,4,6][val+1] and dist2 < [3,4,6][val+1] then
               begin
                    choosen_hexes = [];

                    for j = 1 to 3 do
                        if i + j > hex_list1 then
                           choosen_hexes = choosen_hexes ^ [hex_list1[i+j - hex_list1], hex_list2[i+j - hex_list1]]
                        else
                            choosen_hexes = choosen_hexes ^ [hex_list1[i+j], hex_list2[i+j]];
                    break;
               end;


               if dist1 > dist2 then
                  temp = dist1
               else
                   temp = dist2;

               //Attack 1: picking the closest pair of hexes
               if (temp + [6,8,10][val+1]) < dist then
               begin
                    dist = temp;
                    choosen_hexes = [hex1, hex2];
               end;
          end;

          //If there's an 0dd 1 out it will just do the same as laser2 in the pair
          if un > 2 then
             L2 = L2 ^ un[3];

          //If no available hexes found at all (unlikely), simply move toward the target and hope for the best
          if choosen_hexes[1] = [] then
          begin
               ComMoveUnit([L1,L2], Target);
               exit;
          end;


          //And finally, the command to move through all selected hexes
          ComMoveXY(L1, choosen_hexes[1][1],choosen_hexes[1][2]);
          ComMoveXY(L2, choosen_hexes[2][1],choosen_hexes[2][2]);

          if choosen_hexes > 2 then
             for i = 3 to choosen_hexes do
                 if choosen_hexes[i] > [] then
                    if i in [3,5] then
                       AddComMoveXY(L1, choosen_hexes[i][1],choosen_hexes[i][2])
                    else
                        AddComMoveXY(L2, choosen_hexes[i][1],choosen_hexes[i][2]);

     end;
end;   


Below is a small presentation, of a bit older version (it's just been tweaked a bit since then). In case of the simplest situations, the attack code was literally something like this:

Code:
every 0$1 do
begin
DoubleLaserAttack(BlueTeam, RedTeam, 0, 1);
enable;
end;




Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

Original War is an RTS / RPG game by Altar Games
Original War Support is not part of Altar Games but is maintaining Original War for Altar Games

Privacy Policy