Kod ataku.

Wszelkie pytania na temat SAIL'a i modowania OW.
Post Reply
User avatar
Night
Soldier level 4
Soldier level 4
Posts: 146
Joined: Sat Jun 26, 2010 10:06 am

Kod ataku.

Post by Night »

Po dłuższym czasie wzięło mnie znów na powrót do modowania, podpalałem swoje stare misje, poprzypominałem sobie co i jak i okazało się, że darowałem sobie, gdy po dłuższym czasie nie mogłem zrozumieć czemu moje perfekcyjne kody na atak nie działają. Załozyłem więc sobie wczoraj nowa czystą mapkę, postawiłem tylko budynki i ludzi am, oraz czołgi ru i zacząłem kombinować.

Teoria jest taka:

Jeżeli odległość agresorów ru, od ludzi am jest większa niż 8 to, agresorzy ru będą atakować nabliższy sobie budynek am, powtarzając atak do czasu, az wszystkie budynki nie padną, a następnie skierują się na ludzi, gdziekolwiek by oni nie byli, ale nie mogli już się schować czy stworzyć zabudowy blokującej czolgi.

Problem jednak w tym, że nie wiem jak rozdzielić sprawdzanie odległości pomiędzy każdą pozycją z jednej listy (ludzie am), z każda pozycją z drugiej listy (agresorzy ru).
Zamiast wklepywać cały kod, żacząłem po kolei sprawdzać, czy różne akcje będą się wykonywać i dopiero jak działała, dodawałem kolejną. Obecnie kod wygląda tak:

Code: Select all

Export czolgi, budynki, ludzie, odl;

Starting
begin
budynki=FilterAllUnits([[f_side, 1], [f_type, unit_building]]);
czolgi=FilterAllUnits([[f_side, 3], [f_type, unit_vehicle]]);
ludzie=FilterAllUnits([[f_side, 1], [f_type, unit_human]]);
end;

var veh;
var un;
var i;

Every 0$1 do

for veh in czolgi do
    for un in ludzie do // nie jestem pewien czy mozna tak po sobie, dwa for, ale wcześniej próbowałem róznież z jednym (tylko veh lub un oraz w połaczeniu poprzez "and".
    

begin
repeat
odl=GetDistunits(czolgi, ludzie); // *
if odl < 6 then                       // *
ComAttackUnit(veh, NearestUnitToUnit(budynki, veh));
wait(0$01);
until ludzie = 0
end;
Ten kod jest zbudowany, tylko tak, aby spradzał działanie jednej rzeczy, więc jeszcze nie ma dużego związku z tym co będzie ostatecznie.

*Zamiast, miałem wcześniej mnóstwo innych wariantów z przyjętymi var, długie rozpiski z nearest (podobne do tych z tematu o perfekcyjnym ataku), z [1], [un] i innymi, które to wklepywałem już na pałę "a może się uda". Dosłownie 4h siedziałem wczoraj nad tym i nic, przekopując polski spis funkcji saila i forum. Próbowałem też z see, ale tez nie szło.

Co bym jednak nie robił kod działał (jeśli działał) tylko dla jednego am i jednego ru.

Celowo nie chcę uzywać agresivemove.

Czy da się te listy rozdzielić?
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: Kod ataku.

Post by Serpent »

Wystarczyło napisać mi na pw :D

Pomogę ci wieczorem jak będę w domu.
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
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
Markok
Soldier level 6
Soldier level 6
Posts: 314
Joined: Thu Sep 04, 2014 12:53 am
Location: Oberschlesien
Contact:

Re: Kod ataku.

Post by Markok »

Zamiast sprawdzać odległość, realistyczniejszy i mniej skomplikowany może by był On Contact, czyli dopiero kiedy albo oni albo Ty ich zaatakujesz (czyli jak się będziecie widzieli) / albo area kiedy gdzieś wleziesz i w obu przypadkach ruszą do ataku, a do ataku przefiltrowałbym wszystkie unity z Twojej strony, więc ruscy paliliby i zabijali po kolei wszystko co im się by nawinęło pod lufy :amlaser2: , a nie jak według Ciebie rozwalili całą bazę i się do tego czasu patrzyli na Twoich ludzi strzelających do nich.. Niepotrzebnie komplikujesz i tylko odciągasz Serpa od SoSa :arhello:
User avatar
MrMentor
Soldier level 4
Soldier level 4
Posts: 80
Joined: Thu Aug 28, 2014 1:13 pm
Location: Poland

