Forged Alliance Forever Forged Alliance Forever Forums 2014-09-09T16:58:33+02:00 /feed.php?f=41&t=8462 2014-09-09T15:10:02+02:00 2014-09-09T15:10:02+02:00 /viewtopic.php?t=8462&p=80288#p80288 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
Maybe we can close this thread since it is not related to GetEnemyUnitsInSphere function anymore.

In conclusion:
GetEnemyUnitsInSphere is correctly reporting units within a sphere (it is using an infinite value for Y axis) but its implementation is lacking a check on reported unit to verify if it is an enemy and not an ally.

Thanks

Statistics: Posted by Nono06 — 09 Sep 2014, 15:10


]]>
2014-09-09T13:28:17+02:00 2014-09-09T13:28:17+02:00 /viewtopic.php?t=8462&p=80276#p80276 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]> Statistics: Posted by Deering — 09 Sep 2014, 13:28


]]>
2014-09-09T00:08:47+02:00 2014-09-09T00:08:47+02:00 /viewtopic.php?t=8462&p=80253#p80253 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]> I made the changes and now it is going through the same functions as land units and it has no effect.
Weapon:SetTargetEntity(target) does not affect the weapon. The plane is still targeting the wrong ground units (the ones that are not targeted by SetTargetEntity)
:(

Statistics: Posted by Nono06 — 09 Sep 2014, 00:08


]]>
2014-09-09T16:58:33+02:00 2014-09-08T15:50:48+02:00 /viewtopic.php?t=8462&p=80236#p80236 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
the other Thread was " OnGotTarget":
Code:
   OnGotTarget = function(self, Weapon)
      prevUnit.OnGotTarget(self, Weapon)
      if self:IsUnitState("Attacking") then
         self:SetCanSwitchTarget(false)
      end
   end,


Ground units (at least the one I tested) do not enter "Attacking" state unless the user gives the order to attack a unit.
When they are moving and detecting units around (OnGotTarget) their state is something different than "Attacking". (I'm currently thinking of one case I have not tested that may differ... I have to try this evening :) )

For planes, it seems different. When they reach the destination, they detect the enemies around but their state is switching to "Attacking" unlike ground units. Therefore, by setting CanSwitchTarget to false I'm not evaluating the enemy in Sphere within the weapon thread.

The goal is to insure when the user gives the order for a unit to attack another one that it will not lose its focus even if a "Red" (very high) or an "Orange" (high) priority is in range. That is why I would like to identify the last order given to that unit.

I can call the priority evaluation function when entering OnGotTartget but I think we will have a glitch for the first weapon salvo.

Ps: I still do not understand how CAiBrain.GetUnitsAroundPoint works since LUADOC do not list any parameter :)

Statistics: Posted by Nono06 — 08 Sep 2014, 15:50


]]>
2014-09-08T11:57:40+02:00 2014-09-08T11:57:40+02:00 /viewtopic.php?t=8462&p=80225#p80225 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
Nono06 wrote:
You are also referring to C-code that could be addressed directly. Is that already available in FAF?


Yes I'm referring to the CAiBrain.GetUnitsAroundPoint function that IceDreamer mentioned.

Nono06 wrote:
The issue I'm seeing is coming from another thread which prevents enemy to be detected.

Is there an easy way to know what was the last order a user gave to a unit? Moving, attacking, repair...
IsUnitState() return the current state but it is not necessarily an order provided by the user and I do not know how to use GetCommandQueue() function correctly.


Afaik there is no easy way. But what eactly is it you want to do? And what issue from what thread is this? :)

Statistics: Posted by Sheeo — 08 Sep 2014, 11:57


]]>
2014-09-08T11:17:11+02:00 2014-09-08T11:17:11+02:00 /viewtopic.php?t=8462&p=80224#p80224 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
you were right, GetEnemyUnitsInSphere is working correctly and reports all units independently of their layer.
The only issue is that it is not reporting enemy units only. Domino fixed that in his DMS library mod.

The issue I'm seeing is coming from another thread which prevents enemy to be detected.

Is there an easy way to know what was the last order a user gave to a unit? Moving, attacking, repair...
IsUnitState() return the current state but it is not necessarily an order provided by the user and I do not know how to use GetCommandQueue() function correctly.

Thanks

