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

246 lines
8.1 KiB
Plaintext

// spawn_ocean - Underwater Ocean spawn
#include "antistuck_h"
void fnSpawn(object oArea,object oCenter,int nNumber);
void fnBehavior()
{ // PURPOSE: Movement and behavior AI for animals
object oMe=OBJECT_SELF;
int nR=d8();
object oDest;
object oEnemy;
effect eE;
if (GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oMe)!=OBJECT_INVALID)
{ // PC is present
oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
if (GetIsInCombat(oMe)==FALSE&&oEnemy==OBJECT_INVALID)
{ // not in combat and no perceived enemies
if (nR==1)
{ // ActionRandomWalk()
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionRandomWalk());
DelayCommand(12.0,fnBehavior());
} // ActionRandomWalk()
else if (nR==2)
{ // Animation sequence 1
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_FIREFORGET_DODGE_SIDE,1.0,4.0));
DelayCommand(8.0,fnBehavior());
} // Animation sequence 1
else if (nR==3)
{ // Animation sequence 2
AssignCommand(oMe,ClearAllActions());
oDest=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_FRIEND,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);
if (oDest!=OBJECT_INVALID)
{ // follow
AssignCommand(oMe,ActionForceFollowObject(oDest,3.0));
DelayCommand(24.0,fnBehavior());
} // follow
else
{ // delay
DelayCommand(8.0,fnBehavior());
} // delay
} // Animation sequence 2
else if (nR==4)
{ // disappear reappear
AssignCommand(oMe,ClearAllActions());
AssignCommand(oMe,ClearAllActions());
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,3);
AssignCommand(oMe,ASActionMoveToObject(oDest,Random(2),3.0));
DelayCommand(12.0,fnBehavior());
} // disappear reappear
else if (nR==5)
{ // disappear and reappear elsewhere
AssignCommand(oMe,ClearAllActions());
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,2);
AssignCommand(oMe,ASActionMoveToObject(oDest,Random(2),3.0));
DelayCommand(8.0,fnBehavior());
} // disappear and reappear elsewhere
else if (nR>5&&nR<8)
{ // move to waypoint
AssignCommand(oMe,ClearAllActions());
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d20());
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d12());
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d10());
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d8());
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d6());
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d4());
if (oDest==OBJECT_INVALID) oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe);
AssignCommand(oMe,ASActionMoveToObject(oDest,Random(2),3.0));
DelayCommand(20.0,fnBehavior());
} // move to waypoint
else
{ // despawn + setup delayed new spawn
AssignCommand(oMe,ClearAllActions());
oDest=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC);
if (oDest!=OBJECT_INVALID)
{ // assign respawn to PC
AssignCommand(oDest,DelayCommand(11.0+IntToFloat(d100()),fnSpawn(GetArea(oMe),oDest,1)));
AssignCommand(oMe,ActionMoveAwayFromObject(oDest,TRUE,60.0));
} // assign respawn to PC
DelayCommand(10.0,DestroyObject(oMe));
} // despawn + setup delayed new spawn
} // not in combat and no perceived enemies
else
{ // keep trying
DelayCommand(12.0,fnBehavior());
} // keep trying
} // PC is present
else
{ // keep trying
DelayCommand(6.0,fnBehavior());
} // keep trying
} // fnBehavior()
int fnFindEmptySlot(object oArea)
{ // PURPOSE: Return slot for spawning
int nRet=0;
int nN=1;
object oOb=GetLocalObject(oArea,"oInhabitant"+IntToString(nN));
while(nN<=8&&nRet==0)
{ // look for spot
if (oOb==OBJECT_INVALID) return nN;
nN++;
oOb=GetLocalObject(oArea,"oInhabitant"+IntToString(nN));
} // look for spot
return nRet;
} // fnFindEmptySlot()
void fnCreate(object oArea,object oCenter,int nSlot,string sRes,int bAppear)
{ // PURPOSE: Spawn a creature
object oWP;
object oCreature;
int nN;
oWP=GetNearestObjectByTag("UNDERWATER_SPAWN",oCenter,d20());
if (oWP==OBJECT_INVALID) oWP=GetNearestObjectByTag("UNDERWATER_SPAWN",oCenter,d12());
if (oWP==OBJECT_INVALID) oWP=GetNearestObjectByTag("UNDERWATER_SPAWN",oCenter,d10());
if (oWP==OBJECT_INVALID) oWP=GetNearestObjectByTag("UNDERWATER_SPAWN",oCenter,d8());
if (oWP==OBJECT_INVALID) oWP=GetNearestObject(OBJECT_TYPE_WAYPOINT,oCenter);
if (oWP!=OBJECT_INVALID)
{ // spawn creature
oCreature=CreateObject(OBJECT_TYPE_CREATURE,sRes,GetLocation(oWP),bAppear);
SetLocalObject(oArea,"oInhabitant"+IntToString(nSlot),oCreature);
SetLocalInt(oCreature,"nSlot",nSlot);
AssignCommand(oCreature,fnBehavior());
} // spawn creature
} // fnCreate()
void fnSpawn(object oArea,object oCenter,int nNumber)
{ // PURPOSE: Spawn nNumber creatures
int nC;
int nSlot;
string sRes;
int bAppear;
int nRoll;
nC=1;
while(nC<=nNumber)
{ // find and call spawn
nSlot=fnFindEmptySlot(oArea);
nRoll=d100();
if (nRoll<51)
{ // small shark
sRes="smallshark";
bAppear=FALSE;
} // small shark
else if (nRoll<52)
{ // giant crab
sRes="gcrab";
bAppear=FALSE;
} // giant crab
else if (nRoll<66)
{ // Crab
sRes="crab";
bAppear=FALSE;
} // Crab
else if (nRoll<81)
{ // shark
sRes="shark";
bAppear=FALSE;
} // shark
else if (nRoll<88)
{ // tiny sea snake
sRes="tinyseasnake";
bAppear=TRUE;
} // tiny sea snake
else if (nRoll<92)
{ // large shark
sRes="largeshark";
bAppear=TRUE;
} // large shark
else if (nRoll<94)
{ // huge shark
sRes="hugeshark";
bAppear=FALSE;
} // huge shark
else if (nRoll<96)
{ // seasnake
sRes="seasnake";
bAppear=TRUE;
} // seasnake
else if (nRoll<97)
{ // hugeseasnake
sRes="hugeseasnake";
bAppear=FALSE;
} // hugeseasnake
else if (nRoll<99)
{ // medium sea snake
sRes="medseasnake";
bAppear=FALSE;
} // medium sea snake
else
{ // large sea snake
sRes="largeseasnake";
bAppear=FALSE;
} // large sea snake
if (nSlot!=0)
{
fnCreate(oArea,oCenter,nSlot,sRes,bAppear);
//if (GetIsPC(oCenter)) SendMessageToPC(oCenter," "+sRes);
}
nC++;
} // find and call spawn
} // fnSpawn()
void fnSpawnMonitor(object oArea,object oPC)
{ // PURPOSE: Make sure to keep spawns coming if PC stays in the area
int nSlot;
if (GetArea(oPC)==oArea&&GetIsPC(oPC))
{ // still in the area
nSlot=fnFindEmptySlot(oArea);
if (nSlot!=0) fnSpawn(oArea,oPC,1);
DelayCommand(120.0,fnSpawnMonitor(oArea,oPC));
} // still in the area
} // fnSpawnMonitor()
///////////////////////////////////////////////////////////////////////// MAIN
void main()
{
object oPC=OBJECT_SELF;
object oArea=GetArea(oPC);
int nC;
object oOb;
int nN=1;
int nR;
SendMessageToPC(oPC,"Spawning natural ocean life.");
oOb=GetLocalObject(oArea,"oInhabitant"+IntToString(nN));
while(nN<=8)
{ // count inhabitants
if (oOb!=OBJECT_INVALID) { nC++; }
nN++;
oOb=GetLocalObject(oArea,"oInhabitant"+IntToString(nN));
} // count inhabitants
nN=0;
if (nC<8)
{ // possible to spawn more
nN=8-nC;
nR=Random(nN)+1;
if (nN>4&&nR<5) nR=5;
//SendMessageToPC(oPC,"Spawn:"+IntToString(nR)+" of "+IntToString(nN)+" Count:"+IntToString(nC));
if (nR>0) fnSpawn(oArea,oPC,nR);
} // possible to spawn more
DelayCommand(120.0,fnSpawnMonitor(oArea,oPC));
}
///////////////////////////////////////////////////////////////////////// MAIN