Page 1 of 1

modding pursuit

Posted: Mon Jan 09, 2023 1:38 pm
by companion

Code: Select all

FUNCTION WillUnitPursue(me, enemy, type)

...

if (type > 0)
		{
			stopchance = 50;

			// Foot normally don't pursue mounted
			if ((IsFoot(me) == 1) && (IsMounted(enemy) == 1))
				{
					stopChance = 80;
				}

			// Cavaliers tend to keep pursuing
			//modded
			if ((IsMounted (me) == 1) && (GetAttribArray(me, "MoraleDamageFromShooting", GetCurrentSide()) > 0))
				{
					stopChance = 100;
			
					if ((IsUnitSquadType(me, "Cavaliers") == 1) && (GetAttribArray(me, "MoraleDamageFromShooting", GetCurrentSide()) == 0))
						{
							stopChance = 25;
						}

...

I wanted to make cavalries to stop pursuing when they receive some amount of ranged damage (exact amount to be decided later).
Above code using "MoraleDamageFromShooting" does not crash the game but does not work either.
I tried using "CalculateShootingDamage" but couldn't figure out how to return damages done to "me" rather than "target."
I then, in order to get some ideas, tried to find out the code that makes units to stop moving when they receive reactive fire but couldn't find it.

Any help is appreciated.

Re: modding pursuit

Posted: Tue Jan 10, 2023 6:30 pm
by Cronos09
companion wrote: Mon Jan 09, 2023 1:38 pm I then, in order to get some ideas, tried to find out the code that makes units to stop moving when they receive reactive fire but couldn't find it.
I think this is hidden in the game engine like in this command SetRoute(id, x, y, [react]). We also have FUNCTION REACT_Unit_Shoot(me, unit) in P&S, but there is nothing there according with unit moving.

In my opinion you have a discrepancy in your code:
(GetAttribArray(me, "MoraleDamageFromShooting", GetCurrentSide()) == 0) condition inside (GetAttribArray(me, "MoraleDamageFromShooting", GetCurrentSide()) > 0)
Try to separate them somehow and test then.

Re: modding pursuit

Posted: Sat Feb 11, 2023 6:57 pm
by Cronos09
I decided to get the result of this pursuing situation. "MoraleDamageFromShooting" and "CalculateShootingDamage" do not work in FUNCTION WillUnitPursue(me, enemy, type). Thus I added the extra Attrib "ShotAway":
1) in Init.BSF I added

Code: Select all

	AddAttrib("ShotAway");
	SetAttrib(me, "ShotAway", 0);	
2) in StartTurn.BSF I added at the end of FUNCTION StartTurnMoraleUpdate(me, lastTurnShootingDamage)

Code: Select all

	SetAttrib(me, "ShotAway", 0);
3) in CombatTools.BSF I added at the end of FUNCTION TurnAndFire(me, x, y, unit, volley)

Code: Select all

	if (IsUnitSquadType(unit, "Cavaliers") == 1)
		{
			SetAttrib(unit, "ShotAway", 1);
		}		
4) in FUNCTION WillUnitPursue(me, enemy, type)

Code: Select all

			// Cavaliers tend to keep pursuing
			if (IsUnitSquadType(me, "Cavaliers") == 1)
				{
					if(GetAttrib(me, "ShotAway") == 1)
						{
							stopChance = 100;
						}
					else
						{
							stopChance = 25;
						}
				}
Update 12.02.2023. It's better to reset the attribute at the end of FUNCTION StartTurnMoraleUpdate(me, lastTurnShootingDamage) (StartTurn.BSF) than in FUNCTION TurnAndFire(me, x, y, unit, volley)

Code: Select all

	SetAttrib(me, "ShotAway", 0);

Re: modding pursuit

Posted: Sun Feb 12, 2023 4:22 pm
by companion
Wow, much thanks. Devising such complex set of scripts was beyond my competencies.

To add some context, forced pursuit cancellation was a part of a scheme to simulate defeated cavalries reforming behind friendly infantry support.
Such behaviors - quick to retreat but also quick to reform - seem to grow more common as armours are discarded and average horsemanship, along with horse quality, degrades.

Re: modding pursuit

