Author Topic: Test if two PC's face each other  (Read 1121 times)

Legacy_JediMindTrix

  • Sr. Member
  • ****
  • Posts: 383
  • Karma: +0/-0
Test if two PC's face each other
« on: May 22, 2016, 12:40:42 pm »


               

Essentially, my goal is to test whether PC A is facing PC B's front. The test should return true if PC A is anywhere in 180 degree field in front of PC B, using a field of vision about as wide as your standard SHAPE_SPELLCONE, and false if they were anywhere 180 degree's behind PC B. As I have zero knowledge of geometry functions, I was hoping I could find some assistance here.


 


Any ideas on where to start?



               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Test if two PC's face each other
« Reply #1 on: May 22, 2016, 07:04:45 pm »


               

At what distances apart between PC's do you want this to operate at?



               
               

               
            

Legacy_JediMindTrix

  • Sr. Member
  • ****
  • Posts: 383
  • Karma: +0/-0
Test if two PC's face each other
« Reply #2 on: May 23, 2016, 01:55:29 am »


               

About 15 to 20 meters.



               
               

               
            

Legacy_JediMindTrix

  • Sr. Member
  • ****
  • Posts: 383
  • Karma: +0/-0
Test if two PC's face each other
« Reply #3 on: May 23, 2016, 09:13:14 am »


               

The issue I've run into is that using GetFirst/NextInShape(SHAPE_SPELLCONE) is that it is always OBJECT_SELF, which means from the same script it is impossible (unless we can somehow change what OBJECT_SELF is on the fly?) to check if two different PC's are facing each other.


 


Another route I explored was creating custom 'arcs', and WhiZard posted code that looks like this:



int GetIsTarget(object oGun, location lTarget, float fConeAngle = 10.0)
{
vector vDirection = GetPositionFromLocation(lTarget) - GetPosition(oGun);
float fFacing = GetFacing(oGun);
return (fabs(180.0 - fabs(VectorToAngle(-1.0 * vDirection) - fFacing))) <= fConeAngle/2;
}

Which comes in handy for brainstorming, but as far I see, the arc continues on infinitely, which we don't want. (Whereas SHAPE_SPELLCONE has an adjustable limit to how far it goes.)


 


Relevant Link:http://forum.bioware...n#entry18346094



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Test if two PC's face each other
« Reply #4 on: May 23, 2016, 02:20:37 pm »


               

Presumably, from your initial description of the problem, you know A and B so I would not mess with searching for objects in shapes. You have the two objects.



int GetIsFacingTarget(object oSelf, object oTarget, int nViewArc) {
        float fViewArc = IntToFloat(nViewArc);
        float AngleOffset = fabs(fabs(VectorToAngle(GetPosition(oSelf) - GetPosition(oTarget)) - GetFacing(oSelf)) - 180.0);
        return (AngleOffset <  fViewArc/2.0);
}

This routine will tell if oSelf is facing oTarget, with "facing" being defined by the given nViewArc.   A simple way to do what you want is to call this twice, switching the arguments, and then check the distance between your A and B. e.g.:



if ((GetDistanceBetween(A,B) <= 15.0) && GetIsFacingTarget(A,B) && GetIsFacingTarget(B,A)) {
      // Do stuff
}

There is certainly also a way to write a routine that did the work of both calls to GetIsFacingTarget at once, but I leave that as an exercise for the reader '<img'>


               
               

               
            

Legacy_JediMindTrix

  • Sr. Member
  • ****
  • Posts: 383
  • Karma: +0/-0
Test if two PC's face each other
« Reply #5 on: May 23, 2016, 03:15:38 pm »


               

Ooo! I like that code ^


 


Right, both PC's are already found in the script. The route I ended up going (before you responded) was a modified version of WhiZards above.



int jmtGetTargetFacingPC(object oPC, object oTarget, float FORWARD_ARC = 60.0)  //PC is the onlooker, Target is the onlooked, Arc is the Arc (value x2), default 120 degrees
{
float fTargetFacing = GetFacing(oTarget); //Get the direction oTarget is facing
location lPC = GetLocation(oPC); //Get oPC's Location
vector vDirection = GetPositionFromLocation(lPC) - GetPosition(oTarget);
return (fabs(180.0 - fabs(VectorToAngle(-1.0 * vDirection) - fTargetFacing))) <= FORWARD_ARC/2; // <--- all WhiZard, thanks again.                                                                                              //Returns True/False whether or not the object at lTarget is within it's field
}

This is called inside of a GetFirst/NextObjectInShape(SHAPE_SPELLCONE, 10, etc etc). The logic being that the SHAPE_SPELLCONE ensures that the script in the codebox above doesn't fire at all unless they are within 10 meters, and it just checks to make sure that PC A is within the correct arc to view PC b's front.


 


I was (and still am) pretty tired when I wrote that, so I may have bungled the orders of oTarget/oPC and/or be completely off-base with this route. Haven't had a chance to test it yet either. Let me know if you spot any errors in my logic?