Re: Kod ataku.

Post by MrMentor »

Ogólnie rzecz biorąc algorytm wyglądałby tak:

Code: Select all

var czolgi; // lista czolgow
var ludzie; // list ludzi

var czolg; // zmienna pomocnicza do trzymania aktualnie sprawdzanego czolgu
var czlowiek; // zmienna do trzymania aktualnie sprawdzanego czlowieka

for czolg in czolgi do
    for czlowiek in ludzie do
        if odleglosc(czolg, czlowiek) < 6 then
            atakuj(czolg, czlowiek);
        else
            atakuj(czolg, najblizszy_budynek);

Żeby zapisać to w SAILu, musiałbym przysiąść do edytora.
User avatar
Night
Soldier level 4
Soldier level 4
Posts: 146
Joined: Sat Jun 26, 2010 10:06 am

Re: Kod ataku.

Post by Night »

Markok wrote:Zamiast sprawdzać odległość, realistyczniejszy i mniej skomplikowany może by był On Contact
Gracz może wcisnąć "x", aby nie atakować i cały kod się sypie :).
//edit, a atak agresora, będzie kontaktem, nawet jak zaatakuje pusty budynek.

Natomiast, area odpada, bo musiałbym przewidywać milion sytuacji, gdzie akurat dojdzie do walki, albo zablokować możliwość budowy w miejsach poza wyznaczonymi. Odpada.

Kwestia właśnie tego, że nie mają palić i mordować co się nawinie, a jak najszybciej zabić ludzi, stąd agresivemove odpada, bo jeżeli mogliby przejechać i dostać się to wtedy nawet ten atak na budynki nie pójdzie. Tak więc teoria, którą opisałem, jest tylko częścią jeszcze większego kodu ;).

a nie jak według Ciebie rozwalili całą bazę i się do tego czasu patrzyli na Twoich ludzi strzelających do nich
Jak pisałem, to co podałem, nie wiele ma wspólnego z ostatecznymi zamierzeniami, ma po prostu sprawdzać, czy kod się wykonuje poprawnie. Normalnie będzie tak, że jak odległość < od zasięgu to zaatakują ludzi, jak większa, to nie będą się ludźmi przejmować tylko budynkami, które będą stać im na drodze w dostępie do ludzi. Bo narazie jest właśnie tak, że co bym nie robił, to skupiają się na budynkach, lub od razu jadą do ludzi.

@MrMentor zdaje się, że od dokładnie takiego kodu zaczynałem (poza przystosowaniem go). Nie działało. Nie pamiętam już czy nie ruszało w ogóle, czy ciągle atakowało tylko budynki, chociaż najbardziej prawdopodobne, że ruszał tylko jeden czołg i reagował tylko na jednego człowieka.
User avatar
MrMentor
Soldier level 4
Soldier level 4
Posts: 80
Joined: Thu Aug 28, 2014 1:13 pm
Location: Poland

Re: Kod ataku.

Post by MrMentor »

IMHO musiałeś coś źle zakodować. Serpent ci szybciej podpowie co i jak, bo ja dziś nie mam niestety czasu.
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: Kod ataku.

Post by Serpent »

Założenia:
Night wrote: Jeżeli odległość agresorów ru, od ludzi am jest większa niż 8 to, agresorzy ru będą atakować nabliższy sobie budynek am, powtarzając atak do czasu, az wszystkie budynki nie padną, a następnie skierują się na ludzi, gdziekolwiek by oni nie byli, ale nie mogli już się schować czy stworzyć zabudowy blokującej czolgi.

Code: Select all

Every 0$01 trigger WARUNEK do // WARUNEK musisz sobie sam ustalić, ewentualnie zamienić every na funkcję
var i, filter, am;
begin
enable;

filter := ru; // agresorzy, wstawiasz tu tablice jednostek atakujących
am := FilterAllUnits([f_side, 1]); // am

      if am and filter then // jeżeli obie tablice nie są puste!
         begin
         for i = 1 to filter do
             if not HasTask(filter[i]) or WantsToAttack(filter[i]) > 0 then // jeżeli jednostki nie mają nic do roboty lub są celem ataku
                if GetDistUnits(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i])) < 8 then
                   ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]))
                else
                   ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_not, [f_type, unit_human]]), filter[i]));
         end;


