Aller au contenu

Photo

Flank script


  • Veuillez vous connecter pour répondre
Aucune réponse à ce sujet

#1
mogromon

mogromon
  • Members
  • 41 messages
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;
}