S příchodem Armed Assault přišlo i mnoho nových příkazů, které jsem se rozhodl lehce prozkoumat a napsat o nich něco málo. Zaměřil jsem se na ty, které považuji za zajímavé a pro obyčejného uživatele nejvíce využitelné. Půjde především o ty, které nějak pracují s chováním či nastavením AI a nebo s enginem obecně. Prvním příkazem, který si předvedeme je

findCover

kryt = salat findCover [getPos indian, getPos vokurka,100]; salat domove getpos kryt

Jak je vidět, tak findCover vrací objekt, kterým je místo, jenž by mělo
sloužit jako kryt. Toto místo se vypočítá na základě tří parametrů
předaných v poli. Prvním je pozice odkud má hledání začít, druhým je
pozice před kterým se má ukrýt a třetím je maximální vzdálenost ve
které se má hledat. V mém případě tedy například voják pojmenovaný
salat nedaleko indiana najde místo, kde bude ukrytý před pozicí nepřítele
(enemy) a to v maximální vzdálenosti 100 metrů od indiana. Nicméně dle
několika zkoušek bych na tuto funkci moc nespoléhal. Ne vždy mi daná pozice přišla jako ideální, ale jako obecná funkčnost v případě poplachu
může být obecně využita. Stejně tak je vhodné zkontrolovat, že vrácený
objekt není null.


findNearestEnemy

enemy = salat findNearestEnemy getpos salat;

Tímto příkazem najdeme nejbližšího nepřítele pro našeho dobře
známého saláta. Jen ale upozorním, že daný voják musí o nějakém
nepříteli vědět. Právě z nich totiž vybírá a tudíž vrácený
nepřítel nemusí nutně být opravdu tím nejbližším. Jen salát si to
myslí. Tento příkaz dle několika testů není nijak vzdálenostně
omezen.


enableAI

V OFP existoval příkaz disableAI, kterým bylo možné omezit, aby se AI
přestalo pohybovat, koukat, hledat cíl. Jenže tento proces byl nevratný.
Pomocí enableAI je možné AI tuto schopnost vrátit.

salat disableAI "move"
	~5
salat enableAI "move"

joinSilent

Nechcete aby se vám nové jednotky hlásily při přidání do skupiny
neustále přes rádio, že jsou připraveny? Tak právě vám je určen
příkaz joinSilent.

[vokurka, salat] joinSilent player

vám je přidá a ani si toho nevšimnete.


isNil

Možná si vzpomenete, jak se v OFP dříve složitě muselo zjišťovat,
zda je nějaká hodnota definována. Nyní je díky příkazu isNil vše
naprosto primitivní.

if (isNil "_test") then {_test = 0}

nearTargets

Dalším příkazem o kterém byste měli vědět a který je v Armed
Assault od verze 1.07 je příkaz nearTargets. Jde o příkaz, který vrátí pole obsahující další pole informací o známých nepřátelích zadané jednotky, které se nacházejí se v požadované vzdalenosti. Stejně jako u findnearestenemy je znovu nutné, aby o nich dotyčný vůbec věděl.

Příkaz lze velmi snadno použít především pro zjištění, zda voják
neví o nějakém nepříteli jako alternativa za findnearestenemy. A jelikož
vrácené pole obsahuje kromě daných objektů i další informace včetně
čísla udávajícího nebezpečnost (viz popis), pak lze přímo využít
i pro upřesnění nastavení chování daného vojáka.

Takže pro zjištění zda nějaký voják neví o nepříteli lze snadno použít

@count(vojak neartargets 3000)>0

Spawn

Dalším příkazem o kterém byste měli vědět, který přišel s první
verzí ArmA: Armed Assault je příkaz spawn. Tímto příkazem
můžete velmi snadno paralelně spouštět různé kódy aniž byste museli
čekat na jejich dokončení. Může se vám to zdát zbytečné a matoucí, ale
výsledek je přesně opačný. Pomocí tohoto příkazu můžete udržovat
funkčnost mise v jednom hlavním skriptu a samotné části kódu, které jste
předtím pouštěli paralelně ve více skriptech a které byly různě
nepřehledně provázané, je možné udržovat na jednom místě. Není tak
nutné kvůli každé hlouposti vytvářet a pouštět externí skripty a
editovat několik souborů.

Syntax příkazu je argumenty spawn skript

Nejlepší je asi uvést nějaký příklad.

Mějme jednoduchou misi, kde hráč dělá pozorovatele a musí vyrazit na
kopec odkud se má nahlásit a dle následného rozkazu hlídat údolí na jihu.
Ze severu pak vyráží nepřátelská kolona. Po jejím zpozorování jsou
vyslány helikoptéry, které ji mají zničit. Pokud dojde ke zničení kolony
označí se mise za úspěšnou. V ostatních případech (nezpozorování
kolony či zničení helikoptér) je mise označena za neúspěšnou.

Následující kód je příkladem, jak lze takovou misi řešit:

