Amon_PRC8/_module/nss/em_follow.nss
Jaysyn904 c5cffc37af Initial Commit
Initial Commit [v1.01]
2025-04-03 19:00:46 -04:00

80 lines
3.1 KiB
Plaintext

// FOLLOW SCRIPT
// Now normally an NPC when it has to follow a player would have an entry in
// it's heartbeat script, however it'd be inpractical to go thru all of VoC
// and recode the heartbeat scripts to find and follow the master.
//
// This script is triggered on summoning a monster and loops until it dies
// so the monster will follow it's master without any module-wide or on-creature
// heartbeat scripts being utilised. Additionally the monster despite the lack of
// a heartbeat script will even use the more basic player commands
void WalkLoop(object oPlayer)
{
object oMonster = GetHenchman(oPlayer);
int iCommand = GetLastAssociateCommand(oMonster);
object oItem = GetLocalObject(oMonster, "loMyStone");
int iLastCommand = GetLocalInt(oMonster, "liLastCommand");
int iLifeLeft = GetMaxHitPoints(oMonster) - GetCurrentHitPoints(oMonster);
if(GetIsObjectValid(oMonster)){
if (iCommand == ASSOCIATE_COMMAND_ATTACKNEAREST){
object oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, oMonster, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN);
AssignCommand(oMonster, ActionAttack(oTarget));
}
else if (iCommand == ASSOCIATE_COMMAND_STANDGROUND){
// Do nothing
}
else if (iCommand == ASSOCIATE_COMMAND_LEAVEPARTY){
SetLocalString(oItem, "lsResRef", "");
SetLocalInt(oItem, "liDamage", 0);
RemoveHenchman(oPlayer, oMonster);
SendMessageToPC(oPlayer, "You said I can leave, bye then!");
PlayVoiceChat(VOICE_CHAT_GOODBYE, oMonster);
DelayCommand(2.0, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_1), GetLocation(oMonster)));
DestroyObject(oMonster, 2.1);
}
else {
AssignCommand(oMonster, ActionMoveToObject(oPlayer, TRUE));
}
// If new orders are given, play a random confirmation
if (iLastCommand != iCommand && iCommand != ASSOCIATE_COMMAND_LEAVEPARTY){
int iStyle;
switch (Random(3)){
case 0:
iStyle = VOICE_CHAT_CANDO;
break;
case 1:
iStyle = VOICE_CHAT_GOODIDEA;
break;
case 2:
iStyle = VOICE_CHAT_YES;
break;
}
PlayVoiceChat(iStyle, oMonster);
}
SetLocalInt(oMonster, "liLastCommand", iCommand);
SetLocalInt(oItem, "liDamage", iLifeLeft); // Write creatures hit points to variable now so if they die they can't just be resummoned.
DelayCommand(6.0, WalkLoop(oPlayer)); // Loop it every 6 seconds
}
}
void main()
{
DelayCommand(2.0, WalkLoop(OBJECT_SELF));
}
/*
NOTES:
- Initial Loop MUST be delayed at least 1 second otherwise character won't have
time to be assigned as Henchman causing the GetObjectIsValid command to return
false and in turn prematurly ending the Loop without it even trying to follow
you.
*/