HoS_PRC8/_mod/_module/nss/cai_summon.nss
Jaysyn904 04165202c0 Initial upload
Initial upload
2024-11-25 19:36:07 -05:00

154 lines
4.8 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
// cai_summon - Custom Combat AI - Summon Mode
// By Deva Bryson Winblood. 11/2004
////////////////////////////////////////////////////////////////////////////////
#include "cai_inc_hos"
#include "nw_I0_generic"
int fnClassIsSpellCaster(int nPos,object oNPC)
{ // tell me if this class is a spell caster
int nClass=GetClassByPosition(nPos,oNPC);
int bRet=FALSE;
switch(nClass)
{
case CLASS_TYPE_ARCANE_ARCHER:
case CLASS_TYPE_BARD:
case CLASS_TYPE_CLERIC:
case CLASS_TYPE_DRUID:
case CLASS_TYPE_FEY:
case CLASS_TYPE_DRAGONDISCIPLE:
case CLASS_TYPE_PALADIN:
case CLASS_TYPE_PALEMASTER:
case CLASS_TYPE_RANGER:
case CLASS_TYPE_SHADOWDANCER:
case CLASS_TYPE_SHIFTER:
case CLASS_TYPE_SORCERER:
case CLASS_TYPE_WIZARD: { bRet=TRUE; break; }
default: { break; }
}
return bRet;
} // fnClassIsSpellCaster()
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) nThis=nThis+3;
nC=GetClassByPosition(2,oOb);
if (nC==CLASS_TYPE_CLERIC||nC==CLASS_TYPE_PALADIN) nThis=nThis+3;
nC=GetClassByPosition(3,oOb);
if (nC==CLASS_TYPE_CLERIC||nC==CLASS_TYPE_PALADIN) nThis=nThis+3;
} // see if target is a cleric
if (fnClassIsSpellCaster(1,oOb)) nThis++;
if (fnClassIsSpellCaster(2,oOb)) nThis++;
if (fnClassIsSpellCaster(3,oOb)) 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();
float fF;
int nN;
int nMyRace=GetRacialType(oMe);
object oBest=fnGetBestTarget(nMyRace);
int bTargetChanged=FALSE;
int nState=GetLocalInt(oMe,"nCAIState");
if (oBest!=oTarget)
{
oTarget=oBest;
bTargetChanged=TRUE;
}
if (GetIsObjectValid(oTarget))
{ // target is valid
nState++;
if (nState>4) nState=1;
if (nState==1)
{ // summon spell
if (GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_SUMMONED,oMe,1))==FALSE)
{ // no summoned critters
nN=caiGetAvailableSummonSpell(oTarget);
if (nN!=0)
{ // summon
AssignCommand(oMe,ActionCastSpellAtLocation(nN,GetLocation(oMe)));
} // summon
else { nState=2; }
} // no summoned critters
else { nState=2; }
} // summon spell
if (nState==2)
{ // defensive spells
nN=caiGetAvailableDefensiveSpell(oMe,oMe);
if (nN==0) nState=3;
else
{ // cast this spell
AssignCommand(oMe,ActionCastSpellAtObject(nN,oMe));
} // cast this spell
} // defensive spells
if (nState==3)
{ // combat spell
nN=caiGetAvailableCombatSpell(oMe,oTarget);
if (nN!=0)
{ // spell found
AssignCommand(oMe,ActionCastSpellAtObject(nN,oTarget));
} // spell found
else
{ //
nState=4;
} //
} // combat spell
if (nState==4)
{ // summon spell
if (GetIsObjectValid(GetAssociate(ASSOCIATE_TYPE_SUMMONED,oMe,2))==FALSE)
{ // no summoned critters
nN=caiGetAvailableSummonSpell(oTarget);
if (nN!=0)
{ // summon
AssignCommand(oMe,ActionCastSpellAtLocation(nN,GetLocation(oMe)));
} // summon
else { DetermineCombatRound(oTarget); }
} // no summoned critters
} // summon spell
} // target is valid
// check need to heal self and remove negative spells
// set up sentinel for resting
if (GetLocalInt(oMe,"bCAIRESTSENTINEL")!=TRUE)
{ // trigger the sentinel
SetLocalInt(oMe,"bCAIRESTSENTINEL",TRUE);
caiRestSentinel(oMe);
} // trigger the sentinel
}