39-45 Stratégie > Jeux vidéo > Theatre of War > Theatre of War > Tutoriel de l'éditeur > Les scripts > Partie C 

tuto script partie C, les attaques d'infanterie

Nous allons dans cette partie voir comment faire les triggers d'attaque pour l'infanterie.


Le principe de l'attaque est le suivant :

les 4 sections d'infanterie avancent jusqu'au milieu de la carte, en progressant prudemment par bon (mode de déplacement KNEE). Ils se positionnent en deux groupes de deux sections, l'une derrière l'autre, et en ligne.

A partir de là, le premier groupe de deux sections attaquent le village.

Le deuxième groupe attaque soit le village, soit la colline où sont les tranchées.

Dans ce deuxième cas, une fois les tranchées conquises, le groupe continue vers le village.


D'habitude, les soldats attaquent par vague, en progressant par bons, et se fond massacrer par « centaine » sans se détourner. Nous allons essayer de programmer quelque chose de plus « réaliste » :

Nous avons mis deux sections l'une derrière l'autre. Pendant 20 secondes, la première section avance par bon (mode KNEE), puis elle se couche, et reste à terre (mode HOLD), et couvre la deuxième section qui avance à son tour.


Voilà pour les grandes lignes.

Voyons maintenant comment cela peut se traduire :


La zone de regroupement

Tout d'abord, il nous faut faire une zone de regroupement au milieu de la carte. Il faut choisir un endroit qui ne soit pas en vue du joueur, car l'IA pourrait voir des soldats du joueur, et partir à l'attaque au lieu d'attendre les ordres...


Nous allons donc créer 4 points pour la position des 4 sections d'infanterie, et un rectangle entourant le tout, pour pouvoir tester si les unités sont bien arrivées en position. Enfin, il est genant d'envoyer plusieurs chars sur un point, car ils vont s'entasser sur ce point.



On peut facilement régler la position et la taille des rectangles et points, avec l'icone entourée !



Voici la première partie du trigger « attaque centrale »


Déplacement vers la zone de regrouppement (Rect_regroup)

////////////////////////////////////////////// attaque centrale /////////////////////////

SetWorkArmy ( ARMY , 2 )

BodyMode ( GROUP , "inf_01" , KNEE )
BodyMode
( GROUP , "inf_02" , KNEE )
BodyMode
( GROUP , "inf_03" , KNEE )
BodyMode
( GROUP , "inf_04" , KNEE )

SetGroupFormation ( "inf_01" , LINETANKHUMAN )
SetGroupFormation
( "inf_02" , LINETANKHUMAN )
SetGroupFormation
( "inf_03" , LINETANKHUMAN )
SetGroupFormation
( "inf_04" , LINETANKHUMAN )


RunCommand ( GROUP , "inf_01" , MOVE , POINT , "Point_20" , point , "Point_24" )
RunCommand
( GROUP , "inf_02" , MOVE , POINT , "Point_21" , point , "Point_24" )
RunCommand
( GROUP , "inf_03" , MOVE , POINT , "Point_22" , point , "Point_24" )
RunCommand
( GROUP , "inf_04" , MOVE , POINT , "Point_23" , point , "Point_24" )

RunCommand ( GROUP , "T26_2" , MOVE , rect , "Rect_regroup" )

////////////////////////////////////////////////////////////////////////////////////////////////////////////

