Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post Reply
CharlesdeBatz
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 53
Joined: Sun Jul 11, 2021 5:41 pm

Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by CharlesdeBatz »

I've begun an attempt to add in reactive fire to FoG by copying the REACT_Unit_Shoot function from P&S Shooting.bsf to the FoG Shooting.bsf. However, this only results in enemy units (on my turn) and friendly units (on the enemy's turn) returning fire when fired upon by opposing missile troops. Additionally, this return of fire seems to occur only when the other unit is directly in front (that is the angle between the shooting unit's facing and the enemy unit is zero), and even then it is not consistent.

Is there anything else that needs to be done in the scripts to enable the reactive fire functionality? I am particularly interested in enabling units to shoot at opposing units that move into range, even if they do not fire on the unit.
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28007
Joined: Sun Dec 04, 2005 6:25 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by rbodleyscott »

It is such a long time since I disabled it, that I cannot recall all that might be needed to re-enable it.

However, currently it is disabled by the code in

REACT_Unit_Shoot()

in /Data/Battle/Scripts/Shooting.BSF

Code: Select all

// -1 means don't even consider firing
FUNCTION REACT_Unit_Shoot(me, unit)
{
	return -1; // No reaction shooting.
}
Try replacing that with the Pike and Shot version:

Code: Select all

// we return a score to determine who should fire
// -1 means don't even consider firing
// Units less likely to reaction fire if target at long range or out of full arc of fire. Lower quality troops more likely to shoot at the wrong moment.
FUNCTION REACT_Unit_Shoot(me, unit)
{
	int distance;
	int range;
	int damage ;
	int effectiveness ;
	int x;
	int y;
	int side;
	int volley;
	int priority_target;
	int reaction_chance;
	int quality;
	int percent;

	// Artillery and Ships don't reaction fire as such. (But they do get to use up their "reaction" shot in Housekeeping Shooting.)
	if ((IsArtillery(me) == 1) || (IsUnitSquadType(me, "Ship") == 1))
		{
			return -1;
		}

	effectiveness = -1 ;

	x = GetUnitX(me);
	y = GetUnitY(me);
	side = GetUnitSide(unit);

	// LOS is checked in the code
	// only react fire if hold fire is false or if it is adjacent
	if ((GetAttrib(me, "HoldFire") == 0) || (GetTileLOS(x,y,side) == 1))
		{
			if ((GetAttrib(me, "MoraleState") < 3)) // If not routed/destroyed
				{
					distance = GetDistanceBetween(me, unit);
					range = MaximumRange(me);
					volley = ArcOfFire(me, unit);

					// if in range and arc of fire
					if ((distance <= range) && (volley > 0))
						{
							effectiveness = CalculateShootingDamage(me, unit, volley, 1, 0, 1); // effectiveness takes into account range and arc of fire

							if (effectiveness > 0)
								{
									// Hold fire if there is another targetable priority target
									priority_target = PriorityChargeTarget(me, unit);
									if (unit != priority_target)
										{
											if (CallUnitFunctionDirect(me, "CHECK_UNIT_SHOOT", me, priority_target, GetUnitX(priority_target), GetUnitY(priority_target), 1, 1) >= 0)
												{
													effectiveness = -1;
												}
										}
									else
										{
											percent = 25; // May need tweaking
											quality = Max(percent, GetQuality(me)); // To prevent a /0 error, and reaction chance going above 100%
											reaction_chance = 100;
											if (volley != 3)
												{
													reaction_chance *= percent;
													reaction_chance /= quality;
												}
											if (IsLongRange(me, unit) == 1)
												{
													reaction_chance *= percent;
													reaction_chance /= quality;
												}
//                      Log ("reactor, enemy unit, reaction_chance", me, unit, reaction_chance);
											if (Rand(1,100) >= reaction_chance)
												{
													effectiveness = -1;
												}
										}
								}
							else
								{
									effectiveness = -1;
								}

						}
				}
		}

	return effectiveness;
}
Richard Bodley Scott

Image
CharlesdeBatz
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 53
Joined: Sun Jul 11, 2021 5:41 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by CharlesdeBatz »

I've already gone ahead and done that, but that seems to only yield the results I described above (that is, units only firing when fired upon by units directly in front, and even then that not occurring consistently). Are there any other functions governing how the AI determines its targets?
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28007
Joined: Sun Dec 04, 2005 6:25 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by rbodleyscott »

The following engine functions have an optional react parameter, which is set at 0 in FOG2.

SetRoute(id, x, y, [react]);
SetRouteReverse(id, x, y, [react]);

Where you want reaction to enemy movement to occur, that parameter needs to be 1.

NOTE: Don't set it to 1 in Assault.BSF, it is set to 0 there in Pike & Shot because it causes issues if charges are aborted by enemy reaction fire.
Richard Bodley Scott

Image
CharlesdeBatz
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 53
Joined: Sun Jul 11, 2021 5:41 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by CharlesdeBatz »

Thanks for the advice. I should be able to find every call to those functions using a command-line search in the script folders.

Additionally, you've previously mentioned that re-introducing reactive fire would require modifying the damage output by ranged units. As they currently calculate casualties for two volleys, would this be as straightforward as halving the casualty output from any ranged engagement calculation?
Last edited by CharlesdeBatz on Sun Dec 05, 2021 11:24 pm, edited 1 time in total.
CharlesdeBatz
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 53
Joined: Sun Jul 11, 2021 5:41 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by CharlesdeBatz »

So I could set every call to SetRoute or SetRouteReverse in Move.bsf and Fallback.bsf to have the last parameter as 1 instead of 0. I actually don't recall if P&S has reactive fire for fallbacks, or only for regular moves.

I'm also not sure if I should enable reactive fire for break-offs in CloseCombatLogic.bsf, as well as the standard moves defined in MoveCommandTools.bsf
CharlesdeBatz
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 53
Joined: Sun Jul 11, 2021 5:41 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by CharlesdeBatz »

So upon changing the react parameter to 1 in calls to SetRoute() and SetRouteReverse() in Fallback.bsf, MoveCommandTools.bsf, and Move.bsf, the following are my observations (using the Carrhae scenario, if that affects anything):

- none of my units fire at enemy units that come within range, although the enemy units fire at my units (Roman cavalry) when I move them into range of the horse archers

- the shooting is significantly less reactive than in P&S and SJ; in situations where 2 or 3 archer units are in range of a single cavalry unit, quite often only one of the archers shoots

- it seems that each unit only reactive fires once, and does not do so in subsequent turns

- it is very difficult to consistently get enemy units to return fire when fired upon

Do you have any insight on why that could be happening?
rbodleyscott
Field of Glory 2
Field of Glory 2
Posts: 28007
Joined: Sun Dec 04, 2005 6:25 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by rbodleyscott »

CharlesdeBatz wrote: Sun Dec 05, 2021 9:04 pm Thanks for the advice. I should be able to find every call to those functions using a command-line search in the script folders.

Additionally, you've previously mentioned that re-introducing reactive fire would require modifying the damage output by ranged units. As they currently calculate casualties for two volleys, would this be as straightforward as halving the casualty output from any ranged engagement calculation?
Sadly not.

The game does fire two separate volleys, keeps track of all first and second volley casualties, and takes separate cohesion tests for the accumulated casualties for each of the two volleys (but a maximum of 1 per shooting unit per turn). It is complicated. Untangling that is going to be even harder than resurrecting reaction fire, and making cohesion tests work correctly for reaction fire likewise.

So even if you manage to make reaction fire appear to work correctly, you then still have all the complex cohesion stuff to figure out.

Unfortunately the changes to remove reactive fire were not designed with ease of reversibility in mind. Together with the other issues, it has become clear that resurrecting reaction fire in FOG2 would be a lot more complex than it might at first seem.

I could no doubt, with some difficulty, do it myself if I deemed it necessary for the game (which I don't), but it would take a considerable amount of time to do so.

If there was a simple fix, I would of course share it. But unfortunately there isn't, and I cannot justify the time it would take me to figure it all out for someone else's mod.

Sorry.
Richard Bodley Scott

Image
CharlesdeBatz
Corporal - Strongpoint
Corporal - Strongpoint
Posts: 53
Joined: Sun Jul 11, 2021 5:41 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by CharlesdeBatz »

I see. I suspected that was the case, both from previous explanations of the mechanisms and my own tests. When I continued to test this on the Carrhae scenario (as that has an abundance of ranged units), my Roman cavalry were cut to pieces in short order (that is, even for the historical battle).
pipfromslitherine
Site Admin
Site Admin
Posts: 9700
Joined: Wed Mar 23, 2005 10:35 pm

Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)

Post by pipfromslitherine »

CharlesdeBatz wrote: Sun Dec 05, 2021 9:04 pm Thanks for the advice. I should be able to find every call to those functions using a command-line search in the script folders.

Additionally, you've previously mentioned that re-introducing reactive fire would require modifying the damage output by ranged units. As they currently calculate casualties for two volleys, would this be as straightforward as halving the casualty output from any ranged engagement calculation?
As a note, when searching the game files, use Notepad++:

http://gamewiki.slitherine.com/doku.php ... ne#notepad

And Find in Files.

Cheers

Pip
follow me on Twitter here
Post Reply

Return to “Field of Glory II: Modding”