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

313 lines
12 KiB
Plaintext

////////////////////////////////////////////////////
// OnHeartbeat for the Shadow Realm
//--------------------------------------------------
// By Deva Bryson Winblood. 01/2003
//==================================================
// This realm is responsive to light.
// Light sources
// Torch: NW_IT_TORCH001
// Light Spell VFX_DUR_LIGHT
// Glittering Necklace nw_it_mneck023
// Ring of Jade nw_it_mring011
// Ring of Cyan nw_it_mring009
// Ring of Crimson nw_it_mring010
/////////////////////////////////////////////////////
// All PCs that have a light source active will
// attract beings from the plane of shadows
// 50% Shadow nw_shadow CR 3
// 25% Shadow Mastif nw_shmastif CR 4
// 15% Shadow Fiend nw_shfiend CR 7
// 10% Bodak nw_bodak CR 9
// Night Hag nighthag CR 8
// Nightwalker nightwalker CR 20
/////////////////////////////////////////////////////////
// The death scripts have been altered so, the player
// cannot return to the inn. In addition, the emergency
// recall scroll will return them here. They must escape
// on their own.
/////////////////////////////////////////////////////////
// Escape method: Each door must be passed through once
// to get to the next Shadow Realm.
// Eventually, they will return to the real world.
// This is a difficult quest and will be worth significant
// experience.
////////////////////////////////////////////////////////////
// When light source is present there is a 15% per heartbeat
// of a monster being spawned to deal with the player if
// they have a light source activated. No more than 8 monsters
// at any given time will be spawned.
////////////////////////////////////////////////////////////
#include "prc_inc_skin"
string fnSpawnType(object oPC)
{ // return resref of creature to spawn
string sRet="nw_shadow1";
int nLevel=GetLevelByPosition(1,oPC);
int nR=d100();
nLevel=nLevel+GetLevelByPosition(2,oPC);
nLevel=nLevel+GetLevelByPosition(3,oPC);
if (nLevel<3)
{ // lowest level
if (nR<75) sRet="nw_shadow1";
else if (nR<95) sRet="nw_shmastif1";
else if (nR<100) sRet="nw_shfiend1";
else { sRet="nw_bodak1"; }
} // lowest level
else if (nLevel<6)
{ // second stage
if (nR<50) sRet="nw_shadow1";
else if (nR<80) sRet="nw_shmastif1";
else if (nR<98) sRet="nw_shfiend1";
else { sRet="nw_bodak1"; }
} // second stage
else if (nLevel<10)
{ // third stage
if (nR<33) sRet="nw_shadow1";
else if (nR<50) sRet="nw_shmastif1";
else if (nR<80) sRet="nw_shfien1";
else if (nR<95) sRet="nw_bodak1";
else { sRet="nighthag"; }
} // third stage
else if (nLevel<15)
{ // fourth stage
if (nR<20) sRet="nw_shadow1";
else if (nR<33) sRet="nw_shmastif1";
else if (nR<50) sRet="nw_shfiend1";
else if (nR<80) sRet="nw_bodak1";
else { sRet="nighthag"; }
} // fourth stage
else if (nLevel<19)
{ // fifth stage
if (nR<10) sRet="nw_shadow1";
else if (nR<20) sRet="nw_shmastif1";
else if (nR<33) sRet="nw_shfiend1";
else if (nR<50) sRet="nw_bodak1";
else if (nR<90) sRet="nighthag";
else { sRet="nightwalker"; }
} // fifth stage
else
{ // final stage
if (nR<10) sRet="nw_shfiend1";
else if (nR<33) sRet="nw_bodak1";
else if (nR<75) sRet="nighthag";
else { sRet="nightwalker"; }
} // final stage
return sRet;
} // fnSpawnType()
int HasLightSource(object oT)
{ // check to see if the object has a light source ready
int nRet=FALSE;
effect eTest;
object oItem;
string sTag;
effect eCompare1=EffectVisualEffect(VFX_DUR_LIGHT);
effect eCompare2=EffectVisualEffect(VFX_DUR_LIGHT_WHITE_20);
effect eCompare3=EffectVisualEffect(VFX_DUR_LIGHT_WHITE_15);
effect eCompare4=EffectVisualEffect(VFX_DUR_LIGHT_WHITE_10);
effect eCompare5=EffectVisualEffect(VFX_DUR_LIGHT_WHITE_5);
effect eCompare6=EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_20);
effect eCompare7=EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_15);
effect eCompare8=EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_10);
effect eCompare9=EffectVisualEffect(VFX_DUR_LIGHT_YELLOW_5);
effect eCompare10=EffectVisualEffect(VFX_DUR_LIGHT_BLUE_20);
effect eCompare11=EffectVisualEffect(VFX_DUR_LIGHT_BLUE_15);
effect eCompare12=EffectVisualEffect(VFX_DUR_LIGHT_GREY_20);
effect eCompare13=EffectVisualEffect(VFX_DUR_LIGHT_ORANGE_20);
effect eCompare14=EffectVisualEffect(VFX_DUR_LIGHT_PURPLE_20);
effect eCompare15=EffectVisualEffect(VFX_DUR_LIGHT_RED_20);
oItem=GetItemInSlot(INVENTORY_SLOT_ARMS,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_BELT,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_BOOTS,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
//oItem=GetItemInSlot(INVENTORY_SLOT_CARMOUR,oT);
oItem = GetPCSkin(oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_CHEST,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_CLOAK,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_HEAD,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_LEFTRING,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_NECK,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
oItem=GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oT);
if (GetItemHasItemProperty(oItem,ITEM_PROPERTY_LIGHT)==TRUE) nRet=TRUE;
if (nRet!=TRUE)
{ // test for light spell effect
eTest=GetFirstEffect(oT);
while(GetEffectType(eTest)!=EFFECT_TYPE_INVALIDEFFECT&&nRet==FALSE)
{ // check for light
if(eTest==eCompare1) nRet=TRUE;
else if (eTest==eCompare2) nRet=TRUE;
else if (eTest==eCompare3) nRet=TRUE;
else if (eTest==eCompare4) nRet=TRUE;
else if (eTest==eCompare5) nRet=TRUE;
else if (eTest==eCompare6) nRet=TRUE;
else if (eTest==eCompare7) nRet=TRUE;
else if (eTest==eCompare8) nRet=TRUE;
else if (eTest==eCompare9) nRet=TRUE;
else if (eTest==eCompare10) nRet=TRUE;
else if (eTest==eCompare11) nRet=TRUE;
else if (eTest==eCompare12) nRet=TRUE;
else if (eTest==eCompare13) nRet=TRUE;
else if (eTest==eCompare14) nRet=TRUE;
else if (eTest==eCompare15) nRet=TRUE;
eTest=GetNextEffect(oT);
} // check for light
} // test for light spell effect
oItem=GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oT);
sTag=GetResRef(oItem);
if (sTag=="nw_it_torch001") nRet=TRUE;
sTag=GetName(oItem);
if (sTag=="Torch") nRet=TRUE;
return nRet;
} // HasLightSource()
int CountShadowCreatures()
{ // return number of active shadow creatures
int nRet=0;
object oWP=GetWaypointByTag("SHADOW_DOWN_THE_WELL");
int nC=1;
object oCR=GetNearestObject(OBJECT_TYPE_CREATURE,oWP,nC);
while(oCR!=OBJECT_INVALID)
{ // count them
if (!GetIsPC(oCR))
{ // is not a PC
if (GetIsEnemy(GetFirstPC(),oCR)==TRUE)
nRet++;
} // is not a PC
nC++;
oCR=GetNearestObject(OBJECT_TYPE_CREATURE,oWP,nC);
} // count them
return nRet;
} // CountShadowCreatures()
/*string GetCreatureAttracted()
{ // determine resref of Shadow creature attracted
string sRet="";
int nD=d100();
if (nD<16)
{ // an encounter occurred
nD=d100();
if (nD<51) sRet="nw_shadow"; // a shadow
else if (nD<76) sRet="nw_shmastif"; // a shadow mastif
else if (nD<91) sRet="nw_shfiend"; // a shadow fiend
else sRet="nw_bodak"; // a bodak
} // an encounter occurred
return sRet;
} // GetCreatureAttracted()*/
////////////////////////////////////////////////// MAIN ////////////////////
void main()
{
object oPC=GetFirstPC();
object oWP=GetWaypointByTag("SHADOW_DOWN_THE_WELL");
object oCP;
int nCount=1;
object oCR=GetNearestObject(OBJECT_TYPE_CREATURE,oWP,nCount);
int nHostiles;
object oAttract;
object oATarget;
object oMod=GetModule();
string sShadow;
int nC;
float fDist;
float fDist1;
float fDist2;
object oOldTarget;
int nRun=FALSE;
if (GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,oWP,1)!=OBJECT_INVALID)
{ // PCs in area
while(oCR!=OBJECT_INVALID)
{ // check creatures for light source
nRun=FALSE;
if(HasLightSource(oCR)==TRUE)
{ // carrying a light
oATarget=oCR;
nHostiles=CountShadowCreatures();
if (nHostiles<8)
{ // possibly attract another
sShadow=fnSpawnType(oCR);
if (GetStringLength(sShadow)>1)
{ // yes one was attracted
oCP=GetWaypointByTag("SHAD2_SPAWN_"+IntToString(d6()));
if (oCP!=OBJECT_INVALID&&GetObjectType(oCP)==OBJECT_TYPE_WAYPOINT)
{ // valid spawn location
oAttract=CreateObject(OBJECT_TYPE_CREATURE,sShadow,GetLocation(oCP));
if (oAttract!=OBJECT_INVALID)
{ // was conjured
fDist1=GetDistanceBetween(oCR,oAttract);
oOldTarget=GetLocalObject(oAttract,"oTarget");
fDist2=GetDistanceBetween(oOldTarget,oAttract);
if (oOldTarget==OBJECT_INVALID||GetArea(oOldTarget)!=GetArea(oAttract)||fDist1<fDist2)
{
SetLocalObject(oAttract,"oTarget",oCR);
if(d8()<5) nRun=TRUE;
if (GetIsInCombat(oAttract)==FALSE&&IsInConversation(oAttract)==FALSE)
{
AssignCommand(oAttract,ClearAllActions());
AssignCommand(oAttract,ActionForceMoveToObject(oCR,nRun,3.0,90.0));
}
}
} // was conjured
} // valid spawn location
} // yes one was attracted
} // possibly attract another
} // carrying a light
if (GetIsEnemy(oPC,oCR)==TRUE)
{ // this is a hostile make sure still has a target
oAttract=GetLocalObject(oCR,"oTarget");
if (oAttract==OBJECT_INVALID&&oATarget!=OBJECT_INVALID)
{ // assign default
SetLocalObject(oCR,"oTarget",oATarget);
if(d8()<5) nRun=TRUE;
AssignCommand(oCR,ActionForceMoveToObject(oATarget,nRun,3.0,90.0));
} // assign default
else if ((GetArea(oAttract)!=GetArea(oCR)||HasLightSource(oAttract)==FALSE)&&
(GetDistanceBetween(oAttract,oCR)>10.0))
{ // change targets
SetLocalObject(oCR,"oTarget",oATarget);
if(d8()<5) nRun=TRUE;
AssignCommand(oCR,ActionForceMoveToObject(oATarget,nRun,3.0,90.0));
} // change targets
} // this is a hostile make sure still has a target
oATarget=GetLocalObject(oCR,"oTarget");
if (GetDistanceBetween(oATarget,oCR)==0.0)
{ // target is not here
SetLocalObject(oCR,"oTarget",OBJECT_INVALID);
oATarget=GetNearestObjectByTag("soul_token",oCR,1);
fDist=GetDistanceBetween(oCR,oATarget);
if (fDist!=0.0&&fDist<15.0)
{ // move to soul and eat it
nC=GetLocalInt(oMod,"nShadowSouls");
AssignCommand(oCR,ActionForceMoveToLocation(GetLocation(oATarget),TRUE,1.0));
DestroyObject(oCR);
nC++;
SetLocalInt(oMod,"nShadowSouls",nC);
} // move to soul and eat it
} // target is not here
nCount++;
oCR=GetNearestObject(OBJECT_TYPE_CREATURE,oWP,nCount);
} // check creatures for light source
} // PCs in area
DelayCommand(1.0,ExecuteScript("area_hb_clean",OBJECT_SELF));
}
////////////////////////////////////////////////////////////////////////////