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

285 lines
10 KiB
Plaintext

/////////////////////////////////////////////////////////////////////////////
// Real Time Strategy - NWN - Heartbeat kicker
//===========================================================================
// By Deva Bryson Winblood. 02/24/2003
/////////////////////////////////////////////////////////////////////////////
/* This heartbeat just makes sure the DelayCommand() for the NPC fired off
recently. If it has not then it will start it up again */
// If no AI has been processed for 12 seconds it will launch the script
#include "antistuck_h"
object fnGetCloseTarget(object oMe,float fRange)
{ // PURPOSE: Get a close target
object oRet=OBJECT_INVALID;
object oOb;
int nN=1;
oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,nN,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
if (GetDistanceBetween(oOb,oMe)<=fRange) oRet=oOb;
return oRet;
} // fnGetCloseTarget()
object fnGetFarTarget(object oMe,float fRange)
{ // PURPOSE: Get a target perceived by allies
object oRet=OBJECT_INVALID;
float fDist=1000.0;
object oFriend;
object oOb;
int nF;
nF=1;
oFriend=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,nF,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND);
while(oFriend!=OBJECT_INVALID&&GetDistanceBetween(oMe,oFriend)<=fRange)
{ // check perception of friends
oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oFriend,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
if (GetDistanceBetween(oOb,oMe)<=fRange)
{ // enemy in range spotted by ally
if (GetDistanceBetween(oOb,oMe)<fDist)
{ // closest so far
oRet=oOb;
fDist=GetDistanceBetween(oMe,oOb);
} // closest so far
} // enemy in range spotted by ally
nF++;
oFriend=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,nF,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND);
} // check perception of friends
return oRet;
} // fnGetFarTarget()
float fnFacing(vector vMe,vector vDest)
{ // PURPOSE: Return what facing should be
float fRet=0.0;
int nMX=FloatToInt(vMe.x);
int nMY=FloatToInt(vMe.y);
int nDX=FloatToInt(vDest.x);
int nDY=FloatToInt(vDest.y);
int nNS;
int nEW;
if (nMX>nDX) nEW=-1;
if (nMY>nDY) nNS=-1;
if (nMX<nDX) nEW=1;
if (nMY<nDY) nNS=1;
if (nEW==0&&nNS==1) fRet=0.0;
else if (nEW==0&&nNS==-1) fRet=180.0;
else if (nEW==1&&nNS==0) fRet=90.0;
else if (nEW==-1&&nNS==0) fRet=270.0;
else if (nEW==1&&nNS==1) fRet=45.0;
else if (nEW==-1&&nNS==1) fRet=315.0;
else if (nEW==1&&nNS==-1) fRet=135.0;
else if (nEW==-1&&nNS==-1) fRet=225.0;
return fRet;
} // fnFacing
void fnDamage(object oArtillery,object oTarget,location lLoc,int nType)
{ // PURPOSE: Do damage
effect eE;
object oOb;
int nN;
if (nType==1)
{ // ballista
eE=EffectDamage(d6(3),DAMAGE_TYPE_PIERCING);
if (GetCreatureSize(oTarget)==CREATURE_SIZE_LARGE||GetCreatureSize(oTarget)==CREATURE_SIZE_HUGE) eE=EffectDamage(d8(3),DAMAGE_TYPE_PIERCING);
AssignCommand(oArtillery,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oTarget));
} // ballista
else
{ // catapult
nN=1;
oOb=GetNearestCreatureToLocation(CREATURE_TYPE_IS_ALIVE,TRUE,lLoc,nN);
while(oOb!=OBJECT_INVALID&&GetDistanceBetweenLocations(lLoc,GetLocation(oOb))<=8.0)
{ // in range
eE=EffectDamage(d6(2),DAMAGE_TYPE_FIRE);
DelayCommand(0.2,AssignCommand(oArtillery,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oOb)));
eE=EffectDamage(d4(),DAMAGE_TYPE_BLUDGEONING);
DelayCommand(0.2,AssignCommand(oArtillery,ApplyEffectToObject(DURATION_TYPE_INSTANT,eE,oOb)));
nN++;
oOb=GetNearestCreatureToLocation(CREATURE_TYPE_IS_ALIVE,TRUE,lLoc,nN);
} // in range
} // catapult
} // fnDamage()
void fnFire(object oArtillery,object oTarget, location lLoc,float fRange)
{ // PURPOSE: Fire artillery
float fFacing;
effect eE;
int nType=GetLocalInt(oArtillery,"nType");
int bMiss=FALSE;
int nHit;
int nRoll;
fFacing=fnFacing(GetPosition(oArtillery),GetPosition(oTarget));
fFacing=fFacing+GetLocalFloat(oArtillery,"fFacingOffset");
AssignCommand(oArtillery,SetFacing(fFacing));
if (nType==1)
{ // ballista
nHit=GetAC(oTarget);
if (GetHasSpellEffect(SPELL_SHIELD,oTarget)==TRUE) nHit=nHit+5;
if (GetHasSpellEffect(SPELL_DISPLACEMENT,oTarget)==TRUE) nHit=nHit+4;
if (GetHasSpellEffect(SPELL_ENTROPIC_SHIELD,oTarget)==TRUE) nHit=nHit+3;
nRoll=d20()+5;
if (nRoll<nHit) bMiss=TRUE;
eE=EffectBeam(VFX_BEAM_CHAIN,oArtillery,BODY_NODE_HAND,bMiss);
AssignCommand(oArtillery,ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eE,oTarget,1.5));
if (bMiss!=TRUE) DelayCommand(2.0,fnDamage(oArtillery,oTarget,lLoc,nType));
} // ballista
else
{ // catapult
eE=EffectVisualEffect(VFX_IMP_MIRV_FLAME);
AssignCommand(oArtillery,ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,eE,lLoc,3.0));
eE=EffectVisualEffect(VFX_FNF_FIREBALL);
DelayCommand(3.1,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eE,lLoc));
DelayCommand(3.2,fnDamage(oArtillery,oTarget,lLoc,nType));
} // catapult
DeleteLocalInt(oArtillery,"nLoadCount");
} // fnFire()
void main()
{
object oMe=OBJECT_SELF;
object oDeployed=GetLocalObject(oMe,"oDeployed");
int bDeployed=GetLocalInt(oMe,"bDeployed");
object oTarget=GetLocalObject(oMe,"oTarget");
int nMode=GetLocalInt(oMe,"nMState");
int nS=GetLocalInt(oMe,"nSState");
string sRes="dwfballista";
int nLoadCount=GetLocalInt(oDeployed,"nLoadCount");
float fDistance=GetDistanceBetween(oMe,oTarget);
float fRange=40.0;
int nN;
object oOb;
SetAILevel(oMe,AI_LEVEL_NORMAL);
//SendMessageToPC(GetFirstPC(),"ME:'"+GetName(oMe)+"'");
//SendMessageToPC(GetFirstPC()," DEPLOYED:"+GetName(oDeployed)+" AREA:"+GetName(GetArea(oDeployed)));
//SendMessageToPC(GetFirstPC()," TARGET:"+GetName(oTarget));
//SendMessageToPC(GetFirstPC()," MState:"+IntToString(nMode)+" SState:"+IntToString(nS));
if (GetResRef(oMe)=="dwfupg2")
{ // catapult
fRange=80.0;
sRes="dwfcatapult";
} // catapult
if (oDeployed!=OBJECT_INVALID&&bDeployed==TRUE&&nMode!=3)
{ // artillery is deployed
if (nLoadCount<2)
{ // load
if (GetDistanceBetween(oMe,oDeployed)>2.0&&oDeployed!=OBJECT_INVALID)
{ // move
AssignCommand(oMe,ClearAllActions(TRUE));
AssignCommand(oMe,ASActionMoveToObject(oDeployed,TRUE,1.0));
} // move
else
{ // animate
AssignCommand(oMe,SetFacingPoint(GetPosition(oDeployed)));
ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0,5.5);
nLoadCount++;
SetLocalInt(oDeployed,"nLoadCount",nLoadCount);
} // animate
} // load
else if (oTarget==OBJECT_INVALID||GetIsEnemy(oTarget)==FALSE||GetArea(oTarget)!=GetArea(oMe)||fDistance<10.0||fDistance>fRange)
{ // look for target
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_LOOK_FAR,1.0,5.5));
if (fRange==40.0)
{ // close only
oTarget=fnGetCloseTarget(oMe,fRange);
} // close only
else
{ // close then far
oTarget=fnGetCloseTarget(oMe,fRange);
if (oTarget==OBJECT_INVALID) oTarget=fnGetFarTarget(oMe,fRange);
} // close then far
if (oTarget!=OBJECT_INVALID)
{ // found
AssignCommand(oMe,SpeakString("Target sighted"));
SetLocalObject(oMe,"oTarget",oTarget);
} // found
} // look for target
else
{ // fire
AssignCommand(oMe,SpeakString("Fire!!"));
if (GetResRef(oMe)=="dwfupg1")
{ // ballista
AssignCommand(oMe,PlaySound("cb_sh_ballista"));
} // ballista
else
{ // catapult
AssignCommand(oMe,PlaySound("cb_sh_catapult"));
} // catapult
fnFire(oDeployed,oTarget,GetLocation(oTarget),fRange);
} // fire
} // artillery is deployed
else
{ // artillery is not deployed
if (nMode==0)
{ // stand around - wait
ExecuteScript("nw_c2_default1",oMe);
} // stand around - wait
else if (nMode==1)
{ // follow
if (GetArea(oTarget)!=GetArea(oMe))
{ // teleport
AssignCommand(oMe,ClearAllActions(TRUE));
AssignCommand(oMe,JumpToObject(oTarget));
} // teleport
else if (GetDistanceBetween(oMe,oTarget)>5.0)
{ // move
AssignCommand(oMe,ASActionMoveToObject(oTarget,TRUE,4.0));
} // move
else
{ // standard script
ExecuteScript("nw_c2_default1",oMe);
} // standard script
} // follow
else if (nMode==2)
{ // deploy
if (nS==0)
{ // animate get low
ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0,5.5);
SetLocalInt(oMe,"nSState",1);
} // animate get low
else if (nS==1)
{ // create artillery
oDeployed=CreateObject(OBJECT_TYPE_PLACEABLE,sRes,GetLocation(oMe));
SetLocalObject(oDeployed,"oOwner",oMe);
SetLocalObject(oMe,"oDeployed",oDeployed);
SetLocalInt(oMe,"nSState",2);
} // create artillery
else
{ // completed
SetLocalInt(oMe,"bDeployed",TRUE);
DeleteLocalInt(oMe,"nSState");
DeleteLocalInt(oMe,"nMState");
AssignCommand(oMe,SpeakString("Deployed"));
} // completed
} // deploy
else if (nMode==3)
{ // pack up
if (nS==0)
{ // move to artillery
if (GetDistanceBetween(oMe,oDeployed)>1.5)
{ // move
AssignCommand(oMe,ClearAllActions(TRUE));
AssignCommand(oMe,ASActionMoveToObject(oDeployed,TRUE,1.0));
} // move
else
{ SetLocalInt(oMe,"nSState",1); }
} // move to artillery
else if (nS==1)
{ // get mid animation
AssignCommand(oMe,SetFacingPoint(GetPosition(oDeployed)));
ActionPlayAnimation(ANIMATION_LOOPING_GET_MID,1.0,5.5);
SetLocalInt(oMe,"nSState",2);
} // get mid animation
else if (nS==2)
{ // destroy artillery
DestroyObject(oDeployed);
SetLocalInt(oMe,"nSState",3);
} // destroy artillery
else
{ // completed
DeleteLocalInt(oMe,"nMState");
DeleteLocalInt(oMe,"nSState");
DeleteLocalInt(oMe,"bDeployed");
DeleteLocalObject(oMe,"oDeployed");
DeleteLocalObject(oMe,"oTarget");
AssignCommand(oMe,SpeakString("Packed"));
} // completed
} // pack up
} // artillery is not deployed
}