Page 1 of 2

Priority Charge Target

Posted: Sat Nov 07, 2020 8:40 pm
by Athos1660
As I made the mistake with my Horse today, I just wanted to share the rule :
(I should have known it...)

Kuirassiers A can charge the Horse. Kuirassiers B can't.
The horses can charge A and B or go past them.

Image

Re: Priority Charge Target

Posted: Sun Nov 08, 2020 11:15 pm
by SnuggleBunnies
Wouldn't Horse A be ZoC locked by being one tile and facing within 45 degrees of an enemy?

Re: Priority Charge Target

Posted: Sun Nov 08, 2020 11:45 pm
by Athos1660
Image

I guess only infantry would. I'll carry out tests in the Editor when I have some time.

Re: Priority Charge Target

Posted: Sun Nov 08, 2020 11:51 pm
by SnuggleBunnies
Ah, so it's a priority charge, but you can still move away. Got it.

Re: Priority Charge Target

Posted: Mon Nov 09, 2020 6:13 am
by Athos1660
-

Re: Priority Charge Target

Posted: Sat Nov 14, 2020 11:37 pm
by awesum4
In the original picture A is ZOCed by both units so it can charge either. B is only ZOCed by the foot so can't charge the cavalry

Re: Priority Charge Target

Posted: Sun Nov 15, 2020 12:36 am
by Athos1660
This is indeed the definition of a priority charge target. According to the manual, it is either an :
  • (a) enemy within two map squares directly to their front (one square if the chargers are facing diagonally) and facing within 45 degrees of directly towards them,
  • or (b) enemy ZOCing them.
:-)

Re: Priority Charge Target

Posted: Sun Nov 29, 2020 8:32 pm
by Athos1660
Here is an application of the rules of Priority Charge Target. My Keil can't charge the rear of the enemy Keil :

Image

... because of the enemy Massed Arquebusiers that are within two map squares directly to its front and are an easy prey for Keil :

Image

Re: Priority Charge Target

Posted: Sun Nov 29, 2020 10:12 pm
by SnuggleBunnies
Of course if you moved the light arquebusiers into that intervening tile then you're freed up for the rear charge.

Re: Priority Charge Target

Posted: Sun Nov 29, 2020 10:35 pm
by Athos1660
The unit I guess you're referring to (at the bottom left of the screen) is Massed crossbowmen with AP=10 only, not LF with 12 AP.

Re: Priority Charge Target

Posted: Sun Nov 29, 2020 11:41 pm
by SnuggleBunnies
Ah, right. Still those sorts of tricks to break the charge locks are useful to keep in mind

Re: Priority Charge Target

Posted: Fri Dec 04, 2020 2:12 am
by Athos1660
When (a cruel) happiness is within reach, but... :-)

Image

A can't charge B (unlike in FoGII) as C is a priority charge target.

Re: Priority Charge Target

Posted: Fri Dec 04, 2020 9:11 am
by Cronos09
Most likely a small change in the FUNCTION CanZOC(unit, me, ignore_routers) (Tools.BSF at ...\Pike & Shot Campaigns\Data\scripts\) gives a possibility of charging in FoG2 in this case: adding the script string

Code: Select all

	if (IsInCloseCombat(unit) == 0) // Can't ZOC when in close combat
		{
		
		}

Re: Priority Charge Target

Posted: Fri Dec 04, 2020 10:44 pm
by Athos1660
Interesting. But it seems it does not work either because I did something wrong or it is the first rule about priority charge targets that applies here ('an enemy within two map squares directly to their front (one square if the chargers are facing diagonally) and facing within 45 degrees of directly towards them'), not the second one ('an enemy ZOCing them').

btw I guess it would also be FUNCTION CanZOC that could be modded to tweak the above situation about keils, if it had to. I don't know what the others think of it.

Also note, still about FUNCTION CanZOC, that the latest patch 1.5.33 of FoG: Ancients beta fixes a bug (certainly rarely observed in games) that allowed Light Artillery to exert ZoC, a bug present in P&S.

Re: Priority Charge Target

