This first version works for creatures only. I
haven't yet figured out how to get an alignment out of an item. I also
haven't implemented any line of sight rules yet. This works using a 60ft (18
Metre) diameter range.
The first four functions are helpers for the actual Detect_Evil procedure.
I tried to keep it as close to the 3E Player's Handbook description as
possible, but took some liberties in implementation. Particularly with the
aura strength and the stun feature. I just decided that if the GoodEvil
value of the creature was in the highest range, that was good enough to stun
the caster if they are of a good alignment.
Other than that, it is pretty true to the actual spell. Round 1 shows
presence of evil.
Round 2 shows the number of evil creatures and the strongest aura. If the
strongest aura is overwhelming and the caster is of a good alignment, they
are stunned for a round.
Round 3 shows the exact location of each aura using a distance and compass
heading from the caster.
Feel free to make changes, but please keep my name on it
I'll post this in the sticky as well.
-E
NWScript:
string AuraPower(int iEvilPoints)
{
if((iEvilPoints <= 49) && (iEvilPoints >= 36))
return "Faint";
if((iEvilPoints <= 35) && (iEvilPoints >= 24))
return "Moderate";
if((iEvilPoints <= 23) && (iEvilPoints >= 12))
return "Strong";
if((iEvilPoints <= 11) && (iEvilPoints >= 0))
return "Overwhelming";
return "None";
}
void GetDirection(float fFacing,object oCaster,object oCreature, float nDistance)
{
if (fFacing >= 360.0)
fFacing = 720.0 - fFacing;
if (fFacing < 0.0)
fFacing += (360.0);
int iFacing = FloatToInt(fFacing);
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 = FloatToString(nDistance);
string sEvil = AuraPower(GetGoodEvilValue(oCreature));
SendMessageToPC(oCaster, sEvil + " evil detected " + sDistance + " metres to the " + sDirection);
}
object GetNearest(object oCaster, int iCount)
{
return GetNearestObjectToLocation(OBJECT_TYPE_CREATURE,GetLocation(oCaster),iCount);
}
void Detect_Evil_By_Round(object oCaster,int iRound)
{
float RANGE = 18.0;
int MIN_EVIL = 49;
int iEvilCreatureCount = 0;
int iMostEvil = 0;
int iCount = 1;
float nDistance = 0.0;
string sDistance = "";
string sEvil = "";
int bEvilDetected = FALSE;
location lCreature;
vector vCreature;
location lCaster = GetLocation(oCaster);
object oCreature = GetNearest(oCaster,iCount);
while((GetIsObjectValid(oCreature)) && (GetDistanceBetween(oCaster,oCreature) <= RANGE))
{
nDistance = GetDistanceBetween(oCaster,oCreature);
if(GetGoodEvilValue(oCreature) >= MIN_EVIL)
{
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(GetGoodEvilValue(oCreature) > iMostEvil)
iMostEvil = GetGoodEvilValue(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(iMostEvil <= 11)
{
if(GetAlignmentGoodEvil(oCaster)==ALIGNMENT_GOOD)
{
SendMessageToPC(oCaster,"The most evil is so " + AuraPower(iMostEvil) + " that you are mementarily stunned!");
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectStunned(),oCaster,ROUND);
AssignCommand(oCaster,ActionWait(ROUND));
}
}
else
SendMessageToPC(oCaster,"The most evil is " + AuraPower(iMostEvil));
return;
}
}
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)));
}
float ROUND = 6.0;
void main()
{
object oActivated = GetItemActivated();
object oPlayer = GetItemPossessor(oActivated);
if(GetName(oActivated) == "Ring of Detect Evil")
Detect_Evil(oPlayer);
}
|