Posted: Tue Feb 14, 2023 7:37 pm
by Cronos09
companion wrote: Sun Feb 12, 2023 4:22 pm Wow, much thanks. Devising such complex set of scripts was beyond my competencies.

To add some context, forced pursuit cancellation was a part of a scheme to simulate defeated cavalries reforming behind friendly infantry support.
Such behaviors - quick to retreat but also quick to reform - seem to grow more common as armours are discarded and average horsemanship, along with horse quality, degrades.
The script attributes in the game are universal instrument for scripting various situations. They are used as simple triggers (0 or 1)/counters so weapon, armour, AP indicators. As you see they are very useful things.
I decided to complicate the script, so Cavaliers can leave an enemy unit arc of fire, i.e. they make one (or two in some situations) stage of pursuing after shooting at them. The complete script description:
1) in Init.BSF I added another Attrib

Code: Select all

	AddAttrib("Counter");
	SetAttrib(me, "Counter", 0);
	AddAttrib("TurnsPursuing");	

2) in CombatTools.BSF I added at the end of FUNCTION TurnAndFire(me, x, y, unit, volley)

Code: Select all

	if (IsUnitSquadType(unit, "Cavaliers") == 1)
		{
			SetAttrib(unit, "ShotAway", 1);
			SetAttrib(unit, "TurnsPursuing", 1);
		}	
3) in FUNCTION WillUnitPursue(me, enemy, type)

Code: Select all

			// Cavaliers tend to keep pursuing
			if (IsUnitSquadType(me, "Cavaliers") == 1)
				{
					if((GetAttrib(me, "ShotAway") == 1) && (GetAttrib(me, "TurnsPursuing") > 1))
						{
							stopChance = 100;
						}
					else
						{
							stopChance = 25;
						}
				}
4) in StartTurn.BSF I added in FUNCTION StartTurnMoraleUpdate(me, lastTurnShootingDamage)

Code: Select all

											if (WillUnitPursue(opponent, me, 1) == 1)
												{
													AddToREPQueue(me, opponent);
													SetAttrib(opponent,"AP",GetBaseAttrib(opponent,"AP"));
													if(GetAttrib(opponent, "TurnsPursuing") > 0) //modded
														{
															turns_pursuing = GetAttrib(opponent, "TurnsPursuing");
															if (turns_pursuing > 2) 
																{						
																	SetAttrib(opponent, "ShotAway", 0);
																	SetAttrib(opponent, "TurnsPursuing", 0);							
																}
															else
																{
																	turns_pursuing += 1;
																	SetAttrib(opponent, "TurnsPursuing", turns_pursuing);
																}
														}				//modded
												}
It seems to work, but it needs to test more time.
Update 15.02.2022. Item 4 is fixed. In the function header should be written int turns_pursuing;
Now it works fine. The main feature of the script - a Cavalier unit makes one stage of pursuing after an enemy unit has shot at it. Then it stops if there was not shot at it. If there was a shot at this Cavalier unit, it performes another stage of pursuing.

Re: modding pursuit

Posted: Wed Feb 15, 2023 9:32 am
by Cronos09
I tested the above script with logs on and in StartTurn.BSF I choose not correct unit - 'me' instead of 'opponent'. Thus this point should be next:

Code: Select all

											if (WillUnitPursue(opponent, me, 1) == 1)
												{
													AddToREPQueue(me, opponent);
													SetAttrib(opponent,"AP",GetBaseAttrib(opponent,"AP"));
													if(GetAttrib(opponent, "TurnsPursuing") > 0)	//modded
														{
															turns_pursuing = GetAttrib(opponent, "TurnsPursuing");
															if (turns_pursuing > 2) 
																{						
																	SetAttrib(opponent, "ShotAway", 0);
																	SetAttrib(opponent, "TurnsPursuing", 0);							
																}
															else
																{
																	turns_pursuing += 1;
																	SetAttrib(opponent, "TurnsPursuing", turns_pursuing);
																}
														}				//modded														
												}
Now it works fine. In the function header should be written int turns_pursuing;
PS. The main feature of the script - a Cavalier unit makes one stage of pursuing after an enemy unit has shot at it. Then it stops if there was not shot at it. If there was a shot at this Cavalier unit, it performes another stage of pursuing.