Page 1 of 2

GetUnitLOSToUnit and GetTileLOS Functions

Posted: Thu Dec 08, 2022 8:36 pm
by CharlesdeBatz
Where can the above two functions be found in the game files? I have searched in the Battle/Scripts folder, the Data/scripts folder, and the Core and Core/AI folders without success.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Thu Dec 08, 2022 10:25 pm
by pipfromslitherine
They are intrinsic functions, executed in the engine. You can see them all in the BATTLESCRIPT.TXT file in Documents/My Games/FieldOfGlory2/AUTODOCS.

Cheers

Pip

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 09, 2022 2:58 am
by CharlesdeBatz
What I am trying to do is to modify LOS such that each side cannot see behind the opposing front line until units pass beyond it; the code I have modified is below.

Is this along the lines of what should be done to achieve this effect?

// Returns 1 if unit is hidden from enemy, 0 if not. (Not valid during StartTurn functions).
FUNCTION IsUnitHidden(me)
{
int ret;

ret = 1;
// add condition that checks if at least one unit on the current side has LOS to the target
if ((GetTileLOS(GetUnitX(me), GetUnitY(me), GetEnemySide(me)) == 1) && (CheckLOSForAllEnemyUnits(me) == 0))
{
ret = 0;
}

return ret;
}

