Voila le code permettant un jet de contact a distance selon les regles D&D (du moins j'ai essayé de les approcher au maximum, mais il y'a un manque dans les fonction Bioware de base pour que je puisse parfaire mon code...)
//:://///////////////////////////////////////////// //:: RangeTouchAttack and MissRangeAttack functions //:: raw_code_rta.nss //:: //::////////////////////////////////////////////// /* It simulates the range touch attack roll neccessary to use for some spell (ray, melf acid arrow...) And the second function simulates the original D&D system for the miss of a grenade-like weapon attack. */ //::////////////////////////////////////////////// //:: Created By: Dolanor //:: Created On: 21/05/2003 //:://////////////////////////////////////////////
#include "raw_code_getbab"
//void main(){}
//constantes int ATTACK_TYPE_SPELL = 1; int ATTACK_TYPE_GRENADE_LIKE= 2; //Jet d'attaque int n20 = d20();
int RangeTouchAttack(object oTarget, int bDisplayFeedback=TRUE) { //:: //Gestion de la classe d'armure de la cible //::
int nAC = 10 + GetAbilityModifier(ABILITY_DEXTERITY, oTarget); //On obtient les autres bonus de CA pris en compte par le jet.
//Gestion des bonus de moine (+1 a la CA tous les 5 niveaux et bonus de Sagesse comptabiliss dans la CA) int nClassMonk = GetLevelByClass(CLASS_TYPE_MONK, oTarget); if (nClassMonk >= 1) { nAC = nAC + GetAbilityModifier(ABILITY_WISDOM, oTarget) + (nClassMonk / 5); }
//Gestion des dons donnant des bonus de CA if (GetHasFeat(FEAT_DODGE, oTarget)) { nAC = nAC + 1; //Determine si le bonus d'esquive s'applique //Si il est en combat if (GetIsInCombat(oTarget)) { //Avec une cible differente du caster if(GetAttackTarget(oTarget) != OBJECT_SELF) { nAC = nAC - 1; } //Si il lance un sort sur une cible differente du caster
//------- //==A FAIRE //------- } } //Calcule le bonus/malus de la taille relative nAC = nAC + (GetCreatureSize(OBJECT_SELF) - GetCreatureSize(oTarget));
//Gestion des bonus lies aux objets
//------------- //==A FAIRE //-------------
//Gestion des bonus lies aux sort (buff)
//------------- //==A FAIRE //-------------
//:: //Gestion du jet de touche a distance //::
int nRangeTouchThrow = n20; //Bonus du BAB int nATKBonus = GetBAB(OBJECT_SELF); //Bonus de dexterite nATKBonus = nATKBonus + GetAbilityModifier(ABILITY_DEXTERITY, OBJECT_SELF); //Gestion du bonus de +1 a ce jet si la personne possede le don de tir a bout portant if (GetHasFeat(FEAT_POINT_BLANK_SHOT, OBJECT_SELF)) { if (GetDistanceBetween(OBJECT_SELF, oTarget) <= 10.0) { nATKBonus = nATKBonus + 1; } } //Gestion du malus de tir dans le tas si l'on n'a pas le don tir a bout portant else { //Verification si il y'a combat de melee if (GetDistanceBetween(oTarget, GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oTarget)) <= 2.2 && GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, oTarget) != OBJECT_SELF) { nATKBonus = nATKBonus - 4; }
} nRangeTouchThrow = nRangeTouchThrow + nATKBonus;
//Gestion des bonus lies aux objets
//------------- //==A FAIRE //-------------
//Gestion des bonus lies aux sort (buff)
//------------- //==A FAIRE //-------------
//Test de touche
//Critique string sErreur; if (n20 == 20) { int n20C = d20(); //Touche a tout les coups sErreur = "You execute a critical : (" + IntToString(n20) + " + " + IntToString(nATKBonus) + " = " + IntToString(n20 + nATKBonus) + " : Critical throw : " + IntToString(n20C) + " + " + IntToString(nATKBonus) + " = " + IntToString(n20C + nATKBonus) + ")"; if (n20C == 20) { if (bDisplayFeedback == TRUE) { SendMessageToPC(OBJECT_SELF, sErreur); } return 2; } //Critique normal if ((n20C + nATKBonus) >= nAC) { if (bDisplayFeedback == TRUE) { SendMessageToPC(OBJECT_SELF, sErreur); } return 2; }
if (bDisplayFeedback == TRUE) { sErreur = "You touch your target : (" + IntToString(n20) + " + " + IntToString(nATKBonus) + " = " + IntToString(n20 + nATKBonus) + " : Critical throw : " + IntToString(n20C) + " + " + IntToString(nATKBonus) + " = " + IntToString(n20C + nATKBonus) + ")"; SendMessageToPC(OBJECT_SELF, sErreur); } return 1; }
//Touche if (nRangeTouchThrow >= nAC) { if (bDisplayFeedback == TRUE) { sErreur = "You touch your target : (" + IntToString(n20) + " + " + IntToString(nATKBonus) + " = " + IntToString(n20 + nATKBonus) + ")"; SendMessageToPC(OBJECT_SELF,sErreur); } return 1; } //Loupe else { if (bDisplayFeedback == TRUE) { sErreur = "You miss your target : (" + IntToString(n20) + " + " + IntToString(nATKBonus) + " = " + IntToString(n20 + nATKBonus) + ")"; SendMessageToPC(OBJECT_SELF,sErreur); } return 0; } }
vector MissRangeTouchAttack(object oTarget , int nTypeAttack = 1) { //Calcul de la distance float fLength = ((20.0 -IntToFloat(n20)) / 20.0) * 6.0; 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; }
Ce code inclus aussi une fonction permettant de gerer visuellement un miss de cible en decalant l'effet par rapport a la cible originale. Mais il n'applique pas directement. Il renvoit juste le vecteur et il faut faire une petite bidouille pour que l'effet soit deplacé.
Le code contient les jets affichables ou non (avec le bDisplayFeedback ) grace a des SendMessageToPC
|