Page 1 of 1
Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Fri Dec 03, 2021 6:22 am
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.
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Sat Dec 04, 2021 4:52 pm
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;
}
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Sat Dec 04, 2021 10:31 pm
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?
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Sun Dec 05, 2021 8:05 am
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.
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Sun Dec 05, 2021 9:04 pm
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?
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Sun Dec 05, 2021 11:18 pm
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
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Mon Dec 06, 2021 12:44 am
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?
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Mon Dec 06, 2021 7:28 am
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.
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Mon Dec 06, 2021 8:24 pm
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).
Re: Enabling reactive fire (both in player/AI move phases and by adding a residual shooting phase)
Posted: Mon Dec 06, 2021 9:12 pm
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