// 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