End;
To prosty kod. Jeżeli chcesz możesz się pobawić w rejestrowanie tablic i pseudomakra - efekty na pewno będą lepsze ;)
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
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
User avatar
Night
Soldier level 4
Soldier level 4
Posts: 146
Joined: Sat Jun 26, 2010 10:06 am

Re: Kod ataku.

Post by Night »

Dzięki :D, działa pięknie. Może i prosty, ale w stosunku do tego co chciałem wykorzystać to już jazda zaawansowana. Dodatkowo, sporo jeszcze uproscił w dalszej obróbce. Teoretycznie, bo jeszcze jeden błąd wywala, gdy chcę go uzupełnić.

Code: Select all

Every 0$01 do
var i, filter, am;
begin
enable;

filter := FilterAllUnits([[f_side, 3], [f_type, unit_vehicle]]); 
am := FilterAllUnits([f_side, 1]); 

      if am and filter then 
       begin
         for i = 1 to filter do
Tu jest to co jest nowe:
Zaczynamy od sprawdzenia czy są jakieś jednostki poza ludźmi, jeżeli nie ma, to od razu jadą ubić ludzi, niezależnie od tego, jak daleko się znajdują. Nie będą więc stać bezczynie. I to działa perfekt. Ale trzeba dodać wcześniej jeszcze jedną rzecz (na samym dole).

Code: Select all

if UnitFilter(am, [f_not, [f_type, unit_human]]) < 1 then
                   ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]))
                 else

Code: Select all

             if not HasTask(filter[i]) or WantsToAttack(filter[i]) > 0 then // jeżeli jednostki nie mają nic do roboty lub są celem ataku
                if GetDistUnits(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i])) < 10 then
                   ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]))
                else
                   ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_not, [f_type, unit_human]]), filter[i])); 
                   

         end;


End;
Na zupełny początek trzeba dać warunek, że nawet jeśli są budynki, ale jest przejazd do ludzi to pojazdy pojadą zaatakować ludzi (i automaty, co by mogły w ogóle dojechać, ale to potem). Czyli rozkaz ataku na ludzi, a potem sprawdzenie, czy pojazdy pojechały wykonać czy zatrzymały się w miejscu, bo "cel jest nieosiągalny".

Code: Select all

         ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]));
         wait(0$1);
         if IsIdle(filter[i]) then

//i dalej działający kod

if UnitFilter(am, [f_not, [f_type, unit_human]]) < 1 then
                   ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]))
                 else
         
Jednak, po tych linijkach, przy zablokowanej drodze, pojawia się tak jak powinno "cel nieosiągalny" i zamiast potwierdzić bezczynność i wykonać dalszy kod to pojawia się błąd:

Code: Select all

Module:+Main
Line 30 (właśnie z tym idle)
Error: reading beyond end of list: 3 of [1,2),result set to 0, ignore further errors?!
Przy czym zamiast idle próbowałem również not isBusy i wg. linijki z Hastask, który jednak mógłby wciąż odbierać "wiszące" zadania saila, ale tak czy inaczeji efekt ten sam. Idle nie powinno chyba nic odbierać, więc powinno tu działać. Może kwestia godziny, ale kompletnie nie mogę zrozumieć skąd taki błąd, bo nawet jak kod sprowadziłem tylko do tego i zwykłego mova, gdyby były bezczynne to wywala ten sam błąd.

btw.
Jeśli kliknę yes przy błędzie, nic się nie dzieje, natomiast zonk jest, gdy kliknę "no", bo odpala nie wiadomo skąd, jedną z nut dodanych do moda, ale to tak ciekawostką :D.
User avatar
Night
Soldier level 4
Soldier level 4
Posts: 146
Joined: Sat Jun 26, 2010 10:06 am

Re: Kod ataku.

Post by Night »

Wciąż mi się wraca do tego kodu ataku. Obecnie wygląda tak i działa nieźle.

Code: Select all

Every 0$1 do
var i, filter, am, a, un;
begin
enable;