Statistics: Posted by Nono06 — 08 Sep 2014, 11:17


]]>
2014-09-04T13:52:08+02:00 2014-09-04T13:52:08+02:00 /viewtopic.php?t=8462&p=80058#p80058 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
But I just noticed that Domino redefined the function in his DMS part. (The mod was originally created by him but it was not working well, at least for me)
And he included the check for Enemy Army.

The discussion thread and source are here:
viewtopic.php?f=2&t=5866&start=90

Code:
function GetUnitsInSphere(position, radius)
   local x1 = position.x - radius
   local y1 = position.y - radius
   local z1 = position.z - radius
   local x2 = position.x + radius
   local y2 = position.y + radius
   local z2 = position.z + radius
   local UnitsinRec = GetUnitsInRect( Rect(x1, z1, x2, z2) )

   if not UnitsinRec then
      return false
   end
   local RetEntities = {}
    for k, v in UnitsinRec do
      local dist = VDist3(position, v:GetPosition())
      if dist <= radius then
         table.insert(RetEntities, v)
      end
   end

   return RetEntities
end

function GetEnemyUnitsInSphere(army, position, radius)
   local UnitsinRec = GetUnitsInSphere(position, radius)
   
   army = army or GetFocusArmy()
   
   if not UnitsinRec then
      return false
   end
   
   local RetEntities = {}
   
   if army then
      for k, v in UnitsinRec do
         local dist = VDist3(position, v:GetPosition())
         if IsEnemy(v:GetArmy(), army) and dist <= radius then
            table.insert(RetEntities, v)
         end
      end
   end

   return RetEntities
end


But the GetUnitsInSphere function is using the same structure as the default GetEnemyUnitsInSphere.
Since it is working on your side, I guess I have to re-test it.

You are also referring to C-code that could be addressed directly. Is that already available in FAF?

Thanks

Statistics: Posted by Nono06 — 04 Sep 2014, 13:52


]]>
2014-09-04T11:55:08+02:00 2014-09-04T11:55:08+02:00 /viewtopic.php?t=8462&p=80052#p80052 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
The function is defined in the global namespace, so using 'self' for the first argument would be confusing, since it's not attached to a class. Unit (the first argument) is only used to check if the units returned are in a different army than the given unit, it may as well be a number.

That logic is actually flawed as well, since a different army may well be an allied army.. It should be using the appropriate IsEnemy function :)

Since this whole functionality is duplicated engine side, I suggest we try and remove it to see what code actually uses it. We should then replace all calls in faf-code with the C-version, and update this to produce a deprecation warning the first time it's called.

Statistics: Posted by Sheeo — 04 Sep 2014, 11:55


]]>
2014-09-04T11:46:54+02:00 2014-09-04T11:46:54+02:00 /viewtopic.php?t=8462&p=80051#p80051 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
Also, shouldn't the 'Unit' argument just be 'self'? That would tie up with every other place I've seen similar code, if it is wanting the unit doing the check for other units (self), the position of the centre of the sphere (The position of unit, in this case self), and the radius of the sphere...

Statistics: Posted by IceDreamer — 04 Sep 2014, 11:46


]]>
2014-09-04T11:23:47+02:00 2014-09-04T11:23:47+02:00 /viewtopic.php?t=8462&p=80049#p80049 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
Nono06 wrote:
Code:
         local EnemyUnits = GetEnemyUnitsInSphere(self:GetArmy(), self:GetPosition(), 128)



This shouldn't work at all. GetEnemyUnitsInSphere(unit, position, radius) expects unit to be a table with function GetArmy() (I.e. an entity), not a number.

Nono06 wrote:
If the priority unit is a land unit and a bomber is flying above that unit, the GetEnemyUnitsInSphere func is not reporting it unless the plane starts its landing approach.


I would like a replay showing this behavior, as I can't reproduce it myself.

Nono06 wrote:
I'm not exactly sure how X, Y, Z axis are used in FA but usually Y represents the height and I find strange that it is not used anywhere.


The coordinate system in FA is indeed a normal cartesian coordinate system. It's not passed to the GetEntitiesInRect function, but it's relatively safe to assume (and my testing showed) that this function returns units from then entire y-axis, seemingly the implementor of this function also had this assumption. In your words the rectangle being infinite in the y-axis.

I still don't think using CAIBrain is going to fix anything, but I'll reiterate that it should be more efficient.

