Files
HeroesStone_PRC8/_module/nss/detect_evil.nss
Jaysyn904 1eefc84201 Initial Commit
Initial Commit.
2025-09-14 15:40:46 -04:00

423 lines
15 KiB
Plaintext

/*
Script modified by Ceros.
September 8, 2002
*/
#include "prc_inc_racial"
int AuraStrength(object oEvil)
{
int iLevel = 0;
int bHasCleric = FALSE;
int i;
// Loop through class slots 1-8
for (i = 1; i <= 8; i++)
{
iLevel += GetLevelByPosition(i, oEvil);
if (GetClassByPosition(i, oEvil) == CLASS_TYPE_CLERIC)
{
bHasCleric = TRUE;
}
}
int iAlignGE = GetAlignmentGoodEvil(oEvil);
int iRace = MyPRCGetRacialType(oEvil);
int iHD = GetHitDice(oEvil);
int iEvilPower;
if (iRace == RACIAL_TYPE_UNDEAD && iAlignGE == ALIGNMENT_EVIL)
{
iEvilPower = iHD / 2;
}
else if (iRace == RACIAL_TYPE_ELEMENTAL && iAlignGE == ALIGNMENT_EVIL)
{
iEvilPower = iHD / 2;
}
else if (iRace == RACIAL_TYPE_OUTSIDER && iAlignGE == ALIGNMENT_EVIL)
{
iEvilPower = iHD;
}
else if (bHasCleric && iAlignGE == ALIGNMENT_EVIL && GetDeity(oEvil) != "")
{
iEvilPower = iLevel;
}
else
iEvilPower = iHD / 5;
return iEvilPower;
}
/* int AuraStrength(object oEvil)
{
int iLv1 = GetLevelByPosition(1,oEvil);
int iLv2 = GetLevelByPosition(2,oEvil);
int iLv3 = GetLevelByPosition(3,oEvil);
int iLevel = iLv1 + iLv2 + iLv3;
int iCl1 = GetClassByPosition(1,oEvil);
int iCl2 = GetClassByPosition(2,oEvil);
int iCl3 = GetClassByPosition(3,oEvil);
int iAlignGE = GetAlignmentGoodEvil(oEvil);
int iRace = MyPRCGetRacialType(oEvil);
int iHD = GetHitDice(oEvil);
int iEvilPower;
if (iRace == RACIAL_TYPE_UNDEAD && iAlignGE == ALIGNMENT_EVIL)
{
iEvilPower = iHD / 2;
}
else if (iRace == RACIAL_TYPE_ELEMENTAL && iAlignGE == ALIGNMENT_EVIL)
{
iEvilPower = iHD / 2;
}
else if (iRace == RACIAL_TYPE_OUTSIDER && iAlignGE == ALIGNMENT_EVIL)
{
iEvilPower = iHD;
}
else if ((iCl1 == CLASS_TYPE_CLERIC || iCl2 == CLASS_TYPE_CLERIC ||
iCl3 == CLASS_TYPE_CLERIC) && iAlignGE == ALIGNMENT_EVIL &&
GetDeity(oEvil) != "")
{
iEvilPower = iLevel;
}
else iEvilPower = iHD / 5;
return iEvilPower;
}
*/
//Return a string describing the strength of the evil
string AuraPower(int iEvilPower)
{
if (iEvilPower <= 1)
{
return "Faint";
}
else if (iEvilPower >= 2 && iEvilPower <= 4)
{
return "Moderate";
}
else if (iEvilPower >= 5 && iEvilPower <= 10)
{
return "Strong";
}
else if (iEvilPower >= 11)
{
return "Overwhelming";
}
return "";
}
// Author: Big E
// Date: July 20, 2002
// Given the facing value (0-360), set the compass direction and diplay
// the loction and distance of the evil.
void GetDirection(float fFacing,object oCaster,object oCreature, float nDistance)
{
//Correct the bug in GetFacing (Thanks Iskander)
if (fFacing >= 360.0)
fFacing = 720.0 - fFacing;
if (fFacing < 0.0)
fFacing += (360.0);
int iFacing = FloatToInt(fFacing);
// 359 - 2 = E
// 3 - 45 = NEE
// 46 - 87 = NNE
// 88 - 92 = N
// 93 - 135 = NNW
// 136 - 177 = NWW
// 178 - 182 = W
// 183 - 225 = SWW
// 226 - 267 = SSW
// 268 - 272 = S
// 273 - 315 = SSE
// 316 - 358 = SEE
string sDirection = "";
if((iFacing >= 359) && (iFacing <= 2))
sDirection = "E";
if((iFacing >= 3) && (iFacing <= 45))
sDirection = "NEE";
if((iFacing >= 46) && (iFacing <= 87))
sDirection = "NNE";
if((iFacing >= 88) && (iFacing <= 92))
sDirection = "N";
if((iFacing >= 93) && (iFacing <= 135))
sDirection = "NNW";
if((iFacing >= 136) && (iFacing <= 177))
sDirection = "NWW";
if((iFacing >= 178) && (iFacing <= 182))
sDirection = "W";
if((iFacing >= 183) && (iFacing <= 225))
sDirection = "SWW";
if((iFacing >= 226) && (iFacing <= 267))
sDirection = "SSW";
if((iFacing >= 268) && (iFacing <= 272))
sDirection = "S";
if((iFacing >= 273) && (iFacing <= 315))
sDirection = "SSE";
if((iFacing >= 316) && (iFacing <= 358))
sDirection = "SEE";
string sDistance = IntToString(FloatToInt(nDistance));
//Evil Power
string sEvil = AuraPower(AuraStrength(oCreature));
SendMessageToPC(oCaster, sEvil + " evil detected about " + sDistance + " metres to the " + sDirection);
}
//Author: Big E
//Date: July 20, 2002
object GetNearest(object oCaster, int iCount)
{
return GetNearestObjectToLocation(OBJECT_TYPE_CREATURE,GetLocation(oCaster),iCount);
}
//Author Big E
//Date: July 20, 2002
//Insert you meathod of alignment hiding here.
//Return True if creature's alignment is hidden.
int Alignment_Hidden(object oCreature)
{
if(GetName(GetItemInSlot(INVENTORY_SLOT_LEFTRING,oCreature)) == "Ring of Hide Alignment")
return TRUE;
if(GetName(GetItemInSlot(INVENTORY_SLOT_RIGHTRING,oCreature)) == "Ring of Hide Alignment")
return TRUE;
return FALSE;
}
//Author: Big E
//Date: July 20, 2002
//Detect Evil By Round
void Detect_Evil_By_Round(object oCaster, int iRound)
{
float RANGE = 35.29; // Range in metres
int iEvilCreatureCount = 0;
int iMostEvil = 0;
int iCount = 1;
float nDistance = 0.0;
int bEvilDetected = FALSE;
location lCreature;
vector vCreature;
location lCaster = GetLocation(oCaster);
object oCreature = GetNearest(oCaster, iCount);
// Calculate the caster's total level using a loop
int iLevel = 0;
int i;
for (i = 1; i <= 8; i++)
{
iLevel += GetLevelByPosition(i, oCaster);
}
while ((GetIsObjectValid(oCreature)) && (GetDistanceBetween(oCaster, oCreature) <= RANGE))
{
nDistance = GetDistanceBetween(oCaster, oCreature);
if ((GetAlignmentGoodEvil(oCreature) != ALIGNMENT_EVIL) || (Alignment_Hidden(oCreature)))
{
iCount++;
oCreature = GetNearest(oCaster, iCount);
continue;
}
bEvilDetected = TRUE;
lCreature = GetLocation(oCreature);
if (iRound == 1)
{
if (GetLocation(oCaster) != GetLocalLocation(oCaster, "lPlayer"))
{
SendMessageToPC(oCaster, "Concentration broken. Detect evil cancelled.");
ClearAllActions();
return;
}
SendMessageToPC(oCaster, "There is evil present.");
return;
}
if (iRound == 2)
{
if (GetLocation(oCaster) != GetLocalLocation(oCaster, "lPlayer"))
{
SendMessageToPC(oCaster, "Concentration broken. Detect evil cancelled.");
ClearAllActions();
return;
}
iEvilCreatureCount++;
if (AuraStrength(oCreature) > iMostEvil)
{
iMostEvil = AuraStrength(oCreature);
}
}
if (iRound == 3)
{
if (GetLocation(oCaster) != GetLocalLocation(oCaster, "lPlayer"))
{
SendMessageToPC(oCaster, "Concentration broken. Detect evil cancelled.");
ClearAllActions();
return;
}
vCreature = GetPosition(oCreature);
AssignCommand(oCaster, SetFacingPoint(vCreature));
AssignCommand(oCaster, GetDirection(GetFacing(oCaster), oCaster, oCreature, nDistance));
}
iCount++;
oCreature = GetNearest(oCaster, iCount);
}
if ((iRound == 2) && (bEvilDetected))
{
SendMessageToPC(oCaster, "There are " + IntToString(iEvilCreatureCount) + " evil creatures present.");
if (AuraPower(iMostEvil) == "Overwhelming")
{
if (GetAlignmentGoodEvil(oCaster) == ALIGNMENT_GOOD && iMostEvil > (2 * iLevel))
{
SendMessageToPC(oCaster, "The most evil aura is so " + GetStringLowerCase(AuraPower(iMostEvil)) + " that you are momentarily stunned!");
if (!GetIsImmune(oCaster, IMMUNITY_TYPE_MIND_SPELLS))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectStunned(), oCaster, ROUND);
}
else
{
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_STUN), oCaster);
AssignCommand(oCaster, ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_TIRED, 1.0, ROUND));
DelayCommand(0.5, SetCommandable(FALSE, oCaster));
DelayCommand(ROUND, SetCommandable(TRUE, oCaster));
}
return;
}
else
SendMessageToPC(oCaster, "The most evil aura is " + GetStringLowerCase(AuraPower(iMostEvil)));
}
}
if ((iRound == 1) && (!bEvilDetected))
{
SendMessageToPC(oCaster, "You can't seem to sense any evil auras nearby...");
}
}
/* void Detect_Evil_By_Round(object oCaster,int iRound)
{
float RANGE = 35.29; //Range in metres
// int MIN_EVIL = 29; //The number at which the evil outweighs the good
int iEvilCreatureCount = 0; //The number of evil auras in range
int iMostEvil = 0; //The lowest GoodEvil value
int iCount = 1; //A counter to cycle through creatures
float nDistance = 0.0; //The distance away from the caster of the creature
string sDistance = ""; //String version of nDistance
string sEvil = ""; //Aura strength
int bEvilDetected = FALSE; //Evil found?
location lCreature; //Location of the creature
vector vCreature; //Vector location of the creature
//Get the location of the caster
location lCaster = GetLocation(oCaster);
//Get the first closest creature to the caster
object oCreature = GetNearest(oCaster,iCount);
int iLv1 = GetLevelByPosition(1,oCaster);
int iLv2 = GetLevelByPosition(2,oCaster);
int iLv3 = GetLevelByPosition(3,oCaster);
int iLevel = iLv1 + iLv2 + iLv3;
while((GetIsObjectValid(oCreature)) && (GetDistanceBetween(oCaster,oCreature) <= RANGE))
{
nDistance = GetDistanceBetween(oCaster,oCreature);
if((GetAlignmentGoodEvil(oCreature) != ALIGNMENT_EVIL) || (Alignment_Hidden(oCreature))) //Not Evil or alignment hidden?
{
//Go on to the next creature
iCount++;
oCreature = GetNearest(oCaster,iCount);
continue;
}
bEvilDetected = TRUE; //Evil found
lCreature = GetLocation(oCreature);
//Round 1 - Evil presence detected
if (iRound == 1)
{
if(GetLocation(oCaster) != GetLocalLocation(oCaster,"lPlayer"))
{
SendMessageToPC(oCaster, "Concentration broken. Detect evil cancelled.");
ClearAllActions();
return;
};
SendMessageToPC(oCaster,"There is evil present.");
return;
}
//Round 2 - Number of evil aura's
if(iRound == 2)
{
if(GetLocation(oCaster) != GetLocalLocation(oCaster,"lPlayer"))
{
SendMessageToPC(oCaster, "Concentration broken. Detect evil cancelled.");
ClearAllActions();
return;
};
iEvilCreatureCount++;
if (AuraStrength(oCreature) > iMostEvil)
{
iMostEvil = AuraStrength(oCreature);
}
}
//Round 3
if(iRound == 3)
{
if(GetLocation(oCaster) != GetLocalLocation(oCaster,"lPlayer"))
{
SendMessageToPC(oCaster, "Concentration broken. Detect evil cancelled.");
ClearAllActions();
return;
};
//Get the creature's vector
vCreature = GetPosition(oCreature);
//Face the creature
AssignCommand(oCaster,SetFacingPoint (vCreature));
//Get the compass direction of the creature
AssignCommand(oCaster,GetDirection(GetFacing(oCaster),oCaster,oCreature,nDistance));
}
iCount++;
oCreature = GetNearest(oCaster,iCount);
}
if((iRound == 2) && (bEvilDetected))
{
SendMessageToPC(oCaster,"There are " + IntToString(iEvilCreatureCount) + " evil creatures present.");
if(AuraPower(iMostEvil) == "Overwhelming")
{
//If the caster is good, they are stunned by the overwhelming evil
if(GetAlignmentGoodEvil(oCaster)==ALIGNMENT_GOOD && iMostEvil > (2 * iLevel))
{
SendMessageToPC(oCaster,"The most evil aura is so " + GetStringLowerCase(AuraPower(iMostEvil)) + " that you are momentarily stunned!");
if (!GetIsImmune(oCaster,IMMUNITY_TYPE_MIND_SPELLS))
{
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectStunned(),oCaster,ROUND);
}
else
{
ApplyEffectToObject(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_IMP_STUN),oCaster);
AssignCommand(oCaster,ActionPlayAnimation(ANIMATION_LOOPING_PAUSE_TIRED,1.0,ROUND));
DelayCommand(0.5,SetCommandable(FALSE,oCaster));
DelayCommand(ROUND,SetCommandable(TRUE,oCaster));
}
return;
}
else
SendMessageToPC(oCaster,"The most evil aura is " + GetStringLowerCase(AuraPower(iMostEvil)));
}
}
if ((iRound == 1) && (!bEvilDetected))
{
SendMessageToPC(oCaster,"You can't seem to sense any evil auras nearby...");
}
}
*/
//Author: Big E
//Date: July 20, 2002
void Detect_Evil(object oCaster)
{
SetLocalLocation(oCaster,"lPlayer",GetLocation(oCaster));
DelayCommand(ROUND,AssignCommand(oCaster,Detect_Evil_By_Round(oCaster,1)));
DelayCommand(ROUND+ROUND,AssignCommand(oCaster,Detect_Evil_By_Round(oCaster,2)));
DelayCommand(ROUND+ROUND+ROUND,AssignCommand(oCaster,Detect_Evil_By_Round(oCaster,3)));
}
//Example using a ring of detect evil for event OnActivateItem
float ROUND = RoundsToSeconds(1); //Need this defined. I use a six second round
void main()
{
effect eHead = EffectVisualEffect(VFX_IMP_HEAD_MIND);
ApplyEffectToObject(DURATION_TYPE_INSTANT,eHead,OBJECT_SELF);
Detect_Evil(OBJECT_SELF);
object oActivated = GetItemActivated();
object oPlayer = GetItemPossessor(oActivated);
if(GetName(oActivated) == "Paladin's Detect Evil Sense")
Detect_Evil(oPlayer);
}