Posted: Sat Dec 05, 2020 11:28 am
by Cronos09
Athos1660, you are right. My guess was wrong. We need to compare FUNCTION PriorityChargeTargetAtTile(x, y, facing, me, current_target) in CombatTools.BSF at ...\Pike & Shot Campaigns (Field of Glory II)\Data\scripts\... The difference in the scripts is great.
I removed ZoС from Light Artillery in my TYW with generals module - see my post of 06.01.2020 https://www.slitherine.com/forum/viewto ... 3&start=40. To do this, replace (IsUnitSquadType(unit, "Artillery") == 0) in FUNCTION CanZOC(unit, me, ignore_routers) with (IsArtillery(unit) == 0).

Re: Priority Charge Target

Posted: Sat Dec 05, 2020 3:23 pm
by Athos1660
The difference in the scripts is great.
knowing that there is secondary ZoC in FoG2...

Re: Priority Charge Target

Posted: Sat Dec 05, 2020 7:12 pm
by Cronos09
Athos1660 wrote: Sat Dec 05, 2020 3:23 pm knowing that there is secondary ZoC in FoG2...
I would say so: knowing that there is secondary ZoC in FoG2 I am surprised that the P&S script is much more than FoG2 one.
Let's compare P&S

Code: Select all

FUNCTION PriorityChargeTargetAtTile(x, y, facing, me, current_target)
{
	int potential_target;
	int frontalX;
	int frontalY;
	int current_target_qualifies;
	int priorityTarget1;
	int priorityTarget2;
	int j;
	int k;
	int ret;

	ret = -1;

	priorityTarget1 = -1;
	priorityTarget2 = -1;

	current_target_qualifies = 0;

	frontalX = AdjacentX(x, facing);
	frontalY = AdjacentY(y, facing);

	potential_target = GetUnitOnTile(frontalX, frontalY);
	// If no unit there, look in the next tile forward (orthogonal directions only). (So that units in chequerboard formation can protect each other from being ganged up on)
	// I am not entirely sure about reducing the distance to 1 square in diagonal directions.
	// However, making it 2 squares diagonally looks odd on the map, it just looks too far away to be the priority target.
	// It might also cause issues with the method (see below) of checking for the diagonal move being blocked by an existing combat if "me" is not already in the adjacent square.
	// On the other hand , making it 1 square diagonally means that the effects of a chequerboard are lost in diagonal directions.
	// However, as the battle lines are normally drawn up orthogonally, I think that probably doesn't matter as much as getting it to look right.
	// Of course, I can easily change it back if it causes problems.
	if (potential_target == -1)
		{
			if ((facing == 0) || (facing == 90) || (facing == 180) || (facing == 270)) // Orthogonal directions
				{
					potential_target = GetUnitOnTile(AdjacentX(frontalX, facing), AdjacentY(frontalY, facing));
				}
		}

	// Log("Facing before turn, unit in that direction", facing, potential_target);

	if (potential_target > -1)
		{
			if ((GetUnitSide(potential_target) != GetUnitSide(me)) && (GetAttrib(potential_target, "MoraleState") < 3))
				{
					// If potential target facing within 45 degrees of directly towards us
					if (GetAngleFromTile(x, y, potential_target) < 50)
						{

							// If potential target is in close combat then it isn't a priority target if it isn't a permitted charge target.

							if ((IsInCloseCombat(potential_target) == 1) && (ChargePermitted(me, potential_target) == 0))
								{
									potential_target = -1;
								}

							// If potential target is blocked off from the testing unit by a diagonal close combat, then it isn't a priority target.
							// Cannot use if (CallUnitFunctionDirect(me, "CHECK_UNIT_ASSAULT", me, potential_target) < 0) as test because it causes a crash bug - presumably due to recursive function calls
							// The test below may not work perfectly for units that have to move to get to the adjacent position - if the program finds a different route, which is unlikely.
							// Attempting to shift the unit before testing will cause bugs owing to this function being called from Check_Unit_Assault().

							GetRouteCost(me, GetUnitX(potential_target), GetUnitY(potential_target), 0, 1);
							if (CheckRouteDiagonalStepNotBlocked(me, 4) == -2)
								{
									potential_target = -1;
								}

							if ((IsArtillery(potential_target) == 1) && (IsProtectedArtillery(potential_target) == 1))
								{
									potential_target = -1;
								}
								

							if (potential_target != -1)
								{
									// Non light troops ignore light troops except commanded shot protected by mounted
									if ((IsLightTroops(potential_target) == 0) || (IsProtectedCommShot(potential_target, 0) == 1) || (IsLightTroops(me) == 1))
										{
											if ((current_target == -1) || (potential_target == current_target))
												{
													ret = potential_target;
												}
											else
												{
													priorityTarget1 = potential_target;
												}
										}
								}
						}
				}
		}

	if (ret == -1)
		{
			// If current_target has not yet qualified as a priority target, check for ZOCers
			for (j = x-1; j <= x+1; j++)
			{
				for (k = y-1; k <= y+1; k++)
				{
					potential_target = IsTileZOCing(me, x, y, j, k, 1);
					if (potential_target >= 0)
						{
							if ((current_target == -1) || (potential_target == current_target))
								{
									ret = potential_target;
								}
							else
								{
									if (priorityTarget2 == -1)
										{
											priorityTarget2 = potential_target;
										}
								}
						}
				}
			}
		}

	if (ret == -1)
		{
			if (priorityTarget2 >= 0)
				{
					ret = priorityTarget2;
				}
			else
				{
					if (priorityTarget1 >= 0)
						{
							ret = priorityTarget1;
						}
					else
						{
						ret = current_target;
						}
				}
		}

	// Log("Unit, Priority Target", me, ret);

	return ret;
}
and FoG2

