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

377 lines
12 KiB
Plaintext

// hb avernus
#include "antistuck_h"
int fnCountResidents()
{ // return how many NPCs in the area
int nRet=0;
int nC=1;
object oCr=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,OBJECT_SELF,nC,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC);
while(oCr!=OBJECT_INVALID)
{ // count
nRet++;
nC++;
oCr=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,OBJECT_SELF,nC,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_NOT_PC);
} // count
return nRet;
} // fnCountResidents()
void fnDestroyContainer(object oContainer)
{ // empty items
object oItem=GetFirstItemInInventory(oContainer);
while(oItem!=OBJECT_INVALID)
{
DelayCommand(0.2,DestroyObject(oItem));
oItem=GetNextItemInInventory(oContainer);
}
DelayCommand(0.3,DestroyObject(oItem));
} // fnDestroyContainer()
object fnSpawn(string sRes,location lLoc,int nVis=VFX_FNF_SUMMON_MONSTER_1)
{ // create creature
object oRet;
effect eVis=EffectVisualEffect(nVis);
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eVis,lLoc,1.0);
oRet=CreateObject(OBJECT_TYPE_CREATURE,sRes,lLoc,FALSE);
return oRet;
} // fnSpawn()
void fnWander()
{ // wander
object oMe=OBJECT_SELF;
object oEnemy=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oMe,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
int nR;
if (GetIsInCombat(oMe)!=TRUE&&oEnemy==OBJECT_INVALID)
{ // wander
oEnemy=GetNearestObject(OBJECT_TYPE_ITEM,oMe,1);
if (oEnemy!=OBJECT_INVALID&&GetDistanceBetween(oEnemy,oMe)<20.0)
{ // cleanup item
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionMoveToObject(oEnemy,TRUE,1.0));
AssignCommand(oMe,ActionDoCommand(fnDestroyContainer(oEnemy)));
} // cleanup item
else
{ // check for containers
oEnemy=GetNearestObject(OBJECT_TYPE_PLACEABLE,oMe,1);
if (oEnemy!=OBJECT_INVALID&&GetDistanceBetween(oEnemy,oMe)<20.0&&GetHasInventory(oEnemy)==TRUE)
{ // empty container
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionMoveToObject(oEnemy,TRUE,1.0));
AssignCommand(oMe,ActionDoCommand(fnDestroyContainer(oEnemy)));
} // empty container
else
{ // move
nR=d10();
oEnemy=GetNearestObjectByTag("BAATOR1_WANDER"+IntToString(nR),oMe);
AssignCommand(oMe,ASActionMoveToObject(oEnemy,FALSE,1.0));
} // move
}// check for containers
} // wander
DelayCommand(24.0,fnWander());
} // fnWander()
void fnMoveTo()
{ // move to point and despawn
object oMe=OBJECT_SELF;
object oDest=GetLocalObject(oMe,"oBDest");
float fDist=GetDistanceBetween(oMe,oDest);
effect eVis=EffectVisualEffect(VFX_FNF_IMPLOSION);
if (GetIsInCombat(oMe)!=TRUE)
{ // not fighting
if (fDist<3.0)
{ // arrived
ApplyEffectToObject(DURATION_TYPE_INSTANT,eVis,oMe,3.0);
DelayCommand(2.0,DestroyObject(oMe));
} // arrived
else
{ // move
AssignCommand(oMe,ASActionMoveToObject(oDest,FALSE,1.0));
} // move
} // not fighting
DelayCommand(10.0,fnMoveTo());
} // fnMoveTo()
void fnDestroy()
{ // destroy self
object oMe=OBJECT_SELF;
object oEnemy=GetNearestCreature(CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY,oMe,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
effect eVis=EffectVisualEffect(VFX_FNF_IMPLOSION);
if (GetIsInCombat(oMe)!=TRUE&&oEnemy==OBJECT_INVALID)
{ // Destroy Self
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eVis,GetLocation(oMe),3.0);
DelayCommand(1.0,DestroyObject(oMe));
} // Destroy Self
else
{ // wait a bit longer
DelayCommand(20.0,fnDestroy());
} // wait a bit longer
} // fnDestroy()
void fnTown()
{ // Town interaction
object oDest=GetLocalObject(OBJECT_SELF,"oBDest");
int nR;
object oMe=OBJECT_SELF;
int nState=GetLocalInt(oMe,"nState");
if (GetIsInCombat(oMe)!=TRUE)
{ // not in combat
switch(nState)
{ // town interaction switch
case 0: { // choose waypoint
nR=d4();
oDest=GetWaypointByTag("ELY1_TOWN"+IntToString(nR));
SetLocalObject(oMe,"oBDest",oDest);
SetLocalInt(oMe,"nState",1);
AssignCommand(oMe,ASActionMoveToObject(oDest,FALSE,1.0));
break;
} // choose waypoint
case 1: { // await arrival at waypoint
if (GetDistanceBetween(oDest,oMe)>2.5)
{ // still too far away
if (GetCurrentAction(oMe)!=ACTION_MOVETOPOINT)
{ // move
AssignCommand(oMe,ASActionMoveToObject(oDest,FALSE,1.0));
} // move
} // still too far away
else
{ // close enough
SetLocalInt(oMe,"nState",2);
} // close enough
break;
} // await arrival at waypoint
case 2: { // act
nR=d6();
if (nR==1)
{ // talk
oDest=GetNearestCreature(CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,oMe,1);
if (oDest!=OBJECT_INVALID)
{ //!OI
AssignCommand(oMe,ActionMoveToObject(oDest,FALSE,2.0));
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_TALK_NORMAL,1.0,5.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} //!OI
} // talk
else if (nR==2)
{ // sitc
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS,1.0,9.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // sitc
else if (nR==3)
{ // drink
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_FIREFORGET_DRINK,1.0,9.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // drink
else if (nR==4)
{ // look far
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_LOOK_FAR,1.0,5.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // look far
else if (nR==5)
{ // read
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_FIREFORGET_READ,1.0,9.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // read
else if (nR==6)
{ // talk laughing
oDest=GetNearestCreature(CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,oMe,1);
if (oDest!=OBJECT_INVALID)
{ //!OI
AssignCommand(oMe,ActionMoveToObject(oDest,FALSE,2.0));
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING,1.0,5.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} //!OI
} // talk laughing
break;
} // act
default: { SetLocalInt(oMe,"nState",0); break; }
} // town interaction switch
} // not in combat
DelayCommand(10.0,fnTown());
} // fnTown()
void fnTemple()
{ // Temple interaction
object oDest=GetLocalObject(OBJECT_SELF,"oBDest");
int nR;
object oMe=OBJECT_SELF;
int nState=GetLocalInt(oMe,"nState");
if (GetIsInCombat(oMe)!=TRUE)
{ // not in combat
switch(nState)
{ // temple interaction switch
case 0: { // choose waypoint
nR=d4();
oDest=GetWaypointByTag("ELY1_TEMPLE"+IntToString(nR));
SetLocalObject(oMe,"oBDest",oDest);
SetLocalInt(oMe,"nState",1);
AssignCommand(oMe,ASActionMoveToObject(oDest,FALSE,1.0));
break;
} // choose waypoint
case 1: { // await arrival at waypoint
if (GetDistanceBetween(oDest,oMe)>2.5)
{ // still too far away
if (GetCurrentAction(oMe)!=ACTION_MOVETOPOINT)
{ // move
AssignCommand(oMe,ASActionMoveToObject(oDest,FALSE,1.0));
} // move
} // still too far away
else
{ // close enough
SetLocalInt(oMe,"nState",2);
} // close enough
break;
} // await arrival at waypoint
case 2: { // act
nR=d4();
if (nR==1)
{ // worship
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_WORSHIP,1.0,9.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // worship
else if (nR==2)
{ // meditate
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_MEDITATE,1.0,9.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // meditate
else if (nR==3)
{ // talk pleading
oDest=GetNearestCreature(CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,oMe,1);
if (oDest!=OBJECT_INVALID)
{ //!OI
AssignCommand(oMe,ActionMoveToObject(oDest,FALSE,2.0));
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING,1.0,5.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} //!OI
} // talk pleading
else if (nR==4)
{ // sitc
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS,1.0,9.0));
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nState",0)));
} // sitc
break;
} // act
default: { SetLocalInt(oMe,"nState",0); break; }
} // temple interaction switch
} // not in combat
DelayCommand(10.0,fnTemple());
} // fnTemple()
void fnBehavior(object oCreature,int nBehavior)
{ // assign behavior to the creature
// 1 = wander for 4 hours
// 2 = Town interaction
// 3 = temple interaction
// 4 = move to point and despawn
object oDest;
object oNear;
int nR;
float fDelay=HoursToSeconds(4);
if (nBehavior==1)
{ // wander
AssignCommand(oCreature,fnWander());
AssignCommand(oCreature,DelayCommand(fDelay,fnDestroy()));
} // wander
else if (nBehavior==2)
{ // town interaction
AssignCommand(oCreature,fnTown());
AssignCommand(oCreature,DelayCommand(fDelay,fnDestroy()));
} // town interaction
else if (nBehavior==3)
{ // temple interaction
AssignCommand(oCreature,fnTemple());
AssignCommand(oCreature,DelayCommand(fDelay,fnDestroy()));
} // temple interaction
else if (nBehavior==4)
{ // move to point
oNear=GetNearestObject(OBJECT_TYPE_WAYPOINT,oCreature,1);
nR=d4();
oDest=GetWaypointByTag("BAATOR1_SPAWN"+IntToString(nR));
if (oDest==oNear)
{ // pick another
nR++;
if (nR>4) nR=1;
oDest=GetWaypointByTag("BAATOR1_SPAWN"+IntToString(nR));
} // pick another
SetLocalObject(oCreature,"oBDest",oDest);
AssignCommand(oCreature,fnMoveTo());
} // move to point
} // fnBehavior
void fnResidents(object oArea)
{ // spawn residents if need be
object oMod=GetModule();
int nR;
int nC=fnCountResidents();
int nSP=d4();
object oFirst=GetFirstObjectInArea(oArea);
object oCR;
int nST=VFX_IMP_LIGHTNING_M;
object oSpawnPoint=GetWaypointByTag("BAATOR1_SPAWN"+IntToString(nSP));
location lLoc=GetLocation(oSpawnPoint);
string sRes;
effect eAura=EffectVisualEffect(VFX_DUR_GLOW_WHITE);
oFirst=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,1);
if (nC<8)
{ // spawn okay
nR=d100();
if (nR<36)
{ // spawn
nR=d100();
if (nR<34)
{ // Lemure
sRes="lemure";
} // Lemure
else if (nR<67)
{ // petitioners
nR=d100();
nST=VFX_IMP_BREACH;
if (nR<34)
sRes="imp001";
else if (nR<67)
sRes="hellcat";
else {
sRes="skelwarr003"; }
} // petitioners
else if (nR<98)
{ // Devils
nR=d100();
if (nR<34) sRes="bonedevil";
else if (nR<88) sRes="erinyes001";
else { sRes="gelugon"; }
} // Devils
else
{ // Big Devils
nR=d100();
if (nR<46) sRes="gelugon";
else if (nR<95) sRes="devil002";
else { sRes="goldmflesh002"; }
} // Big Devils
oCR=fnSpawn(sRes,lLoc,nST);
nR=d4(); // behavior
if (GetTag(oCR)=="GodElundur"||GetTag(oCR)=="GoddessAbigail")
{ // god aura
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eAura,oCR,10000.0);
nR=1; // wander for 4 hours
} // god aura
nR=1;
if (d4()<3) nR=4;
fnBehavior(oCR,nR);
} // spawn
} // spawn okay
} // fnResidents()
void main()
{
object oMe=OBJECT_SELF;
object oPC=GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oMe,1);
if (oPC!=OBJECT_INVALID)
{ // PCs present
SendMessageToPC(oPC,"You are wandering in The Nine Hells.");
fnResidents(oMe);
//fnVisualEffects(oMe);
} // PCs present
ExecuteScript("area_hb_clean",oMe);
}