Bodymode permet de choisir la position de déplacement (ramper = LAY , par bond = KNEE , debout = STAY, au choix de l'IA = FREE )

SetGroupFormation permet de choisir la formation. Cela reste très théorique car l'IA fait constament bouger les soldats. On a le choix entre toutes ces formations :


   CUSTOM                              - la formation de combat actuelle du groupe
    WEDGE                                - formation en coin
    TRENCHFORMATION      - personnel dans les tranchées, véhicules derrières les tranchées
    LINETANKHUMAN          - chars et infanterie en ligne
    COLUMN                             - formation en colonne
    DISPERSE                            - formation dispersée
    GATHER                              - formation compacte

Enfin, on fait déplacer le groupe. Pour que la formation (en ligne) soit bien orientée, il faut définir un point d'arrivée (le point 20 pour la première section) et un point d'orientation (la section fera face au point 24) :

RunCommand ( GROUP , "inf_01" , MOVE , POINT , "Point_20" , point , "Point_24" )


Vérification que les unités ont atteint la zone de regrouppement

////////////////////////////////////////////////////////////////////////////////////////////////////////////

label regroup

delay ( 10000 )

SET @num1 = GetNUnitsInArea ( GROUP , "inf_01" , human , "Rect_regroup" )
SET
@num2 = GetNUnitsInArea ( GROUP , "inf_02" , human , "Rect_regroup" )
SET
@num3 = GetNUnitsInArea ( GROUP , "inf_03" , human , "Rect_regroup" )
SET
@num4 = GetNUnitsInArea ( GROUP , "inf_04" , human , "Rect_regroup" )

IF ( @num1 < 5 and @num2 < 5 and @num3 < 5 and @num4 < 5 ) then
   GOTO regroup
   ENDIF

SendMessage ( "des unités russes sont repérées droit devant" , 10000 )

// au moins un groupe de soldat est arrivé dans la zone de regroupement

BodyMode ( GROUP , "inf_01" , LAY )
BodyMode
( GROUP , "inf_02" , LAY )
BodyMode
( GROUP , "inf_03" , LAY )
BodyMode
( GROUP , "inf_04" , LAY )

delay ( 120000 )

////////////////////////////////////////////////////////////////////////////////////////////////////////////

Il est difficile de trouver une condition simple pour tester que toutes les unités sont dans le rectangle pour deux raisons :

+Les unités se baladent un peu autour de leur position indiquée.

+Les unités se précipitent pour attaquer toute unité du joueur visible et sortent du rectangle (avant d'y revenir une fois les unités joueur détruites, ce qui peut prendre du temps...)

+Il faut en plus savoir combien d'unité reste dans le groupe en fonction des pertes.


Donc pour plus de simplicité, je teste si un des 4 groupes a au moins 5 soldats (sur 11) dans le rectangle. Ensuite, on attend 2 minutes encore que tout le monde prenne position. On repasse qussi en mode couché pour être moins repérable.


Les attaques

Le premier T26 pars vers le village avec les deux sectiobs d'infanterie :

////////////////////////////////////////////////////////////////////////////////////////////////////////////

RunCommand ( GROUP , "T26_2" , ATTACK , rect , "A1" )
RunCommand ( GROUP , "inf_01" , ATTACK , rect , "A1" )
RunCommand
( GROUP , "inf_02" , ATTACK , rect , "A1" )

////////////////////////////////////////////////////////////////////////////////////////////////////////////


Pour le deuxième groupe, il s'agit des mêmes actions, mais la zone rectangle peut être soit le village, soit les tranchées, avec une chance sur deux (nombre aléatoire @alea2 ). Nous allons utiliser une variable globale @@zone01 (nous verrons l'utilité d'être globale plus tard).

////////////////////////////////////////////////////////////////////////////////////////////////////////////

SET @alea2 = Rnd ( )
IF ( @alea2 < 50 ) THEN
   SET @@zone01 = "A1"
   ENDIF

IF ( @alea2 > 49 ) THEN
   SET @@zone01 = "Rect_tranchee"
   RunTrigger ( "attaque inf 2" )
   ENDIF

RunCommand ( GROUP , "T26_1" , STORM , rect , @@zone01 )
RunCommand
( GROUP , "inf_03" , ATTACK , rect , @@zone01 )
RunCommand
( GROUP , "inf_04" , ATTACK , rect , @@zone01 )

////////////////////////////////////////////////////////////////////////////////////////////////////////////

Dans le cas de la tranchée, il faut lancer un deuxième trigger [RunTrigger ( "attaque inf 2" )] pour rediriger le groupe de combat vers le village une fois la tranchée conquise.

Enfin, nous lancons les deux programmes qui gèrent la progression de l'infanterie en mode « tirailleur ».

RunTrigger ( "attaque squad 1" )
RunTrigger ( "attaque squad 2" )


Le mode « tirailleur » (trigger attaque squad 1).


Nous créons donc deux triggers pour gérer la progression de l'infanterie. Ils sont quasi identiques, nous allons voir uniquement le deuxième.


///////////////////////////////////////attaque squad 2///////////////////////////////////////////////

SetWorkArmy ( ARMY , 2 )
SET
@c2 = 0

LABEL compteur_c2b
DELAY 15000
ADD (
@c2 , 1 )
IF (
@c2 = 3 ) then
   SUB (
@c2 , 2 )
   endif

IF ( @c2 = 1 ) THEN
   PositionMode
( GROUP , "inf_03"
, FREE )
   BodyMode
( GROUP , "inf_03" , KNEE )
   RunCommand
( GROUP , "inf_03" , ATTACK , rect , @@zone01 )

   PositionMode ( GROUP , "inf_04" , HOLD )
   BodyMode
( GROUP , "inf_04" , LAY )
   ENDIF


IF ( @c2 = 2 ) THEN
   BodyMode
( GROUP , "inf_03" , LAY )
   PositionMode
( GROUP , "inf_03"
, HOLD )

   BodyMode ( GROUP , "inf_04" , KNEE )
   PositionMode ( GROUP , "inf_04" , FREE )
   RunCommand
( GROUP , "inf_04" , ATTACK , rect , @@zone01 )

   ENDIF


SET @num2 = GetNUnits ( GROUP , "inf_03" , HUMAN )
SET
@num3 = GetNUnits ( GROUP , "inf_04" , HUMAN )
IF (
@num2 > 3 OR @num3 > 3 ) THEN

   GOTO compteur_c2b
   ENDIF

   

////////////////////////////////////////////////////////////////////////////////////////////////////////////

Nous avons créée un « compteur »@c2 qui comprend deux états, 1 ou 2 (on peut en faire plus pour gérer plus d'action). Le compteur part de 0. En début de boucle, on ajoute 1. Si la valeur est 3, on retranche 2, ce qui nous ramène à 1. Si la valeur est 2, on fait rien. On a donc bien deux états, 1 ou 2. C'est un peu compliqué, mais cela permet de faire par exemple trois états, si on voulait que le groupe cours, puis marche, puis rampe...

Ici, on fait juste LAY et KNEE ! Donc deux états.

Si la valeur est à 1, le groupe 3 avance, c'est à dire, PositionMode est à FREE (on peut avancer), le mode de déplacement est KNEE (BodyMode), et on attaque la zone @@zone01,ce qui permet d'utiliser la variable globale, contenant la zone qui a été décidée pour l'attaque de ce groupe de combat.

Le deuxième groupe est en PositionMode HOLD, ce qui le contraint à s'arreter, et à terre , avec BodyMode LAY.

A noter que PositionMode HOLD semble annuler l'ordre de runcommand, c'est pourquoi on est obligé de relancer la commande à chaque fois.

Voici une image du groupe en progression tirailleur. On voit le groupe de tête à plat ventre, qui couvre le deuxième groupe qui viens de se relever.


Ce mode de progression est répété tant que les pertes ne sont pas trop élevées. Mais si un des groupes contient moins de 4 soldats, on arrête ce mode de progression et on passe à la suite du script.


////////////////////////////////////////////////////////////////////////////////////////////////////////////

SendMessage ( "un groupe russe 1 est en déroute" , 10000 )

PositionMode ( GROUP , "inf_01" , FREE )
PositionMode
( GROUP , "inf_02"
, FREE )

BodyMode ( GROUP , "inf_01" , LAY )
BodyMode
( GROUP , "inf_02" , LAY )

RunCommand ( group , "inf_01" , RETREAT , RECT , "Rect_tranchee" )
RunCommand
( group , "inf_02"
, RETREAT , RECT , "Rect_tranchee" )

Halt

////////////////////////////////////////////////////////////////////////////////////////////////////////////

On effectue une retraite, vers les tranchées. Cela n'a pas beaucoup de sens ici, car on ne sait pas si les tranchées sont prises ou non, mais c'est purement illustratif !


Suite de l'attaque

Nous allons maintenant voir le trigger qui a pour but de continuer l'attaque vers le village lorsque les tranchées sont prises (trigger « attaque inf 2 »)


On calcule le nombre de soldat du groupe dans la zone des tranchées(@num1). On calcule le nombre de soldat total du groupe (@num3). Lorsque le nombre de soldats dans la zone est égale à 50% du nombre total de soldat du groupe, et qu'il n'y a plus d'ennemi dans cette zone(@num5), on attend 10 minutes avant de repartir vers le village. Pour tester si num1 est égale à 50% de num3, on divise en fait num3 par 2 ( DIV ( @num3 , 2 ) ). Rappel, le jeu ne gère que des nombres entiers. Il faut donc vérifier en plus que num3 est supérieur à 0.

////////////////////////////////////////////// attaque inf 2 /////////////////////////////////////////////////////////////

label regroup
delay ( 10000 )

SET @num1 = GetNUnitsInArea ( GROUP , "inf_03" , human , "Rect_tranchee" )
SET
@num2 = GetNUnitsInArea ( GROUP , "inf_04" , human , "Rect_tranchee" )
SET
@num3 = GetNUnits ( GROUP , "inf_03" , HUMAN )
SET
@num4 = GetNUnits ( GROUP , "inf_04" , HUMAN )
SET
@num5 = GetNUnitsInArea ( ARMY , 1 , human , "Rect_tranchee" )

DIV ( @num3 , 2 )
DIV (
@num4 , 2 )

IF ( @num1 < @num3 and @num3 > 0 ) THEN
   GOTO
regroup

   ENDIF

IF ( @num2 < @num4 and @num4 > 0 ) THEN
   GOTO regroup
   ENDIF

IF ( @num5 > 0 ) THEN
   GOTO regroup
   ENDIF

delay ( 600000 ) // 10 minutes d'attente

SET @@zone01 = "A1"
RunCommand ( GROUP , "T26_1" , STORM , rect , @@zone01 )
RunCommand
( GROUP , "inf_03" , ATTACK , rect , @@zone01 )
RunCommand
( GROUP , "inf_04" , ATTACK , rect , @@zone01 )

Halt

////////////////////////////////////////////////////////////////////////////////////////////////////////////

La suite

Retour au sommaire