// --- Globalni promene pro ukonceni mise
 mise_uspesna   = false;
 mise_neuspesna = false;
 private ["tanky","helikoptery","papa_bear","hlidka"];
 tanky       = group TANK1; // TANK1 definovany v editoru
 helikoptery = group COBRA1; // COBRA1 definovana v editoru
 hlidka      = group player;
 papa_bear   = [west,"PAPA_BEAR"];

 // ---- zacatek mise ----
 [] spawn {
   sleep 1;
   hlidka addWaypoint [position KOTA,0]; // KOTA definovana v editoru
   [hlidka, 1] setWaypointSpeed  "NORMAL";
   [hlidka, 1] setWaypointBehaviour "STEALTH";
   [hlidka, 1] setWaypointCombatMode "RED";
   [hlidka, 1] setWaypointType "MOVE";

   tanky addWaypoint [position UDOLI,0]; // UDOLI definovane v editoru
   [tanky, 1] setWaypointSpeed  "LIMITED";
   [tanky, 1] setWaypointBehaviour "SAFE";
   [tanky, 1] setWaypointCombatMode "YELLOW";
   [tanky, 1] setWaypointType "MOVE";
   [tanky, 1] setWaypointFormation "COLUMN";
 };

 // ---- komunikace po dorazeni na kopec

 [] spawn {
   waitUntil {player distance KOTA<40};
   sleep 5;
   player sideChat "Táto medvěde, tady Alfa. Jsme na kótě 314.";
   sleep 5;
   papa_bear sideChat "Táta medvěd Alfě. Najděte si vhodnou pozici a pozorujte údolí na jihu. Hlaste jakýkoliv pohyb nepřítele. Do ničeho se nepouštějte.";
 };

 // ---- komunikace po detekci tanku
 [] spawn {
   waitUntil {{player knowsAbout vehicle _x>0} count units tanky>0};
   player sideChat "Táto medvěde, tady Alfa, slyšíte mě? Údolím se k naší pozici blíží nepřátelská obrněná technika.";
   sleep 5;
   papa_bear sideChat "Tady Táta medvěd. Posíláme helikoptéry. Vydržte na místě a kontrolujte situaci.";
   sleep 8;
   player sideChat "Rozumím, budeme vás informovat";

   // ---- pridam dynamicky WP helikopteram
   helikoptery addWaypoint [position leader tanky,0];
   [helikoptery, 1] setWaypointTimeout [1,3,2];
   [helikoptery, 1] setWaypointSpeed  "FULL";
   [helikoptery, 1] setWaypointBehaviour "COMBAT";
   [helikoptery, 1] setWaypointCombatMode "RED";
   [helikoptery, 1] setWaypointType "DESTROY";
 };

 // ---- dořešení konce mise (úspěch i neúspěch)
 [] spawn {
   waitUntil {({vehicle _x != x AND canMove vehicle _x} count units tanky==0) OR ({vehicle _x != x AND canMove vehicle _x} count units helikoptery==0) OR ({vehicle _x != x AND vehicle _x distance UDOLI<20} count units tanky>0)};
   sleep 3;
   try {
     if ({canMove vehicle _x} count units helikoptery==0) then {throw "heliny out"};
     if ({vehicle _x distance UDOLI<20} count units tanky>0) then {throw "tanky projely"};

     // ---- komunikace při zničení nepřátelské techniky
     leader helikoptery sideChat "Táto medvěde, hlásíme vyřazení nepřátelské techniky.";

     sleep 7;
     papa_bear sideChat "Tady Táta medvěd. Rozumím. Alfo, můžete to potvrdit?";
     sleep 7;
     player sideChat "Táto medvěde, tady Alfa, potvrzujeme zničení nepřátelské techiky";
     sleep 7;
     papa_bear sideChat "Dobrá práce.";
     sleep 5;
     mise_uspesna = true;
   } catch {

     if (_exception == "heliny out") then {
       // ---- komunikace při zničení helikoptér
       player sideChat "Táto medvěde, tady Alfa, přišli jsme o helikoptéry.";
       sleep 7;
       papa_bear sideChat "Tady Táta medvěd. Rozumím, stáhněte se.";
       sleep 5;
       mise_neuspesna = true;
     };

     if (_exception == "tanky projely") then {
       // ---- komunikace při projetí tanků
       papa_bear sideChat "Táta medvěd Alfě. Nepřátelské tanky projely. Stáhněte se.";
       sleep 5;
       mise_neuspesna = true;
     };
   };
 };

Switch

Dalším příkazem, který přišel s první verzí ArmA: Armed Assault a
který by vám mohl napomoci psát přehledný strukturovaný kód je příkaz
switch. Ten má syntax
*switch (nazev_proměnné) do {case „moznost1“:
{kod_pri_moznosti1};case „moznost2“:
{kod_pri_moznosti2};default {kod_v_ostatnich_pripadech}; * Nejlepší
bude si zase ukázat nějaký příklad. Vezmu ten, který jsem použil již u
(článku o výjimkách). Jde o přiřazování nálože objektům.

comment "skript na pridani naloze vojakovi v parametru _this";
	try {
   if (!alive _this) then {throw "neni nazivu"};
   if (!(_this isKindOf "Man")) then {throw "neni clovek"};
   _this addmagazine "pipebomb";
   hint "muzi byla uspesne vlozena bomba do inventare";
 }
 catch {
   switch (_exception) do {
     case "neni clovek": {
       _this addmagazinecargo ["pipebomb",1];
       hint "objektu byla pridana do vybaveni naloz";
     };
     case "neni nazivu": {
       hint "objekt kteremu se snazite pridat bombu jiz neni nazivu";
     };
     default {
       hint "neznama vyjimka";
     }
   };
 };

Někomu tento styl nemusí sedět, ale mě přijde celkem přehledný. Při
více možnostech je to podle mne mnohem lepší než velké množství if …
then… else…