Working on a segment to order XBows escort LightGuns

Moderator: rbodleyscott

Post Reply
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

Scripting for Day of Herrings
Trying to make function blow
On the initial phase enemy XBow escorting their LG bombarding player’s wagonberge without Barring LG’s Line of Fire

Code: Select all

Tilex=GetUnitX(LG);
Tilex+=1;
Tiley=GetUnitY(LG);
If(IsUnitValid(XBow) == 1)
   {
      If(GetAttrib(LG,"moralestate") < 3)
         {
           if(GetAttrib(LG,"moved”) == 1)
               {
                SetUnitDestination(XBow,Tilex,Tiley);
                //Moveunittowardsdestination(XBow);
                SetAttrib(Xbow,"movelast",1);
               }
            Else
               {
                 SetUnitDestination(Xbow,-1,-1); //At first I wrote SetAttrib(Xbow,"AP",0);
               }
          }
     }
I’m not sure whether it will work properly.
At first I set Xbow’s Ap to 0,if the Light gun unmoved,however the Xbow just stayed put all day long even if the LG moved forward.
I guess it’s becuz AI’s action of LG executed after Xbow,and Xbow’s AP has been cut to zero when it’s his term of action.But what’s “movelast”for? Not for the selected id act after all the other units of the side have been used?
So I altered this sentence with SetUnitDestination to(-1,-1),but not tested yet.
Before commented out moveunittowardsdestination(),the AI Xbow always act before his turn,I do wrote if(side == 1) before this segment,it seems by this sentence the XBow got an extra turn?
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28323
Joined: Sun Dec 04, 2005 6:25 pm

Re: Working on a segment to order XBows escort LightGuns

Post by rbodleyscott »

The "MovedLast" attrib (not "MoveLast") is part of the Undo system. Nothing to do with sequence of movement.

Because of the sequence of play, I think you are probably doomed to failure in getting the Xbows to follow the Guns when the guns are moved by the AI.

Why not move both Guns and XBows automatically using MoveTowardsDestination(), then set their AP to zero so they don't get to move twice?
Richard Bodley Scott

Image
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

rbodleyscott wrote: Tue Nov 22, 2022 9:22 am Why not move both Guns and XBows automatically using MoveTowardsDestination(), then set their AP to zero so they don't get to move twice?
Thanks! Richard. It doesn’t move twice now,but will still block Guns’ line of fire,seems the destination I set (LGX+/-1,LGY) doesn’t work.
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28323
Joined: Sun Dec 04, 2005 6:25 pm

Re: Working on a segment to order XBows escort LightGuns

Post by rbodleyscott »

locustmustdie wrote: Tue Nov 22, 2022 2:59 pm
rbodleyscott wrote: Tue Nov 22, 2022 9:22 am Why not move both Guns and XBows automatically using MoveTowardsDestination(), then set their AP to zero so they don't get to move twice?
Thanks! Richard. It doesn’t move twice now,but will still block Guns’ line of fire,seems the destination I set (LGX+/-1,LGY) doesn’t work.
By all means email me the whole folder and I will take a look. (A script fragment, or even the whole script, may not reveal the answer).
Richard Bodley Scott

Image
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

rbodleyscott wrote: Tue Nov 22, 2022 3:13 pm By all means email me the whole folder and I will take a look. (A script fragment, or even the whole script, may not reveal the answer).
Thanks,mail sent.
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28323
Joined: Sun Dec 04, 2005 6:25 pm

Re: Working on a segment to order XBows escort LightGuns

Post by rbodleyscott »

As far as I can see, what you are attempting to achieve simply isn’t possible. You are not going to be able to move the Crossbowmen depending on what the AI decides the Artillery should do this turn.

The problem is that StartTurnPost() is processed BEFORE AI movement. So the LG “moved” attrib will be 0, and the LG destination won’t yet be set. Your current code is therefore not doing anything, the units are just being moved by the AI with seek and destroy orders.

You could automove both the guns and crossbowmen, for the first move or two, to get the crossbowmen in range. (With the previous conditions re gun survival). But that won’t stop them from possibly obstructing the guns later.

I have emailed you a script that moves them on the first turn.

Note also that if you add or subtract any units from the French side, including during force selection, the id numbers will change, so the script would not work.

Cheers,

Richard
Richard Bodley Scott

Image
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28323
Joined: Sun Dec 04, 2005 6:25 pm

Re: Working on a segment to order XBows escort LightGuns

Post by rbodleyscott »

Another question is why move the guns at all at the start of the game? They are already in range.

You could give them 0 AP on the first two turns, to stop them from moving, and just automove the crossbowmen straight forward for the first turn (long range) and possibly second turn (short range) without crossing in front of the guns.
Richard Bodley Scott

Image
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

rbodleyscott wrote: Wed Nov 23, 2022 10:01 am Another question is why move the guns at all at the start of the game? They are already in range.

You could give them 0 AP on the first two turns, to stop them from moving, and just automove the crossbowmen straight forward for the first turn (long range) and possibly second turn (short range) without crossing in front of the guns.
cuz I want to perform a move&shoot tactic which would inflict casualties to more units.Rouvray is a place described as “featherless almost flat”,little could be done to the terrain design,that made me prefer to do some experiments never tried before in this scenario.
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28323
Joined: Sun Dec 04, 2005 6:25 pm

Re: Working on a segment to order XBows escort LightGuns

Post by rbodleyscott »

locustmustdie wrote: Wed Nov 23, 2022 11:42 am
rbodleyscott wrote: Wed Nov 23, 2022 10:01 am Another question is why move the guns at all at the start of the game? They are already in range.

You could give them 0 AP on the first two turns, to stop them from moving, and just automove the crossbowmen straight forward for the first turn (long range) and possibly second turn (short range) without crossing in front of the guns.
cuz I want to perform a move&shoot tactic which would inflict casualties to more units.Rouvray is a place described as “featherless almost flat”,little could be done to the terrain design,that made me prefer to do some experiments never tried before in this scenario.
If you just make the light guns halt for the first two turns, thereafter the AI will move them forward if they no longer have a target within range.
Richard Bodley Scott

Image
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

can u delete this,Richard? thx
Last edited by locustmustdie on Mon Nov 28, 2022 3:58 pm, edited 1 time in total.
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

Code: Select all

FUNCTION StartTurnPost(side)
{
int i;
int id;
int team;
int turn;
int target;
int targetX;
int targetY;
turn = GetTurn();

if (side == 1)
                               {
                               for(i=0;i <GetUnitCount(1);i++)
     {
      id = GetUnitID(1,i);
      if (id != -1)
          {
           if ((GetAttrib(id, "MoraleState") < 3) &&  (IsUnitValid(id) == 1))
                {
                  if(IsUnitSquadType(id, "Light_Artillery") == 1) //order the guns search and shoot at its max range.
                                {
                                  target=GetClosestEnemyUnit(1, id);
                                  targetX=GetUnitX(target);
                                  targetY=GetUnitY(target);
                                              if (GetDistanceBetween(id, target) > MaximumRange(id))
                                                                   {
                                                                       SetUnitDestination(id,targetX,targetY);
                                                                       MoveTowardsDestination(id);
                                                                       SetAttrib(id,"AP",0); 
                                                                   }
                                                              else
                                                                  {
                                                                      SetAttrib(id,"AP",0); 
                                                                  }
                                }                                                                                    
                } 
          } 
     }

for(i=0;i <GetUnitCount(1);i++)
     {
      id = GetUnitID(1,i);
      if (id != -1)
          {
           if ((GetAttrib(id, "MoraleState") < 3) && (IsUnitValid(id) == 1))
                {
                  if(IsUnitSquadType(id, "Bowmen") == 1) 
                                {
                                      if(GetUnitTeam(id) == 1)
                                           {
                                                 EscortUnit(1,id,"Light_Artillery"); //order the missile troops in team1 to follow the artillery
                                                 SetAttrib(id,"AP",0);   
                                           }
                                }
                }
          }
      }

                               }
}

--------ScriptBottom---------

// Returns the id of the closest enemy unrouted and not-in-closecombating unit to our chosen unit
FUNCTION GetClosestEnemyUnit(side, me)
{
	int enemySide;
	int closestDistance;
	int distance;
	int total;
	int i;
	int id;
                 int closestEnemy;

	closestDistance = 64000;

	enemySide = side + 1;
	enemySide = enemySide % 2;

	total = GetUnitCount(enemySide);

	for (i = 0; i < total; i++)
	{
		id = GetUnitID(enemySide, i)

		if (id != -1)
			{
				if ((IsUnitValid(id) == 1) && (IsValidTile(GetUnitX(id), GetUnitY(id)) == 1) && (GetAttrib(id, "MoraleState") < 3))
					{
						if ((IsLightTroops(id) == 0) && (IsInCloseCombat(id) == 0))
							{
								
													distance = GetDistanceBetweenTiles(GetUnitX(me), GetUnitY(me), GetUnitX(id), GetUnitY(id));

													if (distance < closestDistance)
														{
															closestDistance = distance;
                                                   closestEnemy = id;
														}
												
							}
					}
			}
	}


	return closestEnemy;
}

// Returns the id of the closest friendly unrouted and not-in-closecombating unit to our chosen unit
FUNCTION GetClosestFriendlyUnit(side,me,type)
{
	int closestDistance;
	int distance;
	int total;
	int i;
	int id;
                 int closestFriendly;  

	closestDistance = 64000;
	total = GetUnitCount(side);

	for (i = 0; i < total; i++)
	{
		id = GetUnitID(side, i)

		if (id != -1)
			{
				if ((IsUnitValid(id) == 1) && (IsValidTile(GetUnitX(id), GetUnitY(id)) == 1) && (GetAttrib(id, "MoraleState") < 3))
					{
						if (((IsLightTroops(id) == 0) || (IsUnitSquadType(id, "Light_Artillery") == 1)) && (IsInCloseCombat(id) == 0))
							{
								if(IsUnitSquadType(id, type) == 1)  //alter the "type" with the kind of units you want to escort
                                                                                                                                              {
													distance = GetDistanceBetweenTiles(GetUnitX(me), GetUnitY(me), GetUnitX(id), GetUnitY(id));

													if (distance < closestDistance)
														{
															closestDistance = distance;
                                                   closestFriendly = id;
														}
                                                                                                                                              }
												
							}
					}
			}
	}


	return closestFriendly;
}

//Return the X value of the adjacent tile that unit is facing
FUNCTION GetFrontX(me)
{
int x;
    if((GetUnitFacing(me) == 0) || (GetUnitFacing(me) == 4))
         {
           x=GetUnitX(me);
         }
    if((GetUnitFacing(me) == 1) || (GetUnitFacing(me) == 2) || (GetUnitFacing(me) == 3))
         {
           x=GetUnitX(me);
           x+=1;
         }
    if((GetUnitFacing(me) == 5) || (GetUnitFacing(me) == 6) || (GetUnitFacing(me) == 7))
         {
           x=GetUnitX(me);
           x-=1;
         }
     return x;

}

//Return the Y value of the adjacent tile that unit is facing
FUNCTION GetFrontY(me)
{
int y;
    if((GetUnitFacing(me) == 2) || (GetUnitFacing(me) == 6))
         {
           y=GetUnitY(me);
         }
    if((GetUnitFacing(me) == 1) || (GetUnitFacing(me) == 0) || (GetUnitFacing(me) == 7))
         {
           y=GetUnitY(me);
           y+=1;
         }
    if((GetUnitFacing(me) == 3) || (GetUnitFacing(me) == 4) || (GetUnitFacing(me) == 5))
         {
           y=GetUnitY(me);
           y-=1;
         }
     return y;

}

//search the closest tile among the 8 tiles surrounding the escorted unit
FUNCTION EscortPosition(me,escorted)
{
int x;
int y;
int tilex;
int tiley;
int limitx;
int limity;
int distance;
int closestDistance;
int DefendableX;
int DefendableY;

DefendableX = -1;
DefendableY = -1;
tilex=GetUnitX(escorted);
tiley=GetUnitY(escorted);
limitx=tilex+1;
limity=tiley+1;
closestDistance = 64000;

for(x=tilex-1;x<limitx;x++)
      {
          for(y=tiley-1;y<limity;y++)
                 {
                    if ((x == GetFrontX(escorted)) && (y == GetFrontY(escorted)))
                             { 
                             }
                           else
                                     {   
                                           if((x == GetUnitX(escorted)) && (y == GetUnitY(escorted)))
                                                 {
                                                 }      
                                           else
                                                     {    
                                                           if(GetUnitOnTile(x,y) == -1)
                                                                   {
                                                                     distance = GetDistanceBetweenTiles(GetUnitX(me), GetUnitY(me), GetUnitX(escorted), GetUnitY(escorted));
		                                   if (distance < closestDistance)
		                                         {
                                                                                    closestDistance = distance;                                              
                                                                                    DefendableX = x;
                                                                                    DefendableY = y;
		                                         }
                                                                   }
                                                     }
                                     }
                       
                 }
      }
       if (GetDistanceBetween(me, escorted) > 1)
                  {
                    SetUnitDestination(me,DefendableX,DefendableY);
                    MoveTowardsDestination(me);
                    SetAttrib(me,"AP",0);
                  }
      else
                  {
                    SetAttrib(me,"AP",0);
                  } 
}

//Go to the defendable position to escort the closest perticular type of friendly unit
FUNCTION EscortUnit(side,me,type)
{
      EscortPosition(me,GetClosestFriendlyUnit(side,me,type));
}                               
To get FUNCTION GetClosestEnemyUnit(side, me),there's similar function either in tools.bsf or aitools.bsf,easy to modify.
And a mechanism of the smallest/biggest X need to be developed to decide the target to protect if 2or more guns have the same distance between the escorting unit.
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

much smoother now, although not perfect.
1368870_screenshots_20221127152311_1.jpg
1368870_screenshots_20221127152311_1.jpg (306 KiB) Viewed 2839 times
a new function FriendlyOnLeft was added,inserted into the escort function

Code: Select all

FUNCTION EscortPosition(me,escorted,squad)
{
int x;
int y;
int tilex;
int tiley;
int limitx;
int limity;
int distance;
int closestDistance;
int DefendableX;
int DefendableY;

DefendableX = -1;
DefendableY = -1;
tilex=GetUnitX(escorted);
tiley=GetUnitY(escorted);
limitx=tilex+1;
limity=tiley+1;
closestDistance = 64000;

for(x=tilex-1;x<limitx;x++)
      {
          for(y=tiley-1;y<limity;y++)
                 {
                    if ((x == GetFrontX(escorted)) && (y == GetFrontY(escorted)))
                             { 
                             }
                           else
                                     {   
                                           if((x == GetUnitX(escorted)) && (y == GetUnitY(escorted)))
                                                 {
                                                 }      
                                           else
                                                     {    
                                                           if(GetUnitOnTile(x,y) == -1)
                                                                   {
                                                                     distance = GetDistanceBetweenTiles(GetUnitX(me), GetUnitY(me), GetUnitX(escorted), GetUnitY(escorted));
		                                   if (distance < closestDistance)
		                                         {
                                                                                    closestDistance = distance;                                              
                                                                                    DefendableX = x;
                                                                                    DefendableY = y;
		                                         }
                                                                    //Set priority for same distance targets
                                                                   else
                                                                          {
                                                                               if(distance == closestDistance)
                                                                                     {
                                                                                          if(FriendlyOnLeft(me,squad) == -1) //chose the righter target to escort
                                                                                             {
                                                                                                 if(DefendableX > x)
                                                                                                    {
                                                                                                         DefendableX = x;
                                                                                                         DefendableY = y;
                                                                                                    }
                                                                                             }
                                                                                         if(FriendlyOnLeft(me,squad) == 1) //chose the lefter target to escort
                                                                                             {
                                                                                                 if(DefendableX < x)
                                                                                                    {
                                                                                                         DefendableX = x;
                                                                                                         DefendableY = y;
                                                                                                    }
                                                                                             }
                                                                                         if(FriendlyOnLeft(me,squad) == 0) //chose the fronter target to escort
                                                                                             {
                                                                                                 if(DefendableY < y)
                                                                                                    {
                                                                                                         DefendableX = x;
                                                                                                         DefendableY = y;
                                                                                                    }
                                                                                             }
                                                                                     }
                                                                          }
                  


                                                                   }
                                                     }
                                     }
                       
                 }
      }
       if (GetDistanceBetween(me, escorted) > 1)
                  {
                    SetUnitDestination(me,DefendableX,DefendableY);
                    MoveTowardsDestination(me);
                    SetAttrib(me,"AP",0);
                  }
      else
                  {
                    SetAttrib(me,"AP",0);
                  } 
}

//Go to the defendable position to escort the closest perticular type of friendly unit
FUNCTION EscortUnit(side,me,type,squad)
{
      EscortPosition(me,GetClosestFriendlyUnit(side,me,type),squad);
}

//Return 1 if there is a friendly unit of specipic type on the left side of me
FUNCTION FriendlyOnLeft(me,squad)
{
int i;
int id;
int dx;
int dy;
int left;
int right;
int middle;
int ret;
          
       for(i=0;i<GetUnitCount(1);i++)
                  {
                      if ((IsUnitValid(id) == 1) && (IsValidTile(GetUnitX(id), GetUnitY(id)) == 1) && (GetAttrib(id, "MoraleState") < 2)) //unit unfragmented
	             {
		if (((IsLightTroops(id) == 0) || (IsUnitSquadType(id, "Light_Artillery") == 1)) && (IsInCloseCombat(id) == 0)) //idle Non-Light unit
		       {
		             if(IsUnitSquadType(id, squad) == 1)  //alter the "squad" with the kind of units you want
                                                         {
                                                                   dy=(GetUnitY(id) - GetUnitY(me));
                                                                   dx=(GetUnitX(id) - GetUnitX(me));
                                                                   if((dy >= -2) && (dy <=1))
                                                                         {                              
                                                                                 if((dx > 0) && (dx <= 3))
                                                                                       {
                                                                                               left=1;
                                                                                       }
                                                                                 if((dx == 0) && (dy != 0))
                                                                                       {
                                                                                               middle=1;
                                                                                       }
                                                                                 if((dx < 0) && (dx >= 3))
                                                                                       {
                                                                                               right=1;
                                                                                       }
                                                                         }
                                                         }
                                         }
                              }

                  }
        if(((left == 0) && (right == 0)) || ((left == 1) && (right == 1)))
            {
                  ret=0;
            }        
        if((left == 1) && (right == 0))
            {
                  ret-=1;
            }      
        if((left == 0) && (right == 1))
            {
                  ret=1;
            } 
     
return ret;

}
locustmustdie
Senior Corporal - Destroyer
Senior Corporal - Destroyer
Posts: 117
Joined: Fri Mar 05, 2021 11:33 am

Re: Working on a segment to order XBows escort LightGuns

Post by locustmustdie »

All test passed
I made it :D :D :D
It will be shown in Rouvray's Published edition
Post Reply

Return to “Field of Glory II: Medieval - Modding”