This is the OnEnter event for a trigger that creates the NPCs and sets the PC object on the NPCs.
void main()
{
object oPC = GetEnteringObject();
if( !GetIsPC(oPC) ) return;
if( GetLocalInt(Getdbobj(oPC),"LIBRARY") == 3 )
{
effect eAppear = EffectVisualEffect(VFX_FNF_SUMMON_MONSTER_3);
//Get the waypoints to spawn the creatures at
object oDR = GetWaypointByTag("DEMONRETRIEVER");
object oMF = GetWaypointByTag("MFMASTER");
//Apply the summon VFX for each
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eAppear,GetLocation(oDR));
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eAppear,GetLocation(oMF));
//Create the monsters
object o1 = CreateObject(OBJECT_TYPE_CREATURE,"demonretriever",GetLocation(oDR),FALSE,GetName(oPC)+"1");
object o2 = CreateObject(OBJECT_TYPE_CREATURE,"mindflayermaster",GetLocation(oMF),FALSE,GetName(oPC)+"2");
//Set the PC object on the monsters
SetLocalObject(o1,"PC",oPC);
SetLocalObject(o2,"PC",oPC);
SetLocalInt(Getdbobj(oPC),"LIBRARY",5);
AddJournalQuestEntry("LIBRARY",5,oPC,FALSE);
}
}
That part works. They spawn with the visual.
MagicalMaster, on 24 Feb 2015 - 12:33 AM, said:
If you change the code to this, what happens?
else if(nUser == EVENT_END_COMBAT_ROUND || GetUserDefinedEventNumber() == 1003) // END OF COMBAT
{
string sTag = GetTag(OBJECT_SELF);
if( GetLocalInt(OBJECT_SELF,"BOOK") == 1 )
{
AssignCommand(GetObjectByTag("SCREAMER"),ActionSpeakString("1 Marked with BOOK",TALKVOLUME_SHOUT));//DEBUG
SpeakString("1");
//I CHANGED HERE HOW I GET oPC
//object oPC = GetLocalObject(OBJECT_SELF,"PC");
object oPC = GetFirstPC();
AssignCommand(GetObjectByTag("SCREAMER"),ActionSpeakString("2 PC name is: "+GetName(oPC),TALKVOLUME_SHOUT));//DEBUG
SpeakString("2 "+GetName(oPC));
if( GetIsDead(oPC) )
{
AssignCommand(GetObjectByTag("SCREAMER"),ActionSpeakString("3 PC is dead",TALKVOLUME_SHOUT));//DEBUG
SpeakString("3 "+GetTag(OBJECT_SELF));
effect eGhost = EffectCutsceneGhost();
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eGhost,OBJECT_SELF);
object oBook = GetFirstItemInInventory(oPC);
while( GetIsObjectValid(oBook) )
{
if( GetTag(oBook) == "LIBRARY1" ) {
AssignCommand(GetObjectByTag("SCREAMER"),ActionSpeakString("4 Book is in inventory",TALKVOLUME_SHOUT));//DEBUG
SpeakString("4");
break;
}
oBook = GetNextItemInInventory(oPC);
}
ActionMoveToObject(oPC);
AssignCommand(GetObjectByTag("SCREAMER"),ActionSpeakString("5 I should be moving to the person",TALKVOLUME_SHOUT));//DEBUG
SpeakString("5");
ActionTakeItem(oBook,oPC);
ActionSpeakString("It has the other book we want!");
ActionPlayAnimation(ANIMATION_FIREFORGET_VICTORY1,1.0,6.0);
ActionSpeakString("Let us take these to the artificers.");
ActionMoveToObject(GetWaypointByTag("DST_TSD1"));
//DelayCommand(18.0, DestroyObject(OBJECT_SELF));
}}
What messages does the NPC say?
I added my changed code in the box above. The NPCs say all the parts exactly how I'd expect. Meaning, they spawn and attack the player. While the player is still alive, the NPCs will say #1 (because they are marked to run end combat round events) and #2 with the correct name for the player (because they are getting the correct player object) at the end of each round. **note that I changed how I was getting the oPC to GetFirstPC() since I'm testing with only one player on the server and wanted to rule out that the player object I set in the trigger OnEnter wasn't somehow wrong.
The NPCs don't say 3, 4 and 5 until I'm dead. Which they do nicely right about the time the battle music quits after they've killed me. But then they just stand there. So it seems I've got the right oPC object, I've got the event firing and the code within firing too.
Adding ClearAllActions(TRUE); before the ActionMoveToObject(oPC) doesn't make any difference either. I was hopeful on this one.
Oh, I got something that worked!
else if(nUser == EVENT_END_COMBAT_ROUND || GetUserDefinedEventNumber() == 1003) // END OF COMBAT
{
string sTag = GetTag(OBJECT_SELF);
if( GetLocalInt(OBJECT_SELF,"BOOK") == 1 )
{
object oPC = GetLocalObject(OBJECT_SELF,"PC");
if( GetIsDead(oPC) )
{
effect eGhost = EffectCutsceneGhost();
ApplyEffectToObject(DURATION_TYPE_PERMANENT,eGhost,OBJECT_SELF);
object oBook = GetFirstItemInInventory(oPC);
while( GetIsObjectValid(oBook) )
{
if( GetTag(oBook) == "LIBRARY1" )
break;
oBook = GetNextItemInInventory(oPC);
}
object oSelf;
if( sTag == GetName(oPC)+"1" )
{
oSelf = GetObjectByTag(GetName(oPC)+"1");
AssignCommand(oSelf,ActionMoveToObject(oPC));
AssignCommand(oSelf,ActionTakeItem(oBook,oPC));
AssignCommand(oSelf,ActionSpeakString("It has the other book we want!"));
AssignCommand(oSelf,ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0,4.0));
AssignCommand(oSelf,ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING,1.0,4.0));
AssignCommand(oSelf,ActionSpeakString("Let us take these to the artificers."));
AssignCommand(oSelf,ActionMoveToObject(GetWaypointByTag("DST_TSD1")));
}
else
{
oSelf = GetObjectByTag(GetName(oPC)+"2");
AssignCommand(oSelf,ActionMoveToObject(oPC));
AssignCommand(oSelf,ActionWait(8.0));
AssignCommand(oSelf,ActionMoveToObject(GetWaypointByTag("DST_TSD1")));
}
DelayCommand(18.0, DestroyObject(OBJECT_SELF));
}}
It looks like using AssignCommand worked. I'm not entirely sure why I would have to assign the actions for it to work since this code is run from the UserDefined event handle on the NPC - the NPC is the object calling the code so ActionMoveToObject(oPC) should add the action to the queue of the object calling the script. Hmm, well. Hmm.
Thanks for the posts and ideas. I was about to scrap this and y'all helped me stick with it long enough to get it working.