Ryan Smith on 13/5/2016 at 21:30
Quote Posted by Random_Taffer
In the TDP training mission, they indicate that if the point of your sword is to the right of the target, you'll attack from the right and if it's to the left, your swing comes from the left side.
From a technical standpoint, how does it work? I'm thinking it could be done through line-of-vision. Because the target could be directly in the center and be too far away for the right swing to trigger. It only triggers in close proximity to the player.
It may even be determined through the target's relative position to the player.
Daraan on 13/5/2016 at 21:38
Short: LeftSwing if no Target
This is the script Part:
ObjID target; // what we're swinging at
int cur_swing_type; // what kind of swing are we powering to? [return value
Code:
void FindTargetAndInfo(ObjID owner, ObjID *target, int *swing_type)
{
mxs_vector owner_loc;
mxs_matrix orien;
owner_loc = ObjPosGet(owner)->loc.vec;
mx_ang2mat(&orien, &ObjPosGet(owner)->fac);
//@TODO: Use prox system for this!
AutoAppIPtr_(AIManager, pAIMan);
IAI *pAI;
tAIIter iter;
mxs_vector ai_loc;
mxs_real dist;
mxs_vector ai_offset;
IAI *pBestAI = NULL;
mxs_real best_value;
mxs_vector best_offset;
pAI = pAIMan->GetFirst(&iter);
while (pAI)
{
ai_loc = ObjPosGet(((cAI *)pAI)->GetState()->GetID())->loc.vec;
mx_sub_vec(&ai_offset, &ai_loc, &owner_loc);
dist = mx_mag_vec(&ai_offset);
if (dist < TARG_MAX_DIST)
{
mxs_real offset_proj;
mxs_real value;
// the value is the distance, plus the difference between the offset
// vector and the offset vector's projection onto our facing. So you
// get a low score if you're both close and in-line with our facing.
// low scores are good. offset_proj = mx_dot_vec(&orien.vec[0], &ai_offset);
if (offset_proj > 0)
{
value = dist + (offset_proj - dist);
if ((pBestAI == NULL) || (value < best_value))
{
SafeRelease(pBestAI);
pBestAI = pAI;
pBestAI->AddRef();
best_value = value;
best_offset = ai_offset;
}
}
}
pAI->Release();
pAI = pAIMan->GetNext(&iter);
}
pAIMan->GetDone(&iter);
if (pBestAI == NULL)
{
*target = OBJ_NULL;
*swing_type = kPlayerSwordActionSwingMediumLeft;
}
else
{
*target = ((cAI *)pBestAI)->GetState()->GetID();
pBestAI->Release();
// determine if it's the to the left or right of our facing
if (mx_dot_vec(&best_offset, &orien.vec[1]) < 0)
{
*swing_type = kPlayerSwordActionSwingMediumLeft; }
else
{
// *swing_type = kPlayerSwordActionSwingMediumLeft;
*swing_type = kPlayerSwordActionSwingMediumRight; }
}
}
What we can see is that if there is no target a left swing is performed.
Seems pretty much angle based with the player facing and makes sure that the(best)AI is in range to be even be able to perform a right swing.
-----
Need to figure out what (mx_dot_vec(&best_offset, &orien.vec[1])<0 is
mx_dot_vec -> Matrix Dot Vector multiplication 3x1 x 1x3 (what is this ahh let's see whats the name in english dot product..... well....
Ok dot product < 0
dot product = 0 => 90° angle
<0 => left side, wow left swing.
Everything else is based on the facing and the AI position/OffsetVector. Just not sure why they use orien.vec[1]. It's the UpDownVecor Pitch vector or not?
// Create an orientation matrix from an angvec, using traditional
// order of bank around x, pitch around y, heading around z,
// all using the right hand rule