Code: Select all

FUNCTION PriorityChargeTargetAtTile(x, y, facing, me, current_target)
{
	int priority_target;
	int j;
	int k;
	int ret;

	ret = -1;

	if (ret == -1)
		{
			// Check for ZOCers
			for (j = x-1; j <= x+1; j++)
			{
				for (k = y-1; k <= y+1; k++)
				{
					priority_target = IsTileZOCing(me, x, y, j, k, 1, 0);
					if (priority_target >= 0)
						{
							ret = priority_target;
							if (ret == current_target)
								{
								  // Jump out of loops
									j = x + 2; 
									k = y + 2;
								}
						}
				}
			}
		}

	if (ret == -1)
		{
			ret = current_target;
		}

	// Log("Unit, Priority Target", me, ret);

	return ret;
}
The simple decision of your question:
find the condition if ((IsInCloseCombat(potential_target) == 1) && (ChargePermitted(me, potential_target) == 0)) and replace it with if (IsInCloseCombat(potential_target) == 1) //&& (ChargePermitted(me, potential_target) == 0)). That is to remove the second part of this condition.

Re: Priority Charge Target

Posted: Sat Dec 05, 2020 9:23 pm
by Athos1660
Indeed, now my A can charge B. Well done, Cronos.

Image

But I can't figure out all the implications of such a change right now :-)

Re: Priority Charge Target

Posted: Wed Dec 16, 2020 9:14 am
by Athos1660
In fact, both cases I came across in game and posted in this thread...

Image

Image

...are about (logically ?) preferring rear/flank charging a nearby target than sticking to the priority charge target(s) as defined by the two rules of the priority charge :
a) an enemy within two map squares directly to their front (one square if the chargers are facing diagonally) and facing within 45 degrees of directly towards them,
(b) enemy ZOCing them.
... or, at least, about having this opportunity to rear/flank charge.

Thus, instead of changing the condition...
if ((IsInCloseCombat(potential_target) == 1) && (ChargePermitted(me, potential_target) == 0)) and replace it with if (IsInCloseCombat(potential_target) == 1) //&& (ChargePermitted(me, potential_target) == 0)). That is to remove the second part of this condition.
... as cleverly suggested by Cronos above, how about adding a third rule to the priority charge rules :
(c) enemy can be rear/flank charged when in one of the 3 squares in front of them (from A to B) :
Image

It is impossible in Vanilla P&S. A and B can currently be charged only if facing our unit :

Image

Would it be possible to mod it ? Would it be a good thing ?

(edit)
But then the question on the above picture is : should our unit be allowed to charge B as A would be able to flank charge it in the next turn ? No ? Yes, at your own risk ?

(edit 2)
With the current rules, you can actually charge B at the risk of being flank charged by A during the next turn :

Image

So yes ?

Re: Priority Charge Target

Posted: Wed Dec 16, 2020 10:33 am
by Athos1660
The rules of priority charge target would become :
(a) an enemy on the next nearest map square directly to their front and facing towards them,
(b) an enemy ZoCing them,
(c) an enemy in the 3 tiles to their “front” and in a position of being rear/flank charged.
Image

Any thoughts ?

(edit, edit...)