i found some work of Drammel at the project citadel and he had a Flank validation check but i felt it wasnt accurate enough, so started doing some tests and i did this script. What i need is some help and outsider eyes to find out things i haven't realized, and also to make it more efficient. I've no used nwn2 condition to flank (the creature is not attacking the one who gets the sneak attack) as it's not a PnP rule. IsFlankValid(object oPC, object oTarget, int bMelee = FALSE) is the starting point
float nDistAppearance(object oTarget, int sCheck = 1)
{
if(sCheck == 1)
{
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
if(!GetWeaponRanged(oWeapon) && GetIsObjectValid(oWeapon))
{
int nWeaponType = GetBaseItemType(oWeapon);
return StringToFloat(Get2DAString("baseitems", "PrefAttackDist", nWeaponType));
}
}
int nType = GetAppearanceType(oTarget);
string sColumn;
if(sCheck == 1)
sColumn = "PREFATCKDIST";
else if(sCheck == 0)
sColumn = "CREPERSPACE";
else
sColumn = "HITDIST";
if(nType == APPEARANCE_TYPE_INVALID)
return 0.0;
else
return StringToFloat(Get2DAString("appearance", sColumn, nType));
}
//determines if oFlanker is threatening oTarget's area
int IsValidFlanker(object oFlanker)
{
if(GetIsDead(oFlanker))
return FALSE;
if (GetHasEffect( EFFECT_TYPE_STUNNED, oFlanker)
|| GetHasEffect( EFFECT_TYPE_BLINDNESS, oFlanker)
|| GetHasEffect( EFFECT_TYPE_PARALYZE, oFlanker)
|| GetHasEffect( EFFECT_TYPE_SLEEP, oFlanker)
|| GetHasEffect( EFFECT_TYPE_PETRIFY, oFlanker)
|| GetHasEffect( EFFECT_TYPE_CUTSCENE_PARALYZE, oFlanker)
|| GetHasEffect( EFFECT_TYPE_CONFUSED, oFlanker)
|| GetHasEffect( EFFECT_TYPE_FRIGHTENED, oFlanker)
|| GetHasEffect( EFFECT_TYPE_DOMINATED, oFlanker)
|| GetHasEffect( EFFECT_TYPE_DAZED, oFlanker)
|| GetHasEffect( EFFECT_TYPE_TURNED, oFlanker)
|| GetHasEffect( EFFECT_TYPE_TURNED, oFlanker))//for ethereal creatures that shouldnt be able to attack non-ethereal
return FALSE;
return TRUE;
}
// Determines if the PC is flanking the target or not. Returns TRUE if they are.
int IsFlankValid(object oPC, object oTarget, int bMelee = FALSE)
{
object oFlanker;
//float FoeGirth = GetGirth(oTarget);
float fExtraDist = nDistAppearance(oTarget, 2);
float FoeGirth = nDistAppearance(oTarget, 0) + 0.2;
float FlankerGirth;
float fDistance;
float fMaxFlankDistance;
float fMinFlankDistance;
int nFlank = FALSE;
//int nNth = 1;
float oPCGirth;
oFlanker = GetFirstFactionMember(oPC);
//oFlanker = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oTarget, nNth);//didnt work as expected, nor as friend or enemy
if(GetSpellId() == 8033)//Glaive in Saralach spells.2da
oPCGirth = 2.25;
else
oPCGirth = nDistAppearance(oPC);//GetGirth(oPC, TRUE);
FlankerGirth = nDistAppearance(oFlanker);//GetGirth(oFlanker, TRUE);
fMaxFlankDistance = 0.4 + FlankerGirth + oPCGirth + fExtraDist*2;
fMinFlankDistance = FlankerGirth + fExtraDist + 0.5;//cant be further away
fDistance = GetDistanceBetween(oPC, oFlanker);
int nCheckPCOnly = TRUE;
int nAlliesCount = 0;//only checks 15 creatures (avoid doing too many cycles)
while (GetIsObjectValid(oFlanker) && bMelee && nAlliesCount <= 15)//So other spells avoid this (Only melee attacks get flank bonus and sneak)
{
if ((fDistance > FoeGirth) && (fDistance < fMaxFlankDistance) && (GetDistanceBetween(oFlanker, oTarget) < fMinFlankDistance) && (fDistance <= 10.5))//more than 10.5 meters is too far to flank
{
object oFoe = GetFirstObjectInShape(SHAPE_CONE, FoeGirth, GetLocation(oFlanker), FALSE, OBJECT_TYPE_CREATURE, GetPosition(oPC));
while(GetIsObjectValid(oFoe))
{
if(oFoe == oTarget && oFlanker != oTarget)
{
if(IsValidFlanker(oFlanker))
{
float fline = fDistance - GetDistanceBetween(oPC, oTarget);
float fline2 = GetDistanceBetween(oFlanker, oTarget) - 0.1;//This is a straight line (it's reduced so oPC doesnt have to be in a perfect line)
if(fline >= fline2)
{
nFlank = TRUE;
return nFlank;
}
}
}
oFoe = GetNextObjectInShape(SHAPE_CONE, FoeGirth, GetLocation(oFlanker), FALSE, OBJECT_TYPE_CREATURE, GetPosition(oPC));
}
}
if(nCheckPCOnly)
oFlanker = GetNextFactionMember(oPC);
else
oFlanker = GetNextFactionMember(oPC, FALSE);
if(!GetIsObjectValid(oFlanker) && nCheckPCOnly)//was checking PCOnly but didnt find a correct one
{
oFlanker = GetFirstFactionMember(oPC, FALSE);
nCheckPCOnly = FALSE;//wont check PCOnly any more
}
FlankerGirth = nDistAppearance(oFlanker);//GetGirth(oFlanker, TRUE);
fMaxFlankDistance = 0.4 + FlankerGirth + oPCGirth + fExtraDist*2;
fMinFlankDistance = FlankerGirth + fExtraDist + 0.5;
fDistance = GetDistanceBetween(oPC, oFlanker);
nAlliesCount = nAlliesCount + 1;
}
return nFlank;
}
Flank script
Débuté par
mogromon
, sept. 20 2011 04:52
#1
Posté 20 septembre 2011 - 04:52





Retour en haut