Statistics: Posted by Sheeo — 04 Sep 2014, 11:23


]]>
2014-09-04T10:44:10+02:00 2014-09-04T10:44:10+02:00 /viewtopic.php?t=8462&p=80047#p80047 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
Thanks for the reply.
I know LUADOC page but we cannot really say it is a documentation since the functions are not explained :)

I thought that all CaiBrain functions were available only when playing with AI.
Good to know that we can use it anywhere.
What is the "coverage" of GetUnitsAroundPoint()? Is that covering the whole map?

Regarding GetEnemyUnitsInSphere. We are using it in a thread running on the opponent "priority" unit:
Code:
      while not self:IsDead() and self:HasGlobalPriority() do
         local EnemyUnits = GetEnemyUnitsInSphere(self:GetArmy(), self:GetPosition(), 128)
         local GlobalPriority = self:GetGlobalPriority()
         
         if EnemyUnits and table.getn(EnemyUnits) > 0 then
            for j,k in EnemyUnits do
               if not k:IsPriorityTarget(GlobalPriority, self) then
                  local distance = GetDistanceBetweenTwoEntities(self, k)
                  if (distance <= k:GetMaxPriorityRange()) then
                     k:AddPriorityTarget(GlobalPriority, self)
                  end
               end
            end
         end
         WaitSeconds(1)
      end

If the priority unit is a land unit and a bomber is flying above that unit, the GetEnemyUnitsInSphere func is not reporting it unless the plane starts its landing approach.
I'm not exactly sure how X, Y, Z axis are used in FA but usually Y represents the height and I find strange that it is not used anywhere.
Does GetUnitsInRect actually represents a rectangular parallelepipedal? since Y axis is not present it does not seem to be the case except if the function consider the coordinates infinite on that axis.

Thanks

Statistics: Posted by Nono06 — 04 Sep 2014, 10:44


]]>
2014-09-04T03:15:16+02:00 2014-09-04T03:15:16+02:00 /viewtopic.php?t=8462&p=80038#p80038 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
Looking at the definition of GetEnemyUnitsInSphere in /lua/utilities.lua:

Code:
function GetEnemyUnitsInSphere(unit, position, radius)
   local x1 = position.x - radius
   local y1 = position.y - radius
   local z1 = position.z - radius
   local x2 = position.x + radius
   local y2 = position.y + radius
   local z2 = position.z + radius
   local UnitsinRec = GetUnitsInRect( Rect(x1, z1, x2, z2) )
   #Check for empty rectangle
   if not UnitsinRec then
      return UnitsinRec
   end
   local RadEntities = {}
    for k, v in UnitsinRec do
      local dist = VDist3(position, v:GetPosition())
      if (unit:GetArmy() != v:GetArmy()) and (dist <= radius) then
         table.insert(RadEntities, v)
      end
   end
   return RadEntities
end


You see that it is indeed using GetUnitsInRect, but it does correct distance pruning to only return units within the given spherical radius.

From my testing, GetUnitsInRect works and using this function should work fine, but using CAiBrain:GetUnitsAroundPoint() is likely more efficient.

Statistics: Posted by Sheeo — 04 Sep 2014, 03:15


]]>
2014-09-03T23:46:50+02:00 2014-09-03T23:46:50+02:00 /viewtopic.php?t=8462&p=80030#p80030 <![CDATA[Re: GetEnemyUnitsInSphere func not reporting units in a sphe]]>
This is an excellent resource
http://supcom.wikia.com/wiki/LUADOC_1.5.3599

Statistics: Posted by IceDreamer — 03 Sep 2014, 23:46


]]>
2014-09-03T21:27:08+02:00 2014-09-03T21:27:08+02:00 /viewtopic.php?t=8462&p=80025#p80025 <![CDATA[GetEnemyUnitsInSphere func not reporting units in a sphere?]]>
In priority markers mod, we are using the "GetEnemyUnitsInSphere" function to list the enemy around the units. But based on my trials and on how GetEnemyUnitsInSphere is coded, it seems that enemies that are not on the same layer, are not reported.
When looking closer to the function, we see that Y axis is not used therefore only a rectangle is used and not a sphere/cube.

Does someone know how to fix it?
Is there another function doing the same thing?
How a bomber detects units on the ground for example?

Thanks

Statistics: Posted by Nono06 — 03 Sep 2014, 21:27


]]>