//////////////////////////////////////////////////////////////////////////////// // cai_ranged - Combat AI - Ranged Attack // By Deva Bryson Winblood. 11/2004 //////////////////////////////////////////////////////////////////////////////// #include "cai_inc_hos" #include "nw_I0_generic" object fnGetBestTarget(int nRace) { // tell me who my best target is at the moment object oRet=OBJECT_INVALID; int nN; float fD; int nVal; object oOb; int nThis; int nC; nN=1; oOb=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,nN,CREATURE_TYPE_IS_ALIVE,TRUE,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); fD=GetDistanceBetween(oOb,OBJECT_SELF); while(oOb!=OBJECT_INVALID&&fD<30.0) { // check all nearby targets nThis=0; nN++; if (fD<20.0) nThis++; if (fD<15.0) nThis++; if (fD<10.0) nThis++; if (fD<8.0) nThis++; if (fD<5.0) nThis++; fD=IntToFloat(GetCurrentHitPoints(oOb))/IntToFloat(GetMaxHitPoints(oOb)); if (fD<0.51) nThis++; if (fD<0.31) nThis++; if (fD<0.11) nThis++; if (nRace==RACIAL_TYPE_UNDEAD) { // see if target is a cleric nC=GetClassByPosition(1,oOb); if (nC==CLASS_TYPE_CLERIC||nC==CLASS_TYPE_PALADIN||nC==CLASS_TYPE_DIVINECHAMPION||nC==CLASS_TYPE_BLACKGUARD) nThis=nThis+3; nC=GetClassByPosition(2,oOb); if (nC==CLASS_TYPE_CLERIC||nC==CLASS_TYPE_PALADIN||nC==CLASS_TYPE_DIVINECHAMPION||nC==CLASS_TYPE_BLACKGUARD) nThis=nThis+3; nC=GetClassByPosition(3,oOb); if (nC==CLASS_TYPE_CLERIC||nC==CLASS_TYPE_PALADIN||nC==CLASS_TYPE_DIVINECHAMPION||nC==CLASS_TYPE_BLACKGUARD) nThis=nThis+3; } // see if target is a cleric nC=caiGetEquippedWeaponType(oOb,INVENTORY_SLOT_RIGHTHAND); if (caiGetIsArcane(oOb)) nThis=nThis+2; if (nC==CAI_WEAPON_RANGED) nThis++; if (nThis>nVal) { // new best target oRet=oOb; nVal=nThis; } // new best target oOb=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,OBJECT_SELF,nN,CREATURE_TYPE_IS_ALIVE,TRUE,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); fD=GetDistanceBetween(oOb,OBJECT_SELF); } // check all nearby targets return oRet; } // tell me who my best target is at the moment void main() { object oMe=OBJECT_SELF; object oTarget=GetAttackTarget(); int nN; int nMyRace=GetRacialType(oMe); object oBest=fnGetBestTarget(nMyRace); int nWT=caiGetEquippedWeaponType(oMe,INVENTORY_SLOT_RIGHTHAND); int bTargetChanged=FALSE; float fF; object oOb=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oMe,1,CREATURE_TYPE_IS_ALIVE,TRUE,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN); if (GetIsObjectValid(oOb)) { // there are enemies near if (oBest!=oTarget) { // target change oTarget=oBest; bTargetChanged=TRUE; } // target change fF=GetDistanceBetween(oOb,oMe); if (GetHasFeat(FEAT_POINT_BLANK_SHOT,oMe)==FALSE) { // does not have point blank shot if(fF<4.1) { // too close - go to melee if (nWT==CAI_WEAPON_NONE||nWT==CAI_WEAPON_RANGED) { // equip a weapon AssignCommand(oMe,ActionEquipMostDamagingMelee(oTarget)); } // equip a weapon if (GetHasFeat(FEAT_TWO_WEAPON_FIGHTING,oMe)==TRUE) { // check to see if have a second weapon nN=caiGetEquippedWeaponType(oMe,INVENTORY_SLOT_LEFTHAND); if (nWT==CAI_WEAPON_NONE||nWT==CAI_WEAPON_RANGED) { // equip AssignCommand(oMe,ActionEquipMostDamagingMelee(oTarget,TRUE)); } // equip } // check to see if have a second weapon } // too close - go to melee else if (fF<10.1) { // too close - move away AssignCommand(oMe,ClearAllActions(TRUE)); AssignCommand(oMe,ActionMoveAwayFromObject(oOb,TRUE,15.0)); } // too close - move away else if (fF>22.0) { // get a little closer AssignCommand(oMe,ActionMoveToObject(oOb,TRUE,17.0)); } // get a little closer else { // far enough away - ranged if (nWT!=CAI_WEAPON_RANGED) { //equip a ranged weapon AssignCommand(oMe,ActionEquipMostDamagingRanged(oTarget)); } //equip a ranged weapon } // far enough away - ranged } // does not have point blank shot else { // point blank shot AI fF=GetDistanceBetween(oMe,oOb); if (fF<5.1&&oOb!=oTarget) { // move away from this other person AssignCommand(oMe,ActionMoveAwayFromObject(oOb,TRUE,8.0)); } // move away from this other person else { // deal with my target fF=GetDistanceBetween(oMe,oTarget); if (fF>7.0) { // move closer AssignCommand(oMe,ActionMoveToObject(oTarget,TRUE,5.0)); } // move closer else if (fF<3.1) { // melee if (nWT==CAI_WEAPON_NONE||nWT==CAI_WEAPON_RANGED) { // equip a weapon AssignCommand(oMe,ActionEquipMostDamagingMelee(oTarget)); } // equip a weapon if (GetHasFeat(FEAT_TWO_WEAPON_FIGHTING,oMe)==TRUE) { // check to see if have a second weapon nN=caiGetEquippedWeaponType(oMe,INVENTORY_SLOT_LEFTHAND); if (nWT==CAI_WEAPON_NONE||nWT==CAI_WEAPON_RANGED) { // equip AssignCommand(oMe,ActionEquipMostDamagingMelee(oTarget,TRUE)); } // equip } // check to see if have a second weapon } // melee else if (fF<5.0) { // move away AssignCommand(oMe,ActionMoveAwayFromObject(oTarget,TRUE,6.5)); } // move away else { // good distance if (nWT!=CAI_WEAPON_RANGED) { //equip a ranged weapon AssignCommand(oMe,ActionEquipMostDamagingRanged(oTarget)); } //equip a ranged weapon } // good distance } // deal with my target } // point blank shot AI DetermineCombatRound(oTarget); } // there are enemies near else { // no enemies near - equip ranged if (nWT!=CAI_WEAPON_RANGED) { //equip a ranged weapon AssignCommand(oMe,ActionEquipMostDamagingRanged()); } //equip a ranged weapon } // no enemies near - equip ranged }