Bon, voila, apres plusieurs tests, mon script marche plutot pas mal et respecte la regle de D&D 3 concernant le raté d'attaque a distance de jeté de projectile :
Provient du Manuel du Joueur ( p 138 )
Si l'attaque rate, jouez 1d6 et multipliez le resultat par 30 cm pour savoir à quelle distance de la cible le projectile atterit. Ajoutez 30 cm par facteur de portée (autrement dit, exception faite de la pierre a tonnerre, +30 cm tous les 3 m de distance entre le personnage et la cible). Jetez ensuite 1d8 pour determiner dans quelle direction se produit l'impact par rapport a la cible :
8 1 2
7 ¤ 3
6 5 4
Légende : ¤ = cible de l'attaque.
C'est une fonction qui renvoie un vecteur qui se base sur la position de l'objet entré (oTarget) et qui décale le point d'impact selon les regles D&D.
Si l'option entrée est un ATTACK_TYPE_SPELL, alors c'est considéré comme un sort, et donc on ne tiens pas compte du facteur de portée qui rajoute 30 cm tous les 3m separant le caster de sa cible, car je considere que comme c'est une attaque magique (rayon, ...), ce n'est pas affecté par la pesanteur, et ce n'est pas parce que la distance est plus grande que le point d'impact doit etre plus eloigné.
De plus ca ajoute une valeur aleatoire de décalage de hauteur basé sur le meme genre de regles : entre 0 et 2,4 m par pallier de 20 cm.
Si l'option Entrée est un ATTACK_TYPE_GRENADE_LIKE, alors l'attaque est considéré comme un projectile a impact, donc comme c'est un projectile lancé manuellement, sans moyen magique, alors il est affecté par la pesanteur/mecanique, donc il subira les effet de facteur de portée, et comme il atterit forcément (pas comme un sort) alors son vecteur de decalage verticale vaut toujours 0
Maintenant voyons le code :
//constantes int ATTACK_TYPE_SPELL = 1; int ATTACK_TYPE_GRENADE_LIKE= 2;
vector MissRangeTouchAttack(object oTarget , int nTypeAttack = 1) { //Calcul de la distance float fLength = IntToFloat(d6()); fLength = fLength * 0.3; //Prise en compte si l'utilisation est pour une un projectile a impact //Rajoute 30 cm de decalage pour chaque 3 m separant le lanceur de sa cible if (nTypeAttack == ATTACK_TYPE_GRENADE_LIKE) { float fDistance = GetDistanceBetween(OBJECT_SELF, oTarget); int nDivision; //arrondi de la valeur nDivision = FloatToInt(fDistance / 3); fLength = fLength + IntToFloat(nDivision) * 0.3; } int nDirection = d8(); float fXValue = 0.0; float fYValue = 0.0; float fZValue = 0.0;
//Calcul de la hauteur aleatoire dans le cas d'un ATTACK_TYPE_SPELL if (nTypeAttack == ATTACK_TYPE_SPELL) { fZValue = IntToFloat(Random(6)) * 0.6; }
//Gestion de la direction du decalage switch(nDirection) { //Il vise au Nord de la cible case 1: fYValue = fLength; break; //Il vise au Nord Est de la cible case 2: fXValue = fLength / (1.41421); fYValue = fLength / (1.41421); break; //Il vise a l'Est de la cible case 3: fXValue = fLength; break; //Il vise au Sud Est de la cible case 4: fXValue = fLength / (1.41421); fYValue = -(fLength / (1.41421)); break; //Il vise au Sud de la cible case 5: fYValue = -fLength; break; //Il vise au Sud Ouest de la cible case 6: fXValue = -(fLength / (1.41421)); fYValue = -(fLength / (1.41421)); break; //Il vise a l'Ouest de la cible case 7: fXValue = -fLength; break; //Il vise au Nord Ouest de la cible case 8: fXValue = -(fLength / (1.41421)); fYValue = fLength / (1.41421); break; }
vector vRate = GetPosition(oTarget); vRate.x += fXValue; vRate.y += fYValue; vRate.z += fZValue; return vRate; }
Voila
|