//////////////////////////////////////////////////////////////////////////////// // nonteam_raiders - Spawn and control non-team raiders // By Deva Bryson Winblood. 03/30/2005 //////////////////////////////////////////////////////////////////////////////// #include "antistuck_h" #include "x3_inc_string" int fnPlayerExistsWithLevel(int nLevelMin) { // PURPOSE: return true if there is a connected player of this level or higher int nLevel; object oPC=GetFirstPC(); while(oPC!=OBJECT_INVALID) { // check each player if (GetIsDM(oPC)==FALSE) { // not a DM nLevel=GetLevelByPosition(1,oPC)+GetLevelByPosition(2,oPC)+GetLevelByPosition(3,oPC); if (nLevel>=nLevelMin) return TRUE; } // not a DM oPC=GetNextPC(); } // check each player return FALSE; } // fnPlayerExistsWithLevel() int fnGetAbsoluteHour() { // PURPOSE: Return time in absolute hours int nTime=GetTimeHour(); nTime=nTime+(GetCalendarDay()*24)+(GetCalendarMonth()*24*30)+(GetCalendarYear()*24*30*12); return nTime; } // fnGetAbsoluteHour() string fnGetResRaider(string sPrefix) { // PURPOSE: will return a creature resref string sRet=""; int nR=d100(); if (sPrefix=="ORCRAID") { // orcs if (nR<61) sRet="orcb002"; else if (nR<91) sRet="orcb001"; else { sRet="orcchiefb001"; } } // orcs else if (sPrefix=="gnollraid") { // gnolls if (nR<61) sRet="gnoll002"; else if (nR<91) sRet="gnoll004"; else { sRet="gnoll003"; } } // gnolls else if (sPrefix=="boggleraid") { // boggles if (nR<61) sRet="swamplandbogg001"; else if (nR<91) sRet="swamplandboggle"; else { sRet="swamplandbogglew"; } } // boggles else if (sPrefix=="barbraid") { // barbarians if (nR<61) sRet="barbarian"; else if (nR<91) sRet="barbarianaxethro"; else { sRet="barbarian001"; } } // barbarians else if (sPrefix=="duergarraid") { // duergars if (nR<61) sRet="duefight002"; else if (nR<91) sRet="duefight006"; else { sRet="duemage011"; } } // duergars else if (sPrefix=="dbanditraid") { // desert bandits if (nR<61) sRet="desertbandit"; else if (nR<91) sRet="desertbandit001"; else { sRet="desertbandit002"; } } // desert bandits else if (sPrefix=="pygmyraid") { // pygmys if (nR<61) sRet="pygmiewarrior"; else if (nR<91) sRet="pygmyarcher"; else { sRet="pygmychampion"; } } // pygmys else if (sPrefix=="giantraid") { // giants if (nR<61) sRet="gntfrost001"; else if (nR<91) sRet="gntfrostfem001"; else { sRet="gntfrostfem002"; } } // giants return sRet; } // fnGetResRaider() int fnAllArrived(string sPrefix,object oDest) { // PURPOSE: Returns TRUE if all raiders have arrived object oOb; int nN; object oMod=GetModule(); nN=1; while(nN<=8) { // check all oOb=GetLocalObject(oMod,"o_"+sPrefix+"er_"+IntToString(nN)); if (oOb!=OBJECT_INVALID&&GetIsDead(oOb)==FALSE) { // valid creature if (GetArea(oDest)!=GetArea(oOb)||GetDistanceBetween(oOb,oDest)>9.9) return FALSE; } // valid creature nN++; } // check all return TRUE; } // fnAllArrived() void fnRaiderAI(string sPrefix) { // PURPOSE: Handle the movement of the spawned units object oMod=GetModule(); object oMe=OBJECT_SELF; object oDest; int nN; int nR; string sS; float fDelay; object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY); fDelay=6.0+(IntToFloat(Random(20))/10.0); if (oEnemy==OBJECT_INVALID&&GetIsInCombat(oMe)==FALSE&&IsInConversation(oMe)==FALSE) { // okay to move nN=GetLocalInt(oMod,"n_"+sPrefix+"er_dest"); if (nN==0) { // set initial destination nN=1; SetLocalInt(oMod,"n_"+sPrefix+"er_dest",nN); } // set initial destination PrintString("(nonteam_raiders) "+GetName(oMe)+" going to #:"+IntToString(nN)); oDest=GetWaypointByTag(sPrefix+"_"+IntToString(nN)); if (oDest!=OBJECT_INVALID) PrintString("===> The waypoint was found"); if (GetArea(oDest)!=GetArea(oMe)||GetDistanceBetween(oMe,oDest)>10.0) { // move AssignCommand(oMe,ASActionMoveToObject(oDest,TRUE,1.0)); } // move else { // check and see if everyone has arrived if (fnAllArrived(sPrefix,oDest)) { // all there sS=GetName(oDest); // choose next destination if (GetStringLeft(sS,1)=="R"||GetStringLeft(sS,1)=="r") { // random sS=GetStringRight(sS,GetStringLength(sS)-1); nR=Random(StringToInt(sS))+1; nN=nN+nR; } // random else if (GetStringLeft(GetStringUpperCase(sS),1)=="L") { // Outside Lair L_<# to go to if lair is PC controlled>.<# if not PC controlled> string sParse; string sID; object oLead; int nIfPC; int nIfNPC; sS=GetStringRight(sS,GetStringLength(sS)-1); sID=StringParse(sS,"_"); sS=StringRemoveParsed(sS,sID,"_"); sParse=StringParse(sS,"."); sS=StringRemoveParsed(sS,sParse,"."); nIfPC=StringToInt(sParse); nIfNPC=StringToInt(sS); oLead=GetLocalObject(oMod,"oTeamLead"+sID); if (!GetIsPC(oLead)||!GetIsObjectValid(oLead)) nN=nIfNPC; else { nN=nIfPC; } } // Outside Lair L_<# to go to if lair is PC controlled>.<# if not PC controlled> else { // fixed nN=StringToInt(sS); } // fixed if (nN!=0) { // valid destination SetLocalInt(oMod,"n_"+sPrefix+"er_dest",nN); } // valid destination else { // error SendMessageToPC(GetFirstPC(),"MONSTER RAIDER PATHING ERROR: '"+GetTag(oDest)+"' next destination resulted in a value of '"+IntToString(nN)+"' which should be a positive number!"); PrintString("MONSTER RAIDER PATHING ERROR: '"+GetTag(oDest)+"' next destination resulted in a value of '"+IntToString(nN)+"' which should be a positive number!"); DestroyObject(oMe); } // error } // all there } // check and see if everyone has arrived } // okay to move DelayCommand(fDelay,fnRaiderAI(sPrefix)); } // fnRaiderAI() void fnCheckRaiders(string sLeaderTag,string sPrefix,int nSpeed,int nMinLevel,int nCreatures) { // PURPOSE: Deal with raiders object oOb; object oMod=GetModule(); object oWP; int nN; int nC; int nSpawnSpeed=nSpeed; int nLastTime; int nCurrentTime; int nTimeDiff; int nDelay; if (nSpawnSpeed==0) { // default if (sPrefix=="duergarraid") nSpawnSpeed=2; else if (sPrefix=="boggleraid") nSpawnSpeed=4; else if (sPrefix=="barbraid") nSpawnSpeed=3; else if (sPrefix=="pygmyraid") nSpawnSpeed=3; else if (sPrefix=="dbanditraid") nSpawnSpeed=3; else if (sPrefix=="giantraid") nSpawnSpeed=1; else if (sPrefix=="ORCRAID") nSpawnSpeed=3; else if (sPrefix=="gnollraid") nSpawnSpeed=3; } // default oOb=GetObjectByTag(sLeaderTag); if (oOb!=OBJECT_INVALID) { // leader exists - okay to raid nLastTime=GetLocalInt(oMod,"nLastTime_"+sPrefix); if (nLastTime==0) { // set timer nLastTime=fnGetAbsoluteHour(); SetLocalInt(oMod,"nLastTime_"+sPrefix,nLastTime); } // set timer if (fnPlayerExistsWithLevel(nMinLevel)) { // PCs with high enough level are in play nCurrentTime=fnGetAbsoluteHour(); nTimeDiff=nCurrentTime-nLastTime; nDelay=8-nSpawnSpeed; if (nTimeDiff>=nDelay) { // possibly time to spawn some more nN=1; nC=0; oOb=GetLocalObject(oMod,"o_"+sPrefix+"er_"+IntToString(nN)); while(nN<=nCreatures) { // count raiders still living if (oOb!=OBJECT_INVALID&&GetIsDead(oOb)!=TRUE) nC++; nN++; oOb=GetLocalObject(oMod,"o_"+sPrefix+"er_"+IntToString(nN)); } // count raiders still living if (nC==0) { // no raiders left - create some more PrintString("(nonteam_raiders) Spawning "+sPrefix+" raiders"); oWP=GetWaypointByTag(sPrefix+"_spawn"); if (oWP==OBJECT_INVALID) oWP=GetWaypointByTag(sPrefix+"_SPAWN"); if (oWP!=OBJECT_INVALID) { // waypoint found nN=1; while(nN<=nCreatures) { // spawn new creatures oOb=CreateObject(OBJECT_TYPE_CREATURE,fnGetResRaider(sPrefix),GetLocation(oWP)); SetLocalObject(oMod,"o_"+sPrefix+"er_"+IntToString(nN),oOb); DeleteLocalInt(oMod,"n_"+sPrefix+"er_dest"); AssignCommand(oOb,fnRaiderAI(sPrefix)); SetAILevel(oOb,AI_LEVEL_NORMAL); nN++; } // spawn new creatures SetLocalInt(oMod,"nLastTime_"+sPrefix,nCurrentTime); } // waypoint found else { // error SendMessageToPC(GetFirstPC(),"Waypoint for monster raiders '"+sPrefix+"_spawn' could not be found!"); PrintString("ERROR: Waypoint for monster raiders '"+sPrefix+"_spawn' could not be found!"); } // error } // no raiders left - create some more } // possibly time to spawn some more } // PCs with high enough level are in play } // leader exists - okay to raid } // fnCheckRaiders() //////////////////////////////////////////////////////////////////////// MAIN void main() { object oMod=GetModule(); // settings 0=default, -1 = disabled, 1 = very slow, 2 = slow, 3 = mid, 4 = fast, 5 = very fast int nDuergar=GetLocalInt(oMod,"nduergarRaiders"); // 2 int nBoggle=GetLocalInt(oMod,"ndoggleRaiders"); // 4 int nBarbarian=GetLocalInt(oMod,"nbarbRaiders"); // 3 int nPygmy=GetLocalInt(oMod,"npygmyRaiders"); // 3 int nDesert=GetLocalInt(oMod,"ndbanditRaiders"); // 3 int nGiant=GetLocalInt(oMod,"ngiantRaiders"); // 1 int nOrc=GetLocalInt(oMod,"norcRaiders"); // 3 int nGnoll=GetLocalInt(oMod,"ngnollRaiders"); // 3 int bEasy=GetLocalInt(oMod,"bEasy"); int bChallenging=GetLocalInt(oMod,"bChallenging"); int nPop; int nLevel; if (nDuergar!=-1) { // duergar nPop=6; nLevel=4; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("duergarleader","duergarraid",nDuergar,nLevel,nPop); } // duergar if (nBoggle!=-1) { // boggle nPop=6; nLevel=3; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("boggleleader","boggleraid",nBoggle,nLevel,nPop); } // boggle if (nBarbarian!=-1) { // barbarian nPop=8; nLevel=4; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("barbleader","barbraid",nBarbarian,nLevel,nPop); } // barbarian if (nPygmy!=-1) { // pygmy nPop=8; nLevel=3; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("pygmyleader","pygmyraid",nPygmy,nLevel,nPop); } // pygmy if (nDesert!=-1) { // desert bandits nPop=6; nLevel=4; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("dbanditleader","dbanditraid",nDesert,nLevel,nPop); } // desert bandits if (nGiant!=-1) { // Giants nPop=4; nLevel=9; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("giantleader","giantraid",nGiant,nLevel,nPop); } // Giants if (nOrc!=-1) { // Orcs nPop=8; nLevel=3; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("orcleader","ORCRAID",nOrc,nLevel,nPop); } // Orcs if (nGnoll!=-1) { // gnolls nPop=6; nLevel=4; if (bEasy) { nPop=nPop/2; nLevel=nLevel*2; } else if (bChallenging) nLevel=nLevel-1; fnCheckRaiders("gnollleader","gnollraid",nGnoll,nLevel,nPop); } // gnolls } ///////////////////////////////////////////////////////////////////////// MAIN