Author Topic: NPC-Only-Doors?  (Read 469 times)

Legacy_Wyndhane

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
NPC-Only-Doors?
« on: November 13, 2012, 07:42:02 pm »


               Hello, venerable people of the NWN1 Scripting forum. I once again turn to you for help, puzzled and clueless, with what is probably an embarrassingly banal problem.

Using the Mobile/Immobile Ambient Animations system, I thought I'd make an area the PC is not meant to frequent marked as NW_HOME (I'm using a different section of the same area for the introduction sequence, so the PC has visited the area and the NPCs in it start moving and everything), to put a bulltoad of daytime-street-filling peasants into. Issue being, I can't seem to get the doors to let the NPCs through, but not the PC.

If I stick in an OnAreaTransitionClick script that gives PCs an error message and aborts the script and otherwise ports the user to the desired exit location, the NPCs can't pass through anymore either. I assume this probably has something to do with the scripts that define the actions of mobile-ambient-animations-activated NPCs and will now proceed to check those out, if I can manage to find them.

If any of you fine folks happen to have the answer for me, that would be super convenient and altogether awesome of you. ^^ Arright, more experimenting for me.
               
               

               
            

Legacy_ehye_khandee

  • Hero Member
  • *****
  • Posts: 1415
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #1 on: November 13, 2012, 08:34:52 pm »


               if(GetIsPC(GetLastUsedBy())return;


^^^ make that the first line of your custom script and all will work as intended (NPC only can use door).

Be well. Game on.
GM_ODA

P.S. if that does not sufficiently illuminate the issue, PM me and I will send you the whole script.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #2 on: November 13, 2012, 08:51:04 pm »


               That will also keep out a DM though. So I'd change the check to
object oUser = GetLastUsedBy();
if(GetIsPC(oUser)&&!GetIsDM(oUser)) return;

I think that would do it.

My preference however would be to give the PC some text feedback to explain the situation. Something akin to...nothing of interest to the adventure exists beyond this door. Or the like.
               
               

               
            

Legacy_Wyndhane

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #3 on: November 13, 2012, 09:07:58 pm »


               Yay, I love you people. '<img'>


Mine went;
-----------------------------------
void main()
{

object oUser = GetLastUsedBy();
if (GetIsPC(oUser))
    {
    FloatingTextStringOnCreature("You have no reason to go in here.", oUser);
    return;
    }

AssignCommand(oUser, ClearAllActions());
AssignCommand(oUser, ActionJumpToLocation(GetLocation(GetObjectByTag("STORAGE"))));

}
-----------------------------------

I cut out the first part and replaced it with a plain "if (GetIsPC(oUser)) return;" just now, still doesn't work. If I was on the right track with the first part, I suppose that means there must be something wrong with the second part. '<img'>

"STORAGE" here is a Waypoint in the middle of a largeish room with numerous doors leading to different places throughout the city. What am I doing wrong? Am I ClearAllActions-ing the jump command away by calling it at the same time? Should I delay the jump command or something? Do Ambient-Animations-NPCs for some reason not like teleporting like normal people? Have I completely messed up something about the jumping process? D:
               
               

               
            

Legacy_Wyndhane

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #4 on: November 13, 2012, 10:22:27 pm »


               Continuted experiments with different variants of the same script led to me switching switching to AssignCommand - ActionSpeakString for the error message, which by itself has no message being delivered at all.

Adding a 0.1 second delay before that, as in,
DelayCommand(0.1, AssignCommand(oUser, ActionSpeakString("You have no reason to go in here.")));
has the PC correctly delivering the error message upon trying to use the door.

Very interesting development: So do the NPCs' attempts to use the door... And by that I mean, they make the PC speak the error line (if the PC has previously used the door and thus qualifies to be the Last User of the door) not the NPC who attempted to use the door. BUT: If the NPC does not *use* the door or call it's scripts to transition, therefore not becoming the Last User, why does adding a script that prevents the player from passing through the door also stop NPCs?

Another interesting observation: If the door is closed at the time, the NPC who reaches it first and gets to *open* the door successfully transitions. All others remain standing in/before it, looking lost.

Also worth noting: Without a script in OnAreaTransitionClick, all NPCs (and, of course, the PC, which is not desired) transition successfully.


I... think I need to find the scripts that define the behavior of mobile-ambient-animations-active NPCs. The answer must be lurking in them. Gonna update my findings if I somehow, miraculously, manage to figure it out, for posterity and all.
Further helpful suggestions and/or solutions are always welcome. ^^
               
               

               


                     Modifié par Wyndhane, 13 novembre 2012 - 10:22 .
                     
                  


            

Legacy_ehye_khandee

  • Hero Member
  • *****
  • Posts: 1415
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #5 on: November 14, 2012, 12:37:21 am »


               PM'd you back friend.

Btw, a DM is a PC too, but a special one. So a DM possessed NPC is still a DM and thus a PC for script purposes.

Be well. Game on.
GM_ODA
               
               

               


                     Modifié par ehye_khandee, 14 novembre 2012 - 12:39 .
                     
                  


            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #6 on: November 14, 2012, 01:22:50 am »


               Also worth noting: Without a script in OnAreaTransitionClick, all NPCs (and, of course, the PC, which is not desired) transition successfully.

Yes and this is because that is way doors work.  In your case you are trying to make a special door only useable by npc's.  So the problems are.
1. The first npc can use the door and transition properly.
Probable cause:  The door is not closing and reseting after all if the door is not closed there will be no opening of it. Also on area transition click might be problematic for npc's though I am not sure on this one.

One thing you could try would be to put a trigger on the ground in front of the door and forget about fooling with the door itself.  This trigger would be on enter and have the script perhaps spin the PC around and say a vile smell repels you from the door. This incidentally would solve the problem of the PC speaking the line inappropriately as is happening currently, and could be use in front of any door. To make it more random you could have a random message on a switch to give any number of reasons the PC would not want to or be allowed ingress into the building.
               
               

               
            

Legacy_Wyndhane

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #7 on: November 14, 2012, 01:30:46 am »


               Wait... wait. Wait. Logic did not fail me after all; It was I who failed at logic. Some hours after my original realizations, I at long last successfully combine them! Of course the NPC who *opened* the door would transition; It has USED the door and therefore become the target of GetLastUsedBy, which apparently does not happen on a transition click! Admittedly, that doesn't make a whole lot of sense, since there are separate commands for that (GetLastOpenedBy and GetLastClosedBy), but that seems to be what's happening. Maybe it's just because they're NPCs. Do players become the Last User of an area transition by clicking it? I'd feel this calls for further testing if my problem hadn't been solved already. ^^

Fixed the whole issue by simply calling for the door to close itself in the script, so every NPC who wants to go back to the home zone has to open it again and therefore transition successfully. Victory!

For the education of any potential future Googlers with the same issue;
--------------------------------
void main()
{
object oUser = GetLastUsedBy();

AssignCommand(OBJECT_SELF, ActionCloseDoor(OBJECT_SELF));

if (GetIsPC(oUser) && !GetIsDM(oUser))
{
FloatingTextStringOnCreature("You have no reason to go in here.", oUser);
return;
}

AssignCommand(oUser, ClearAllActions());
AssignCommand(oUser, ActionJumpToLocation(GetLocation(GetObjectByTag("WP_STORAGE"))));
}
--------------------------------


@ffbj
Yes, exactly! ^^ Gosh, couldn't you have come around a few hours earlier, you would have saved me so much puzzling time with the probable-cause-line. I think I might actually steal the vile-smell-repels-you idea for a sewer-entrance-themed NPC exit.



Many thanks to everybody who contributed. '<img'>
               
               

               
            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #8 on: November 14, 2012, 01:43:55 am »


               Ok cool!  That was conjecture on the door opening.  But anyway I whipped this up for other things like just someplace that is restricted:
//Put this script OnEnter
//no pc access
#include "x3_inc_horse"
void main()
{

       object oPC = GetEnteringObject();
       object oArea = GetArea(oPC);
       int iHd = GetHitDice(oPC);
       string sSoundName = "whinny";
       float fDistance = 4.0 - (d4 (1));
  location lWP = GetRandomLocation(oArea, oPC, fDistance);

if (!GetIsPC(oPC))
return;


  AssignCommand(oPC, JumpToLocation(lWP));
  PlaySound(sSoundName);

string sText;
 switch (Random(4))
 {
   case 0: sText="A vile smell exudes from this arear." ; break;
   case 1: sText="A sign on the door says members only."; break;
   case 2: sText="The door is barred to you."; break;
   case 3: sText="Abandon all hope ye who enter here!"; break;

 }
 AssignCommand((oPC), ActionSpeakString(sText));
}
               
               

               
            

Legacy_Terrorble

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #9 on: November 14, 2012, 01:58:58 am »


               

Wyndhane wrote...

Wait... wait. Wait. Logic did not fail me after all; It was I who failed at logic.


Oh, the many times this phrase has described me to a T.  ':lol:'  Carry on.
               
               

               


                     Modifié par Terrorble, 14 novembre 2012 - 01:59 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #10 on: November 14, 2012, 02:38:19 am »


               FYI
if the OnTransitionClick event has no script specified it defaults to nw_g0_transition
check that script out to see default transition behavior
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #11 on: November 14, 2012, 02:40:41 am »


               

Wyndhane wrote...

void main()
{

object oUser = GetLastUsedBy();
if (GetIsPC(oUser))
    {
    FloatingTextStringOnCreature("You have no reason to go in here.", oUser);
    return;
    }

AssignCommand(oUser, ClearAllActions());
AssignCommand(oUser, ActionJumpToLocation(GetLocation(GetObjectByTag("STORAGE"))));

}
-----------------------------------

I cut out the first part and replaced it with a plain "if (GetIsPC(oUser)) return;" just now, still doesn't work. If I was on the right track with the first part, I suppose that means there must be something wrong with the second part. '<img'>

... What am I doing wrong? ...


You are using the wrong accessor function.  Use:


object oUser =GetClickingObject();
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #12 on: November 14, 2012, 02:50:51 am »


               

ehye_khandee wrote...
Btw, a DM is a PC too, but a special one. So a DM possessed NPC is still a DM and thus a PC for script purposes.


FYI
While a DM is indeed a PC,
a DM possessed object does not register as a DM nor as a PC.

So if you reject all PCs at a door, you will exclude Players and DMs, but NOT DM possessed creatures.
               
               

               
            

Legacy_Wyndhane

  • Newbie
  • *
  • Posts: 18
  • Karma: +0/-0
NPC-Only-Doors?
« Reply #13 on: November 14, 2012, 04:16:23 pm »


               @Lightfoot8
...
...
oh my god. I filtered for "GetLast" when looking for the function I needed to call for the script, and then figured "OK, there's no GetLastClickedBy, must be GetLastUsedBy I need to be using". Oh my god. All of this could have been avoided by me sensibly trying to filter for "Click" as well.
... D:
I need to go hit my head against a wall for a while now. My permit to operate a human brain should be revoked. Gawd.
Will I ever run out of horrifyingly banal problems to pester the online world with? :x Frig. Thank you. I believe I learned a lesson about assuming things today.



In other news for potential future people attempting to do the same thing and getting here via their search machine of choice, my current situation has the entire herd of NPCs using only one of the six currently proffered doors, both in and out of the storage area, which looks rather weird in game.

Still trying to figure out why they do that.

Area transitions are (hopefully?) correctly linked, NPCDOOR1 to NPCDOORSTORAGE1 and back, and so on and so forth.

Getting mildly paranoid - there's probably yet another ridiculously simple thing I'm overlooking that would solve it all.

Created a workaround for this issue *inside* the storage area by putting in an OnAreaTransitionClick script on the inside as well which teleports to one of several random locations instead, so they are spread more or less evenly across the city. If all else fails, I will probably settle for just making the entire herd move out of the main gates and come up with some asinine ingame excuse for why they're all running out of the city when night falls.

Anyway. :-) ::waves::