Sail: Podwójny Laser

Wszelkie pytania na temat SAIL'a i modowania OW.
Post Reply
User avatar

Topic author
0dd1
ArCamp Developer
Posts: 220
Joined: Tue Jul 01, 2014 3:01 pm

Sail: Podwójny Laser

#1

Post by 0dd1 » Sat Aug 12, 2017 11:05 pm

Funkcja w założeniu ma działać jak ComAttackUnit dla podwójnych laserów. Jednak z racji na ich wyjątkowość musi być używana bez przerwy, przez cały czas trwania ataku. Dodatkowo zadziała na całą listę laserów i wrogów - funkcja sama dobiera lasery do celów.

Podanie Area przy użyciu funkcji jest opcjonalne - oznacza obszar do którego lasery mają NIE wchodzić, czyli niedostępne hexy jak strome zbocza albo głęboka woda. Nie da się tego określić z poziomu Saila, jedyny sposób to ręczne zaznaczenie wszystkich takich hexów na mapie.

Ostatnia wartość oznacza preferowaną odległość laserów od ich celu. Dozwolone wartości: 0 - lasery otaczają cel jak najciaśniej, 1 - pośrednia odległość (w większości przypadków najbardziej rozsądna), 2 - lasery będą rozstawiać się podczas ataku jak najszerzej.

Code: Select all

Function DoubleLaserAttack(Units, 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(Units, [f_not,[f_weapon,us_double_laser]]);

     if temp_list > 0 then
        ComAttackUnit(temp_list, AllTargets[1]);

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

     if Lasers < 2 then
     begin
          ComAttackUnit(Lasers, AllTargets[1]);
          exit;
     end
     else
         begin
              LaserGroups = [];

              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;

     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;

          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;

              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 = [];

          for i = 1 to 6 do
          begin
               hex1 = [];
               hex2 = [];

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

               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;

               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;

                    hex1 = temp_hex;
                    break;
               end;

               if hex1 = [] then
                  continue;

               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;

                    hex2 = temp_hex;
                    break;
               end;

               if hex2 = [] then
                  continue;

               hex_list1 = Replace(hex_list1, i, hex1);
               hex_list2 = Replace(hex_list2, i, hex2);
          end;


          if (hex_list1 diff 0) = 0 then
          begin
               ComMoveUnit(un, Target);
               exit;
          end;

          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];

          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;

          for i in temp_list do
          begin
               if hex_list1[i] = [] then
                  continue;

               hex1 = hex_list1[i];
               hex2 = hex_list2[i];
               L1 = un[1];
               L2 = un[2];

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

               if dist1 < [3,4,4][val+1] and dist2 < [3,4,4][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;


               if (temp + [6,8,10][val+1]) < dist then
               begin
                    dist = temp;
                    choosen_hexes = [hex1, hex2];
               end;
          end;

          if un > 2 then
             L2 = L2 ^ un[3];

          if choosen_hexes[1] = [] then
          begin
               ComMoveUnit([L1,L2], Target);
               exit;
          end;

          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;

Mała prezentacja (starszej wersji) poniżej. Kod ataku to dosłownie coś takiego:

Code: Select all

every 0$1 do
begin
DoubleLaserAttack(BlueTeam, RedTeam, area);
enable;
end;
Last edited by 0dd1 on Mon Aug 14, 2017 5:17 pm, edited 3 times in total.

User avatar

zoNE
The Great Uniter & Site Administrator
The Great Uniter & Site Administrator
Posts: 1119
Joined: Fri Feb 17, 2006 3:44 pm
Location: Poland
Contact:

Re: Sail: Podwójny Laser

#2

Post by zoNE » Sat Aug 12, 2017 11:38 pm

Fajne, fajne :P. Nie zaglebialem sie w kod, wiec nie sprawdzalem jak dokladnie dziala, ale tak patrzac na filmik, bym zrobil jeszcze 2ga, do ktorej bym dodal priorytety celow oraz skupianie sie na celach, bo tak, jak ComAttackUnit troszke sie gubia i dzialaja chaotycznie jedynie atakujac w drodze do celu :P. By mozna zrobic tak, by otaczaly konkretne wybrane cele priorytetowe w kodzie (wg waznosci celu) i na nich sie skupialy, by w drodze do okreslonego miejsca najpierw zniszczyc cele priorytetowe lub cele blokujace do nich dostep, a dopiero pozniej szly dalej. Moglaby z tego fajna funkcja wyjsc pod AI :).
Last edited by zoNE on Sat Aug 12, 2017 11:47 pm, edited 3 times in total.
PC MB: MSI Z97-G43 | CPU: Intel Xeon E3-1231v3 3.4GHz + Raijintek EreBoss | RAM: HyperX 2x8GB 1866MHz DDR3 CL9 | GPU: MSI GeForce GTX 970 100ME 4GB GDDR5 (256bit) | SSD: Crucial BX100 250GB | HDD: 4TB | LCD: EIZO FlexScan 22" S2243W Black | AUDIO: Asus Xonar D2 + KODA DRA-660 + KODA AV-701 + SW-550 v2 + Sennheiser HD 595 | OS: Windows 10 Pro
Laptop DELL Precision M6500 CPU: i5-520M RAM: 8GB DDR3 SSD: 128GB HDD: 500GB GPU: ATI FirePro M7740 1GB DDR5 OS: Windows 7 Ultimate 64-bit

