246 lines
11 KiB
Plaintext
246 lines
11 KiB
Plaintext
#include "x3_inc_string"
|
|
#include "wazoo_h"
|
|
#include "nw_i0_generic"
|
|
#include "prc_inc_util"
|
|
#include "prc_inc_racial"
|
|
|
|
////////////////////////////////////////
|
|
// FUNCTIONS
|
|
////////////////////////////////////////
|
|
|
|
void fnPossessiveHenchman(object oMaster)
|
|
{ // PURPOSE: Follow Master
|
|
object oMe=OBJECT_SELF;
|
|
object oAreaMe=GetArea(oMe);
|
|
object oAreaMaster=GetArea(oMaster);
|
|
object oEnemy=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oMe,1,CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN,CREATURE_TYPE_REPUTATION,REPUTATION_TYPE_ENEMY);
|
|
if (!GetIsDead(oMaster)&&GetIsObjectValid(oMaster))
|
|
{ // okay to follow
|
|
float fDistance=GetDistanceBetween(oMe,oMaster);
|
|
if (GetCurrentAction(oMaster)==ACTION_REST)
|
|
{ // rest
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,30.0));
|
|
AssignCommand(oMe,ActionDoCommand(PRCForceRest(oMe)));
|
|
DelayCommand(30.5,fnPossessiveHenchman(oMaster));
|
|
} // rest
|
|
else if (GetArea(oMe)!=GetArea(oMaster))
|
|
{ // might be time to jump
|
|
int bJumpOK=TRUE;
|
|
if (!GetLocalInt(oAreaMe,"bOP")&&GetLocalInt(oAreaMaster,"bOP")) bJumpOK=TRUE;
|
|
if (bJumpOK)
|
|
{ // okay to jump
|
|
AssignCommand(oMe,ClearAllActions(TRUE));
|
|
AssignCommand(oMe,JumpToObject(oMaster));
|
|
DelayCommand(3.0,fnPossessiveHenchman(oMaster));
|
|
} // okay to jump
|
|
else
|
|
{ // despawn
|
|
AssignCommand(oMe,ClearAllActions());
|
|
DelayCommand(2.0,fnPossessiveHenchman(OBJECT_INVALID));
|
|
} // despawn
|
|
} // might be time to jump
|
|
else if (GetIsInCombat(oMe)&&fDistance>40.0)
|
|
{ // master is too far away abort combat
|
|
AssignCommand(oMe,ClearAllActions(TRUE));
|
|
AssignCommand(oMe,ActionMoveToObject(oMaster,TRUE,4.5));
|
|
DelayCommand(3.0,fnPossessiveHenchman(oMaster));
|
|
} // master is too far away abort combat
|
|
else if (!GetIsInCombat(oMe)&&fDistance>30.0)
|
|
{ // jump to master
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,JumpToObject(oMaster));
|
|
DelayCommand(3.0,fnPossessiveHenchman(oMaster));
|
|
} // jump to master
|
|
else if (!GetIsInCombat(oMe)&&fDistance>5.0)
|
|
{ // move to master
|
|
AssignCommand(oMe,ActionMoveToObject(oMaster));
|
|
DelayCommand(6.0,fnPossessiveHenchman(oMaster));
|
|
} // move to master
|
|
else
|
|
{ // delay
|
|
if (GetIsObjectValid(oEnemy))
|
|
{ // attack
|
|
AssignCommand(oMe,ClearAllActions());
|
|
DetermineCombatRound(oEnemy);
|
|
} // attack
|
|
DelayCommand(3.0,fnPossessiveHenchman(oMaster));
|
|
} // delay
|
|
} // okay to follow
|
|
else
|
|
{ // despawn
|
|
if (!GetIsInCombat(oMe)&&!GetIsDMPossessed(oMe)&&!GetIsObjectValid(oEnemy))
|
|
{ // okay to despawn
|
|
DestroyObject(oMe);
|
|
} // okay to despawn
|
|
else
|
|
{ // allow interaction
|
|
DelayCommand(10.0,fnPossessiveHenchman(OBJECT_INVALID));
|
|
} // allow interaction
|
|
} // despawn
|
|
} // fnPossessiveHenchman()
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////[ MAIN ]/////
|
|
void main()
|
|
{
|
|
object oPC=GetItemActivator();
|
|
string sRes=GetResRef(GetItemActivated());
|
|
object oTarget=GetItemActivatedTarget();
|
|
object oItem=GetItemActivated();
|
|
effect eE1;
|
|
effect eE2;
|
|
float fDur;
|
|
int nLevel=GetLevelByPosition(1,oPC)+GetLevelByPosition(2,oPC)+GetLevelByPosition(3,oPC);
|
|
if (sRes=="rts_srbr1")
|
|
{ // blur
|
|
fDur=IntToFloat(nLevel)*20.0;
|
|
eE1=EffectVisualEffect(VFX_DUR_BLUR);
|
|
eE2=EffectACIncrease(4);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eE1,oPC,fDur);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eE2,oPC,fDur);
|
|
SendMessageToPC(oPC,"You use your blur ability.");
|
|
if (GetItemCharges(oItem)==0) DestroyObject(oItem);
|
|
} // blur
|
|
else if (sRes=="rts_srwm1")
|
|
{ // Burst of Speed
|
|
fDur=IntToFloat(nLevel)*15.0;
|
|
SetLocalInt(oPC,"bBurstOfSpeed",TRUE);
|
|
DelayCommand(fDur,DeleteLocalInt(oPC,"bBurstOfSpeed"));
|
|
SendMessageToPC(oPC,"You use your burst of speed ability.");
|
|
DelayCommand(fDur+0.1,SendMessageToPC(oPC,StringToRGBString("Burst of speed done","777")));
|
|
if (GetItemCharges(oItem)==0) DestroyObject(oItem);
|
|
} // Burst of Speed
|
|
else if (sRes=="rts_srwm2")
|
|
{ // Charm Feline
|
|
int bDestroy=FALSE;
|
|
int bValid=FALSE;
|
|
string sRes=GetResRef(oTarget);
|
|
if (GetItemCharges(oItem)==0) DestroyObject(oItem);
|
|
if (sRes=="sum4cg"||sRes=="sum2wood"||sRes=="sum8cave")
|
|
{ // banish
|
|
bDestroy=TRUE;
|
|
bValid=TRUE;
|
|
} // banish
|
|
else if (sRes=="rdcommon4"||sRes=="cougar001"||sRes=="cragcat001"||sRes=="jaguar001") bValid=TRUE;
|
|
else if (sRes=="cat001"||sRes=="lion001"||sRes=="beastmalar002"||sRes=="panther001") bValid=TRUE;
|
|
else if (sRes=="panther001"||sRes=="displacerbeast"||sRes=="manticore"||sRes=="jaguar002") bValid=TRUE;
|
|
else if (sRes=="hellcat"||sRes=="werecat001") bValid=TRUE;
|
|
if (bValid)
|
|
{ // valid target
|
|
if (bDestroy)
|
|
{ // banish
|
|
FloatingTextStringOnCreature("You banish "+GetName(oTarget)+".",oPC,FALSE);
|
|
effect eVFX=EffectVisualEffect(VFX_IMP_UNSUMMON);
|
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eVFX,GetLocation(oTarget));
|
|
GiveXPToCreature(oPC,GetLevelByPosition(1,oTarget)+GetLevelByPosition(2,oTarget)+GetLevelByPosition(3,oTarget));
|
|
DelayCommand(0.5,DestroyObject(oTarget));
|
|
} // banish
|
|
else
|
|
{ // control
|
|
object oMaster=GetMaster(oTarget);
|
|
if (GetIsObjectValid(oMaster))
|
|
{ // degroup
|
|
RemoveHenchman(oMaster,oTarget);
|
|
} // degroup
|
|
string sTeamID=GetLocalString(oPC,"sTeamID");
|
|
oMaster=GetObjectByTag(sTeamID+"_PROXY");
|
|
ChangeFaction(oTarget,oMaster);
|
|
SetIsTemporaryFriend(oTarget,oMaster);
|
|
SetIsTemporaryFriend(oMaster,oTarget);
|
|
AssignCommand(oTarget,ClearAllActions(TRUE));
|
|
FloatingTextStringOnCreature("You permanently charm "+GetName(oTarget)+".",oPC,FALSE);
|
|
GiveXPToCreature(oPC,GetLevelByPosition(1,oTarget)+GetLevelByPosition(2,oTarget)+GetLevelByPosition(3,oTarget));
|
|
DeleteLocalInt(oTarget,"nMState");
|
|
DeleteLocalInt(oTarget,"nSState");
|
|
SetAILevel(oTarget,AI_LEVEL_NORMAL);
|
|
AssignCommand(oTarget,fnPossessiveHenchman(oPC));
|
|
} // control
|
|
} // valid target
|
|
else
|
|
{ // no effect
|
|
FloatingTextStringOnCreature(StringToRGBString("That ability had no effect on that target.","777"),oPC,FALSE);
|
|
} // no effect
|
|
} // Charm Feline
|
|
else if (sRes=="rts_srdr2")
|
|
{ // Dancing Lights
|
|
AssignCommand(oPC,ActionCastSpellAtObject(SPELL_WZ_DANCING_LIGHTS,oPC,METAMAGIC_ANY,TRUE,0,PROJECTILE_PATH_TYPE_DEFAULT,TRUE));
|
|
SendMessageToPC(oPC,"You use your dancing lights ability.");
|
|
if (GetItemCharges(oItem)==0) DestroyObject(oItem);
|
|
} // Dancing Lights
|
|
else if (sRes=="rts_srwm3")
|
|
{ // Rage
|
|
fDur=IntToFloat(nLevel)*15.0;
|
|
eE1=EffectAbilityIncrease(ABILITY_STRENGTH,4);
|
|
eE2=EffectTemporaryHitpoints(10);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eE1,oPC,fDur);
|
|
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eE2,oPC,fDur);
|
|
SendMessageToPC(oPC,"You use your rage ability.");
|
|
if (GetItemCharges(oItem)==0) DestroyObject(oItem);
|
|
} // Rage
|
|
else if (sRes=="rts_srwm4")
|
|
{ // Sense Life
|
|
int nN;
|
|
object oOb;
|
|
vector vVec;
|
|
float fDistance;
|
|
string sDir;
|
|
int nRace;
|
|
vector vMe=GetPosition(oPC);
|
|
float fTest;
|
|
string sType;
|
|
string sMsg;
|
|
SendMessageToPC(oPC,"You reach out with your enhanced senses to sense life in the area.");
|
|
nN=1;
|
|
oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN);
|
|
while(GetIsObjectValid(oOb))
|
|
{ // find all life
|
|
nRace=MyPRCGetRacialType(oOb);
|
|
if (nRace!=RACIAL_TYPE_UNDEAD&&nRace!=RACIAL_TYPE_CONSTRUCT&&nRace!=RACIAL_TYPE_ELEMENTAL&&!GetLocalInt(oOb,"nIsVampire")&&!GetLocalInt(oOb,"bUndead"))
|
|
{ // senseable
|
|
if (!GetHasSpellEffect(SPELL_IMPROVED_INVISIBILITY,oOb))
|
|
{ // not improved invisible
|
|
vVec=GetPosition(oOb);
|
|
fTest=vVec.y-vMe.y;
|
|
sDir="";
|
|
if (fTest<-8.0) sDir="S";
|
|
else if (fTest>8.0) sDir="N";
|
|
fTest=vVec.x-vMe.x;
|
|
if (fTest<-8.0) sDir="W";
|
|
else if (fTest>8.0) sDir="E";
|
|
sType="Unknown";
|
|
if (nRace==RACIAL_TYPE_ANIMAL) sType="Animal";
|
|
else if (nRace==RACIAL_TYPE_BEAST) sType="Beast";
|
|
else if (nRace==RACIAL_TYPE_DRAGON) sType="Dragon";
|
|
else if (nRace==RACIAL_TYPE_DWARF) sType="Dwarf";
|
|
else if (nRace==RACIAL_TYPE_ELF||nRace==RACIAL_TYPE_FEY) sType="Sylvan";
|
|
else if (nRace==RACIAL_TYPE_GIANT) sType="Giant";
|
|
else if (nRace==RACIAL_TYPE_GNOME||nRace==RACIAL_TYPE_HALFLING) sType="Small One";
|
|
else if (nRace==RACIAL_TYPE_HALFORC||nRace==RACIAL_TYPE_HUMANOID_ORC) sType="Orc";
|
|
else if (nRace==RACIAL_TYPE_HALFELF||nRace==RACIAL_TYPE_HUMAN) sType="Human";
|
|
else if (nRace==RACIAL_TYPE_HUMANOID_GOBLINOID) sType="Goblin";
|
|
else if (nRace==RACIAL_TYPE_HUMANOID_REPTILIAN) sType="Lizardkind";
|
|
else if (nRace==RACIAL_TYPE_OOZE) sType="Ooze";
|
|
else if (nRace==RACIAL_TYPE_OUTSIDER) sType="Planar Being";
|
|
else if (nRace==RACIAL_TYPE_SHAPECHANGER) sType="Shapechanger";
|
|
else if (nRace==RACIAL_TYPE_VERMIN) sType="Vermin";
|
|
fDistance=GetDistanceBetween(oPC,oOb);
|
|
sMsg=StringToRGBString(sType,"777");
|
|
sMsg=sMsg+"["+StringToRGBString(sDir,"366")+"]";
|
|
sMsg=sMsg+" Distance:"+IntToString(FloatToInt(fDistance));
|
|
sMsg=sMsg+" (X:"+IntToString(FloatToInt(vVec.x))+", Y:";
|
|
sMsg=sMsg+IntToString(FloatToInt(vVec.y))+")";
|
|
SendMessageToPC(oPC,sMsg);
|
|
} // not improved invisible
|
|
} // senseable
|
|
nN++;
|
|
oOb=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oPC,nN);
|
|
} // find all life
|
|
SendMessageToPC(oPC,"Sensing completed.");
|
|
if (GetItemCharges(oItem)==0) DestroyObject(oItem);
|
|
} // Sense Life
|
|
}
|
|
///////////////////////////////////////////////////////////////////[ MAIN ]/////
|