filter := FilterAllUnits([[f_side, 3], [f_type, unit_vehicle]]);
am := FilterAllUnits([f_side, 1]); // am
      if am and filter then 
         for i = 1 to filter do
         begin
         if UnitFilter(am, [f_not, [f_type, unit_human]]) < 1 then
            ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]))
                 else
                 for a = 1 to am do
                 if WantsToAttack(am[a]) > 0 or Attacks(filter[i]) then 
                  ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]))
                 else
                 ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_not, [f_type, unit_human]]), filter[i]));

         end;



End;
Ale mam dwa problemy. Nie mogę wykombinować, tak żeby się nie chromoliło, jak dodać, aby reagowali na atak z budynków. Ludzi i pojazdy atakują ładnie, ale jak wejdę do środka to już klops, zaczynają ponownie atakować najbliższy budynek.

I drugi problem, to taki, że poruszają się ruchem skokowym (wykonuje się kod jażdy do zaatakowania ludzi naprzemiennie z tym do ataku budynków). Gdy zmieniam kod i robię ruch płynny to z kolei nie chcą się ruszyć z miejsca jak droga zastawiona.
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: Kod ataku.

Post by Serpent »

2. Użyj HasTask.
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
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
User avatar
Night
Soldier level 4
Soldier level 4
Posts: 146
Joined: Sat Jun 26, 2010 10:06 am

Re: Kod ataku.

Post by Night »

Za chiny nie mogę tego przeskoczyć. Podobnie z HasTask, które mam wrażenie, że nawet nie działa. Na milion sposobów ten kod budowałem i nie mogę tego przeskoczyć.
User avatar
Night
Soldier level 4
Soldier level 4
Posts: 146
Joined: Sat Jun 26, 2010 10:06 am

Re: Kod ataku.

Post by Night »

Albo coś nie działa na nowych patchach albo nie wiem. Rozłożyłem na czynniki pierwsze kod, jak się dało i powoli po kolei sprawdzałem czy działa.

Code: Select all

Every 0$1 do
var i, filter, am, a, un;
begin
enable;

filter := FilterAllUnits([[f_side, 3], [f_type, unit_vehicle]]);
am := FilterAllUnits([f_side, 1]); // am
      if am and filter then
         for i = 1 to filter do
         begin
         ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]));
                 if not HasTask(filter[i]) then
                      RemoveTasks(filter[i]);
                      ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_not, [f_type, unit_human]]), filter[i]));
                        
        end;
end;
To sobie działa perfekt. Jak nie mogą dojechać do ludzi to jadą zniszczyć budynki. RemoveTasks niezbędne, bo inaczej jadą przerywanym.

Dalej dodaje:

Code: Select all

if WantsToAttack(filter[i]) then
                           RemoveTasks(filter[i]);
                             ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_type, unit_human]), filter[i]));
I w momencie gdy droga jest zablokowana. Nic się nie dzieje. A przecież ta cześć, nie powinna się włączać nawet jeśli nikt nie chce ich atakować.

Wypróbowałem więc, sam kod WantsToAttack, czy jeśli ktoś ich zaatakuje, to oleją i pojadą atakować budynki. Nic z tego. Agresora ubijają i stoją.

Code: Select all

Every 0$1 do
var i, filter, am, a, un;
begin
enable;

filter := FilterAllUnits([[f_side, 3], [f_type, unit_vehicle]]);
am := FilterAllUnits([f_side, 1]); // am
      if am and filter then
         for i = 1 to filter do
         begin
         if WantsToAttack(filter[i]) then
         ComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_not, [f_type, unit_human]]), filter[i]));
           
        end;
end;
Dla testów spróbowałem też z dodaniem:

Code: Select all

for i = 1 to filter do
         begin
         for a = 1 to am do
         begin
         if Attacks(am[a]) then // także if Attacks(am[a]) = filter[i] oraz if Attacks(am[a]) > 0
         AddComAttackUnit(filter[i], NearestUnitToUnit(UnitFilter(am, [f_not, [f_type, unit_human]]), filter[i]));
        end;
        end;
I tu działa. Jeśli am zaatakują to rus jadą atakować budynki.

Nie rozumiem, więc czy ja coś pomijam, czy ta komenda nie działa.

Sprawdziłem jeszcze, biorąc kod bezpośrednio z polskiego spisu funkcji saila:
if GetDistUnits(hunter,WantsToAttack(hunter)) < 13 then ComCrawl(hunter)
I także nie działało.
Post Reply