User avatar

MarkedOne
Soldier level 5
Soldier level 5
Posts: 281
Joined: Wed Aug 17, 2011 12:36 pm
Location: Киев/Ольштын/Вроцлав

Re: Sail: Podwójny Laser

#3

Post by MarkedOne » Sun Aug 13, 2017 10:15 pm

Świetnie to wygląda, a wyglądałoby jeszcze lepiej z poprawkami, które napisał zoNE. :D
Gratulacje odd1
Завтра забудешь, что тебя короновал, что душу цветущую любовью выжег
И суетных дней взметенный карнавал растреплет страницы моих книжек
Слов моих сухие листья ли заставят остановиться, жадно дыша
Дай хоть последней нежностью выстелить твой уходящий шаг)

User avatar

Topic author
0dd1
ArCamp Developer
Posts: 220
Joined: Tue Jul 01, 2014 3:01 pm

Re: Sail: Podwójny Laser

#4

Post by 0dd1 » Mon Aug 14, 2017 5:45 pm

Lasery się gubią przy ataku bo wszystko jest w ciągłym ruchu, a nie ma prostego sposobu aby sprawdzić jak "dostępny" jest cel, poza porównywaniem odległości w prostej linii. Teraz to trochę usprawniłem i jest odrobinę stabilniej ale wciąż potrafią zachowywać się dziwnie.

Priorytety celów to raczej indywidualna kwestia, to trzeba dopasować do konkretnej sytuacji. Po to funkcja jest tak napisana żeby mogła poradzić sobie z każdą ilością jednostek, żeby można było samemu wybrać lasery i ich cele. Na przykład na filmiku widać jak atakują bazę z Am14. Tam specjalnie ustawiłem żeby najpierw atakowali wieżyczki, a dopiero potem inne jednostki. Dodatkowo funkcja celowo była użyta tylko na jednym celu naraz, aby lasery skupiły swój atak. Normalnie lepiej jest jak każda para ma osobny cel, ale tutaj miały utrudnione zadanie i w tym trybie o wiele szybciej by zostały zniszczone.

A co do samego AI, to już stworzyłem coś takiego w misji 13 Arabskiej Kampanii. Właściwie cała misja polega na tym że jednostki wroga spawnują się, jadą po wytyczonej ścieżce w górę mapy, i atakują jednostki gracza które zobaczą, a jak te zostaną zniszczone albo im uciekną, to jadą dalej. Teraz zastosowałem to samo w ostatniej misji, gdzie bazy wroga wysyłają co jakiś czas oddział na patrol po mapie, a funkcja ataku laserów powstała właśnie po to żeby AI mogło użyć podwójnych laserów przeciw graczowi.

User avatar

zoNE
The Great Uniter & Site Administrator
The Great Uniter & Site Administrator
Posts: 1119
Joined: Fri Feb 17, 2006 3:44 pm
Location: Poland
Contact:

Re: Sail: Podwójny Laser

#5

Post by zoNE » Mon Aug 14, 2017 6:29 pm

Ogolnie fajna funkcja, w grze czegos takiego wlasnie brakowalo - praktycznego wykorzystania DL przez komputer.
PC MB: MSI Z97-G43 | CPU: Intel Xeon E3-1231v3 3.4GHz + Raijintek EreBoss | RAM: HyperX 2x8GB 1866MHz DDR3 CL9 | GPU: MSI GeForce GTX 970 100ME 4GB GDDR5 (256bit) | SSD: Crucial BX100 250GB | HDD: 4TB | LCD: EIZO FlexScan 22" S2243W Black | AUDIO: Asus Xonar D2 + KODA DRA-660 + KODA AV-701 + SW-550 v2 + Sennheiser HD 595 | OS: Windows 10 Pro
Laptop DELL Precision M6500 CPU: i5-520M RAM: 8GB DDR3 SSD: 128GB HDD: 500GB GPU: ATI FirePro M7740 1GB DDR5 OS: Windows 7 Ultimate 64-bit

User avatar

Serpent
Soldier level 10
Soldier level 10
Posts: 3818
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: Sail: Podwójny Laser

#6

Post by Serpent » Wed Sep 20, 2017 8:24 am

Mała uwaga:
Podanie Area przy użyciu funkcji jest opcjonalne - oznacza obszar do którego lasery mają NIE wchodzić, czyli niedostępne hexy jak strome zbocza albo głęboka woda. Nie da się tego określić z poziomu Saila, jedyny sposób to ręczne zaznaczenie wszystkich takich hexów na mapie.
Ostatnio poprosiłem Stukacza który dodał funkcję sprawdzającą hex'a pod kątem jego właściwości. Myślę że można jej użyć w tym kodzie zamiast wyznaczać aree z góry :)
Epickie teksty:
Marek1906: jak zrobic aby sail był zielony?
Kvantovy: Wszystko normalne, wszystko w koło było dziwne
Kvantovy:: To jest fajne, że to nie jest takie głupie
Kvantovy:: remove sos from kanapeczka
Kvantovy:: zdarzają się rzezy które sie filozofom nie śniły

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest