Author Topic: Problem with Portal Scripts  (Read 363 times)

Legacy_Zejan the Wonder Monkey

  • Jr. Member
  • **
  • Posts: 61
  • Karma: +0/-0
Problem with Portal Scripts
« on: September 24, 2012, 12:03:56 am »


               After going on a bug run for the umpteenth time, I have discovered a script that simply won't work under the conditions I want it to.  This is how it's supposed to go:  Under certain conditions, a portal is spawned in at a specific waypoint [this part works just fine].  An imp is also spawned in as a first instance, as if it came from the portal [this part works too].

The problem comes with the conditions i'm trying to set for the scenario.  The imp is supposedly regenerated by the portal each time it's killed, up to four times.  For some reason, setting it as an if/then/else decision simply doesn't work.  Here's what I have - first in the portal userdef:

[nwscript]
//:: portal_make_imp
//::////////////////////////////////////////////////////////////////////////////
/*
  The village is plagued by a portal that spawns a pesky, regenerating imp.
*/
//::////////////////////////////////////////////////////////////////////////////
void main()
{
 int nCount;
 //object oPC = GetFirstPC();
 object oPortal = OBJECT_SELF;
 object oImp = GetObjectByTag("PortalImp");
 location lPortal = GetLocation(oPortal);
 int nUser = GetUserDefinedEventNumber();
 if(nUser == 100)
   {
    if(GetLocalInt(OBJECT_SELF, "PortalCount") <= 4)
      {
       CreateObject(OBJECT_TYPE_CREATURE, "portal_imp", lPortal);
       DelayCommand(0.5, ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
                    EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD), lPortal));
       nCount = GetLocalInt(OBJECT_SELF, "PortalCount");
       nCount++;
       SetLocalInt(OBJECT_SELF, "PortalCount", nCount);
       SetLocalInt(oImp, "PortalCount", nCount);
       SpeakString("Portal count is: " + IntToString(GetLocalInt(OBJECT_SELF, "PortalCount")), TALKVOLUME_SHOUT);
       SpeakString("Imp count is: " + IntToString(GetLocalInt(oImp, "PortalCount")), TALKVOLUME_SHOUT);
      }
    }
 else if(nUser == 200)
   {
    object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR,
                                    PLAYER_CHAR_IS_PC, OBJECT_SELF, 1);
    SpeakString("The imp appears to have been defeated...for now, at least.", TALKVOLUME_SHOUT);
    SetLocalInt(oPC, "KilledPortalImp", 10);
    AddJournalQuestEntry("StrangeMagic", 35, oPC, TRUE, FALSE, FALSE);
   }
}
[/nwscript]

And this is for the imp's onDeath script:

[nwscript]
void main()
{
 if(GetLocalInt(GetModule(), "ImpPortalGone") == TRUE) return;
 object oPortal = GetObjectByTag("ImpPortal");
 event eMoreImps = EventUserDefined(100);
 event eNoMoreImps = EventUserDefined(200);
 if(GetLocalInt(OBJECT_SELF, "PortalCount") == 4)
   {
    SignalEvent(oPortal, eNoMoreImps);
   }
 else
   {
    SignalEvent(oPortal, eMoreImps);
   }
}
[/nwscript]

I need for the evernt 200 code to fire after the last imp dies.  The shouts are showing me that the variable has been set on both the portal and the imp.  I'm just not getting it...*sigh*. 
               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #1 on: September 24, 2012, 03:24:27 pm »


               I think you're setting the variable on the wrong imp.

If you're in the nUser=100 case you've looked up an imp but are creating a new one.
The one you looked up presumably is the one that just died. You then set the count on
that one not the one you just created so you when you kill the new one the variable is not set
and you get event 100 again.

Try
    oImp = CreateObject(OBJECT_TYPE_CREATURE, "portal_imp", lPortal);


Cheers,

Meaglyn
               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #2 on: September 24, 2012, 03:29:41 pm »


               Also, fwiw, why bother with the extra variable on the imp? You've looked up the portal in the
onDeath script. Why not just read the portal's variable there anyway?

Cheers,

Meaglyn
               
               

               
            

Legacy_Zejan the Wonder Monkey

  • Jr. Member
  • **
  • Posts: 61
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #3 on: September 24, 2012, 11:50:22 pm »


               The extra variable was just a test to see if the code was working at all.  It'll be removed once I know everything is working.  And thanks so much for the reply, I'm doing some debugging right now so I can plug that in and test it.
               
               

               
            

Legacy_Zejan the Wonder Monkey

  • Jr. Member
  • **
  • Posts: 61
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #4 on: September 27, 2012, 01:26:56 am »


               Made some slight changes as well, but now it appears to be fixed.  Still have to test in game, but spot testing appears to do nicely.  Many thanks!  : )
               
               

               
            

Legacy_Pattycake1

  • Jr. Member
  • **
  • Posts: 98
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #5 on: October 04, 2012, 12:22:24 am »


               I'm just curious on why youre using two scripts when all you need is one. You can do every thing on the OnDeath script. That would make it easier to manage and trouble shoot.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #6 on: October 04, 2012, 02:28:34 am »


               I myself, Like the idea of using an event handler for things like this.  The main reason is that the imp that is being killed will no longer be around after it is killed.  with the imp object being destroyed, you can not store locals on it to refferance them later. since another object needs to be used for that, It might as well be an event handler.  

I do agree that all of the processing should be done in one script.   It would be simpler if the Imp's OnDeath Script Simply signaled a IMP_DIED Event instead of deciding what event to signal.  That processing should be done by the event handler not the Imp's death script.
               
               

               
            

Legacy_Pattycake1

  • Jr. Member
  • **
  • Posts: 98
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #7 on: October 04, 2012, 10:29:06 am »


               Not sure why you have ‘ if(GetLocalInt(GetModule(),"ImpPortalGone")== TRUE) return; ‘ in your script. But I’m going to assume its because you are creating a single player module. If not then you will have to change this part to include all party members in the area and not just the one player.

object oPC = GetNearestCreature(CREATURE_TYPE_pLAYER_cHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF, 1); SpeakString("The imp appears to have been defeated... for now, at least.",TALKVOLUME_SHOUT); SetLocalInt(oPC, "KilledPortalImp",10); AddJournalQuestEntry("StrangeMagic",35,oPC,TRUE,FALSE,FALSE);

Place this on your OnDeath script.

Void main() { object oPortal = GetObjectByTag("ImpPortal"); location lPortal = GetLocation(oPortal); if(GetLocalInt(GetModule(),"ImpPortalGone")== TRUE) return;// not sure why this is here... if(GetLocalInt(oPortal, "PortalCount")<=4) // this will make sure the bottom part happens when the imp dies 4 times. { //Visual effect happens first then the imp appears, just made more sense to me, but you can change that if you want.

ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FN_SUMMON_UNDEAD),lPortal); DelayCommand(0.5, CreateObject(OBJECT_TYPE_CREATURE,"portal_imp",lPortal)); SetLocalInt(oPortal,"PortalCount", GetLocalInt(oPortal,"PortalCount") +1); // every time the imp dies the count is increased by 1 } else { // adds visual effect while destroying portal

DelayCommand(0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FN_SUMMON_UNDEAD),lPortal)); DelayCommand(0.5,DestroyObject(oImp));// destroys portal object oPC = GetNearestCreature(CREATURE_TYPE_pLAYER_cHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF, 1); SpeakString("The imp appears to have been defeated... for now, at least.",TALKVOLUME_SHOUT); SetLocalInt(oPC, "KilledPortalImp",10); AddJournalQuestEntry("StrangeMagic",35,oPC,TRUE,FALSE,FALSE); } }

If you notice the count is done to the portal not on the imp. Makes it easier to keep track of. Doing it this way makes it so that every thing is done in one script instead of two which makes it easier to trouble shoot and change.
               
               

               
            

Legacy_Pattycake1

  • Jr. Member
  • **
  • Posts: 98
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #8 on: October 04, 2012, 10:32:14 am »


               LOL for give the crampt posting of the above script. I posted from my phone and it acts weird some times. The above script is just a suggestion and nothing more. If you got it to work your way then stick with that.
               
               

               
            

Legacy_Pattycake1

  • Jr. Member
  • **
  • Posts: 98
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #9 on: October 04, 2012, 10:47:49 am »


               Not sure why you have ‘ if(GetLocalInt(GetModule(),"ImpPortalGone")== TRUE) return; ‘ in your script. But I’m going to assume its because you are creating a single player module. If not then you will have to change this part to include all party members in the area and not just the one player.

object oPC = GetNearestCreature(CREATURE_TYPE_pLAYER_cHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF, 1); SpeakString("The imp appears to have been defeated... for now, at least.",TALKVOLUME_SHOUT); SetLocalInt(oPC, "KilledPortalImp",10); AddJournalQuestEntry("StrangeMagic",35,oPC,TRUE,FALSE,FALSE);

Place this on your OnDeath script.

Void main()
{
object oPortal = GetObjectByTag("ImpPortal");
location lPortal = GetLocation(oPortal);
if(GetLocalInt(GetModule(),"ImpPortalGone")== TRUE) return;// not sure why this is here... if(GetLocalInt(oPortal, "PortalCount")<=4) // this will make sure the bottom part happens when the imp dies 4 times.
{
//Visual effect happens first then the imp appears, just made more sense to me, but you can change that if you want.
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FN_SUMMON_UNDEAD),lPortal);
DelayCommand(0.5, CreateObject(OBJECT_TYPE_CREATURE,"portal_imp",lPortal)); SetLocalInt(oPortal,"PortalCount", GetLocalInt(oPortal,"PortalCount") +1); // every time the imp dies the count is increased by 1
}
else
{
// adds visual effect while destroying portal
DelayCommand(0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FN_SUMMON_UNDEAD),lPortal));
DelayCommand(0.5,DestroyObject(oImp));// destroys portal object
oPC = GetNearestCreature(CREATURE_TYPE_pLAYER_cHAR,PLAYER_CHAR_IS_PC,OBJECT_SELF, 1); SpeakString("The imp appears to have been defeated... for now, at least.",TALKVOLUME_SHOUT); SetLocalInt(oPC, "KilledPortalImp",10); AddJournalQuestEntry("StrangeMagic",35,oPC,TRUE,FALSE,FALSE);
 }
}

Hope this is easier to read
               
               

               
            

Legacy_Pattycake1

  • Jr. Member
  • **
  • Posts: 98
  • Karma: +0/-0
Problem with Portal Scripts
« Reply #10 on: October 04, 2012, 03:14:12 pm »


               Okay now that i'm home you can try this script. It compiles and should work. It also gets party members in the immediate area so as not to give the quest variables to every one in the party that wasnt there.

const float PARTY_DISTANCE = 40.0;
void main()
{
object oPortal = GetObjectByTag("ImpPortal");
object oImp;
location lPortal = GetLocation(oPortal);
if(GetLocalInt(GetModule(),"ImpPortalGone")== TRUE) return;// not sure why this is here...
if(GetLocalInt(oPortal, "PortalCount")<=4) // this will make sure the bottom part happens when the imp dies 4 times.
  {
    //Visual effect happens first then the imp appears, just made more sense to me, but you can change that if you want.
    location lPortal = GetLocation(oPortal);
    DelayCommand(0.1, ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD),lPortal));
    oImp = CreateObject(OBJECT_TYPE_CREATURE, "portal_imp", lPortal);
    SetLocalInt(oPortal,"PortalCount", GetLocalInt(oPortal,"PortalCount") +1); // every time the imp dies the count is increased by 1
  }
else
  {
    object oImp = OBJECT_SELF;
    // adds visual effect while destroying portal
    DelayCommand(0.5,ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD),lPortal));
    DelayCommand(0.5,DestroyObject(oImp));// destroys portal object
    //Who KIlled this creature?
    object oKiller = GetLastKiller();
    if (!GetIsPC(oKiller) && !GetIsPC(GetMaster(oKiller)))  return;
    object oKillersArea = GetArea(oKiller);
    //Determine the first member of the Killer's Party:
    object oPartyMember = GetFirstFactionMember(oKiller, FALSE);
    while (GetIsObjectValid(oPartyMember))
     {
        object oPartyMembersArea = GetArea(oPartyMember);
        // Be certain the party member is alive and is within the appropriate distance:
        float fDistance = GetDistanceBetween(oKiller,oPartyMember);
        if (!GetIsDead(oPartyMember) && oKillersArea == oPartyMembersArea && fDistance >= 0.0 && fDistance <= PARTY_DISTANCE)
        {
                // Make sure its a PC:
                if(GetIsPC(oPartyMember))
                  {
                    SetLocalInt(oPartyMember, "KilledPortalImp",10);
                    AddJournalQuestEntry("StrangeMagic",35,oPartyMember,TRUE,FALSE,FALSE);
                    SendMessageToPC(oPartyMember,"The imp appears to have been defeated... for now, at least.");
                  }
        }
        oPartyMember = GetNextFactionMember(oKiller, FALSE);
     }
  }
}