// 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); }