FUNCTION CheckLOSForAllEnemyUnits(me)
{
mySide = GetUnitSide(me);
enemySide = GetEnemySide(me);
total = GetUnitCount(enemySide);
blocked_LOS = 1; // defaults to blocked LOS
for (i=0; i<total; i++)
{
id = GetUnitID(k, i);
if (UnitBlockingLOS(id,me) != 1)
{
blocked_LOS = 0;
return blocked_LOS;
}

return blocked_LOS;

}

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 09, 2022 2:44 pm
by CharlesdeBatz
Essentially, my focus is on the function that determines whether units are hidden; in addition to the check for tile LOS, I have introduced a new function that utilizes existing functions to determine if at least one friendly unit has LOS to the referenced enemy unit. But I am unsure if that is the correct approach.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 09, 2022 4:37 pm
by rbodleyscott
CharlesdeBatz wrote: Fri Dec 09, 2022 2:44 pm Essentially, my focus is on the function that determines whether units are hidden; in addition to the check for tile LOS, I have introduced a new function that utilizes existing functions to determine if at least one friendly unit has LOS to the referenced enemy unit. But I am unsure if that is the correct approach.
It sounds correct. Does it appear to work?

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 09, 2022 5:44 pm
by CharlesdeBatz
It doesn't appear to be working properly (although I did find a mistake in that the reference to k in CheckLOSForAllEnemyUnits should actually be a reference to enemySide in order to locate each unit in the enemy unit array). Enemy units behind the front lines are still visible to me as the player.

As far as I understand, the UnitBlockingLOS function uses an optimal route to determine if the unit in question has LOS to its target; is this correct?

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 09, 2022 5:49 pm
by CharlesdeBatz
I suppose an alternative method could be used that would involve dynamically moving the LOS boundary as the enemy line advances in order to hide units behind the line, but since the LOS calculation is done internally within the engine that would be significantly more complex.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Sat Dec 10, 2022 6:45 am
by rbodleyscott
Your main problem is that the engine functions GetUnitLOStoUnit and GetTileLOS take no account of intervening troops, only terrain features.

So you would essentially have to block out everything then check each tile using the script function UnitBlockingLOS(). This tries a couple of alternate "best" routes to ensure that a unit does not block LOS just because the engine route-finding algorithm happens to go through it when there is an equally plausible alternative route.

Doing this for every tile or every unit would probably have an adverse effect on performance, since script functions are far less efficient than engine functions.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Sat Dec 10, 2022 6:21 pm
by CharlesdeBatz
I see, so the fundamental issue would be that the engine functions only refer to the map (which is static during each battle) as opposed to also examining units (which can change their positions). I believe that I have already observed some performance drop when using the modified functions in Tools.bsf, although as stated previously the intended effect is still not being achieved.

Another alternative I thought of would be to simply decrease the LOS distance, although this would then mean that each army might not be able to see any of the opposing force. And any attempts to have the LOS distance vary (i.e. LOS = min(normal LOS distance, distance between my line and the enemy line)) would depend on constantly referencing the positions of units on the battlefield, which has the issues described above.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Tue Dec 13, 2022 6:53 am
by Schweetness101
CharlesdeBatz wrote: Fri Dec 09, 2022 2:58 am What I am trying to do is to modify LOS such that each side cannot see behind the opposing front line until units pass beyond it; the code I have modified is below.

...
I tried something similar before with not being able to see through enemy units to enemies behind them, and technically accomplished part of it (the fog changes), but it dropped performance to like 3 frames per second:
https://www.slitherine.com/forum/viewto ... 26#p938826
you could maybe try something like setting los or visibility or whatever on a unit based on it's grid position? dunno...

Something much simpler is to just lower the LOS total such that you aren't likely to see them until they've passed a certain point. Or by front line do you mean unit positions and not a specific grid line on the map?

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Thu Dec 15, 2022 1:40 pm
by Cronos09
As it turned out it was not difficult to make the dynamic LoS for a game with advancing a player' units vs static AI' units so the player could only see the first line of enemy units:

Beginning of turn 2
Image

End of turn 4
Image

But it is much difficult to change LoS when the AI/opponent's units are advancing in order to cover units behind the first line. I do not know how to bound the enemy units movement with decreasing of a player's unit LoS.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Tue Dec 20, 2022 6:12 pm
by Schweetness101
Cronos09 wrote: Thu Dec 15, 2022 1:40 pm As it turned out it was not difficult to make the dynamic LoS for a game with advancing a player' units vs static AI' units...
are you just setting line of sight off beyond a certain grid row?

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Wed Dec 21, 2022 3:51 pm
by Cronos09
Schweetness101 wrote: Tue Dec 20, 2022 6:12 pm
Cronos09 wrote: Thu Dec 15, 2022 1:40 pm As it turned out it was not difficult to make the dynamic LoS for a game with advancing a player' units vs static AI' units...
are you just setting line of sight off beyond a certain grid row?
No. I tried to make a dynamic LoS. I used FUNCTION DistanceToNearestEnemy(me, excludeFoot, excludeMounted, excludeLights) in StartTurnPost(side) and decreased LoS like AP in MoveCommandTools.BSF and Move.BSF.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Wed Dec 21, 2022 7:49 pm
by Schweetness101
Cronos09 wrote: Wed Dec 21, 2022 3:51 pm
Schweetness101 wrote: Tue Dec 20, 2022 6:12 pm
Cronos09 wrote: Thu Dec 15, 2022 1:40 pm As it turned out it was not difficult to make the dynamic LoS for a game with advancing a player' units vs static AI' units...
are you just setting line of sight off beyond a certain grid row?
No. I tried to make a dynamic LoS. I used FUNCTION DistanceToNearestEnemy(me, excludeFoot, excludeMounted, excludeLights) in StartTurnPost(side) and decreased LoS like AP in MoveCommandTools.BSF and Move.BSF.
oh k, so it's LOS is no further than the nearest enemy? this will prevent you from seeing through gaps in their line though? what does it look like if you move both sides more? or after engaging?

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Thu Dec 22, 2022 7:34 pm
by Cronos09
Schweetness101 wrote: Wed Dec 21, 2022 7:49 pm
Cronos09 wrote: Wed Dec 21, 2022 3:51 pm
Schweetness101 wrote: Tue Dec 20, 2022 6:12 pm

are you just setting line of sight off beyond a certain grid row?
No. I tried to make a dynamic LoS. I used FUNCTION DistanceToNearestEnemy(me, excludeFoot, excludeMounted, excludeLights) in StartTurnPost(side) and decreased LoS like AP in MoveCommandTools.BSF and Move.BSF.
oh k, so it's LOS is no further than the nearest enemy? this will prevent you from seeing through gaps in their line though? what does it look like if you move both sides more? or after engaging?
You can't see anything except the nearest enemy units (non-light). It's a line in my example because my units are lined up. I think 4-5 tiles are the permanent/not changed LoS.
I have a progress when the AI is changing the LoS of player's units:
End of a player's turn
Image

Start of the AI turn - the LoS is changed
Image

Then the AI units are coming from the fog
Image

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 23, 2022 3:36 am
by Schweetness101
Cronos09 wrote: Thu Dec 22, 2022 7:34 pm You can't see anything except the nearest enemy units (non-light)...
ok, what does that look like once you've started fighting or if the enemy is not in a line?

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Fri Dec 23, 2022 7:16 pm
by Cronos09
Schweetness101 wrote: Fri Dec 23, 2022 3:36 am
Cronos09 wrote: Thu Dec 22, 2022 7:34 pm You can't see anything except the nearest enemy units (non-light)...
ok, what does that look like once you've started fighting or if the enemy is not in a line?
I described it in my previous post. Use the code and see for yourself

Code: Select all

        for (j = 0; j < 2; j++)
			{
				for (i = 0; i < GetUnitCount(j); i++)
					{
						id = GetUnitID(j,i);
						if (id != -1)
							{
								v = DistanceToNearestEnemy(id, 0, 0, 1) * 10;
								if (v < 40)
									{
										v = 40;
									}
								SetAttrib(id, "LOS", v);
							}		
					}
			}	

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Sat Dec 24, 2022 5:03 am
by Schweetness101
Cronos09 wrote: Fri Dec 23, 2022 7:16 pm I described it in my previous post. Use the code and see for yourself
...
ok it just sets it to the LOS of each unit to the distance to the nearest enemy (but at least 40). Are you finding this has generally desirable results? It seems like it would sort of work if the enemy is in a line, but doesn't make that much sense if you can't see past one lone unit nearest to you (like in your screenshots it seems you should be able to see past the units with spaces between them). It might also give a very long line of sight if the nearest enemy is very far away?

I was thinking if you already implemented this in a mod you could post some more screens to see the results? Like what effect does this end up having by mid battle? I don't really want to add a new mod or edit an existing one to look at this one thing if you already did it lol.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Thu Jan 05, 2023 12:44 pm
by CharlesdeBatz
Schweetness101 wrote: Tue Dec 13, 2022 6:53 am Something much simpler is to just lower the LOS total such that you aren't likely to see them until they've passed a certain point. Or by front line do you mean unit positions and not a specific grid line on the map?
Yes, I am referring to the unit positions. My idea is that if a non-uniform formation is used (such as a reinforced flank, as at Leuctra), this should not be visible to the other side if a solid line is maintained. A variety of historical battles undoubtedly were affected by the inability of one or both of the opposing sides to determine the complete enemy formation based on the ground-level view available.

For instance, at Pharsalus, the ability of Caesar's fourth line to surprise the Pompeian cavalry was dependent on their being screened by the Caesarian cavalry prior to the counterattack; if Pompey had access to the "aerial" view present in-game, his battle plan would likely have changed to account for the fourth line.

Re: GetUnitLOSToUnit and GetTileLOS Functions

Posted: Thu Jan 05, 2023 10:09 pm
by Schweetness101
CharlesdeBatz wrote: Thu Jan 05, 2023 12:44 pm Yes, I am referring to the unit positions. My idea is that if a non-uniform formation is used (such as a reinforced flank, as at Leuctra), this should not be visible to the other side if a solid line is maintained....
Right, I understand why you would do it. My question is more about how well this specific implementation actually works in a game where both sides are moving/fighting for awhile. IE, this question:
It seems like it would sort of work if the enemy is in a line, but doesn't make that much sense if you can't see past one lone unit nearest to you (like in your screenshots it seems you should be able to see past the units with spaces between them). It might also give a very long line of sight if the nearest enemy is very far away?