Aller au contenu

Photo

how to: capture attempt to open door before it is opened?


  • Veuillez vous connecter pour répondre
68 réponses à ce sujet

#1
Calgacus

Calgacus
  • Members
  • 122 messages
Before I allow  a character to open a door I want to check a variable on the character.  If the variable is set to 0 allow the door to open, else do not.  Can I use the onuserdefined event this way? Or will the open event finish before it can be interrupted.  If so how? 
I'd rather not prelock all the doors and then run a script in the onfailedtoopen event, that would be bad  because the player would fail to open the door (play locked door sounds) and then it would open.

#2
Shadooow

Shadooow
  • Members
  • 4 465 messages
I don't know about any way.

Guess prelocking them is only way, but you can use key instead of variable - then if the pplayer have it he wont fail to open. However if you want to do this for all doors, it maybe isn't workable, depends on the number of different variables/keys you need.

The key also appers in inventory, the best way to workaround this would be using NWNX function to change the tag of the some item (skin, PC ID, anything that every character start with).

EDIT: OnUserDefined won't let you do it, this event's usage is very limited, itss good only for day/time events executed from heartbeat or for making scripts for doors if you have some script system installed that uses all events and you don't want to mess with it.

Modifié par ShaDoOoW, 29 août 2010 - 10:50 .


#3
Calgacus

Calgacus
  • Members
  • 122 messages
Thanks,

the keys, that might work but would be a little awkward, my labyrinth is basically made of locked doors. so a bunch of keys appearing and disappearing as the char walks around would be ugly. I guess I could set all doors to open only by key but I need some to not open at all. I could set the openable doors to open by key the others to not open at all. Then when a character opens a door he uses a key up and when he walks into the new room he gets a new key so he can open a new door. the real issue is that I don't want a character to open two doors in the same room without first moving into the new room he opens a door into.


#4
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
How about if you place a trigger in front of each door. If the character can open the door unlock it. If he can't, lock it if it is not already.

You could even make it a generic script to just find the closest door for to the trigger, so you dont have to have a script for each door/trigger set up.

Modifié par Lightfoot8, 29 août 2010 - 11:22 .


#5
Shadooow

Shadooow
  • Members
  • 4 465 messages
Trigger might work too, but depends on enviroment if its just for one area, guess its the best way. However getting automatically closest door from trigger won't work correctly since the location of trigger is IIRC the west-southest corner.

#6
Calgacus

Calgacus
  • Members
  • 122 messages
the trigger idea would mean drawing a 112 triggers and putting variables on them and still more scripting. I think I'll go with my idea of just setting a variable on the pc when they open doors, then each rooms trigger area (i hav ethese already drawn) will check for it and if the pc has it set then they get teleported back to the place they were when the door was opened. Unless there's an easier way to set a trigger area as being unenterable by a pc - is there?

#7
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Ok, Now I feel like a fool. Use a trigger on the door itself ( A custom trap script)



set it active and uncheck the detectable/disarmable/oneshot. You then have your trigger that will fire befor the door is opened. Of course you will have the trap/trigger open the door.

#8
Calgacus

Calgacus
  • Members
  • 122 messages
interesting. will the door trigger prevent the door opening? I guess if it fires first it can lock the door before the open event hits the door? or does the trigger eat the open event - its own script could do the opening if checks are passed I guess? that might be the best way.

#9
Shadooow

Shadooow
  • Members
  • 4 465 messages

Lightfoot8 wrote...

Ok, Now I feel like a fool. Use a trigger on the door itself ( A custom trap script)

set it active and uncheck the detectable/disarmable/oneshot. You then have your trigger that will fire befor the door is opened. Of course you will have the trap/trigger open the door.

+1 however dont forget to recreate this trap after the doors are opened/closed, well at least if you plan to re-use them.

#10
Calgacus

Calgacus
  • Members
  • 122 messages
So if a door is opened it will lose its trigger?

Also, when i make my custom trap how do i select it as the trap type? and can I suppress the "Trap Triggered" message?

#11
Shadooow

Shadooow
  • Members
  • 4 465 messages

Calgacus wrote...
will the door trigger prevent the door opening? I guess if it fires
first it can lock the door before the open event hits the door? or does
the trigger eat the open event - its own script could do the opening if
checks are passed I guess? that might be the best way.

yes it should prevent the opening the door

Calgacus wrote...

So if a door is opened it will lose its trigger?

Well depends, I wasn't correct before. LightFoot8 suggested you to set trap as NOT one shot. If you do this the trap will not goes away. The other approach is to set is as one shot, but nothing will get changed, except you have to recreate the trap, well maybe it could be used for something, but forget it for now.

Also, when i make my custom trap how do i select it as the trap type? and can I suppress the "Trap Triggered" message?

Select any type, if does not matter if you use custom script in OnTrapTriggered which you have to do.

Unfortunately only way to get rid of trap triggered message is to delete this message from the dialog.tlk, but still best solution.

#12
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
I hae decided that I do not like the trap option after testing. The reason is that there is no way to get rid of the "you triggered a trap' from floating over your head.



the best option seems to be to use the "OnDoorOpened' event. In my testing just telling the door to reclose it's self is enough to have the door never open.



I placed this in the Even and could not budge the door.



void main()

{

ActionCloseDoor(OBJECT_SELF);

}



So there is your answer. If they have the proper var do nothing. if they dont close the door.



To answer you questions above. No the door will not lose its trigger if the "oneshot" is unchecked on the trap tab. But since i never disarmed the traps in my test this may be ther reason i was still getting the trap feed back to the PC.



When you make a custom trap script and place it in the OnTrapTriggered event it take the place of the standerd trap setting scripts, so they will not fire in addition to the custom script.





As a second note. Since you are going to most likely be setting you doors to plot so that they can not be damaged. You could use your door stats instead of a local int on the door for who can open it. ( hardness/HP/fort save/reflex save/ willsave. for exsample



void main()

{

if (GetHardness()!= GetLocalInt(GetLastOpenedBy(),"DoorControl"))

{

ActionCloseDoor(OBJECT_SELF);

PlayVoiceChat(VOICE_CHAT_CUSS,GetLastOpenedBy());

}

}

#13
Calgacus

Calgacus
  • Members
  • 122 messages

Lightfoot8 wrote...

I hae decided that I do not like the trap option after testing. The reason is that there is no way to get rid of the "you triggered a trap' from floating over your head.

the best option seems to be to use the "OnDoorOpened' event. In my testing just telling the door to reclose it's self is enough to have the door never open.

I placed this in the Even and could not budge the door.

void main()
{
ActionCloseDoor(OBJECT_SELF);
}

So there is your answer. If they have the proper var do nothing. if they dont close the door.


SWEET!!!!  Thats it.

To answer you questions above. No the door will not lose its trigger if the "oneshot" is unchecked on the trap tab. But since i never disarmed the traps in my test this may be ther reason i was still getting the trap feed back to the PC.

When you make a custom trap script and place it in the OnTrapTriggered event it take the place of the standerd trap setting scripts, so they will not fire in addition to the custom script.


As a second note. Since you are going to most likely be setting you doors to plot so that they can not be damaged. You could use your door stats instead of a local int on the door for who can open it. ( hardness/HP/fort save/reflex save/ willsave. for exsample

void main()
{
if (GetHardness()!= GetLocalInt(GetLastOpenedBy(),"DoorControl"))
{
ActionCloseDoor(OBJECT_SELF);
PlayVoiceChat(VOICE_CHAT_CUSS,GetLastOpenedBy());
}
}


I don't need that var on the door just the PC eg:

void main()
{
   if (TRUE == GetLocalInt(GetLastOpenedBy(),"DoorControl"))
   {
      ActionCloseDoor(OBJECT_SELF);
      PlayVoiceChat(VOICE_CHAT_CUSS,GetLastOpenedBy());
   }
}

and then in my other area triggers (covering the floor in each room)


void main()

{

   if ( pc_has_entered_a_new_room )

   {
       setLocalInt(oPC,"DoorControl", 0);
   }else{
       // do nothing
       return;
   }
   //   ...
   ///  do other stuff
   //  ...

}

Thanks !!

Modifié par Calgacus, 30 août 2010 - 01:51 .


#14
Calgacus

Calgacus
  • Members
  • 122 messages
thought you might like to see what it looks like: http://calgacus.game...rinthingame.bmp

this is a link to an image of the chessboard version of the labyrinth. the red areas are the walls drawn with traps, the player reveals them one by one as he bumps into them trying to move around. The scripts make a new labyrinth each time the mini-game is played.

The dungeon version with the doors just looks like the standard dungeon tiles with square rooms and those big dungeon doors that rise up between the rooms.



Thanks again.

#15
Genisys

Genisys
  • Members
  • 525 messages
nvm, looks like you got your answers above... :D

Prelocked with fake key name (not openable) with a OnFailToOpen script is the best way to handle it all... good suggestions guys.. :D

Modifié par Genisys, 30 août 2010 - 06:37 .


#16
ffbj

ffbj
  • Members
  • 593 messages
Something I did was to have certain doors all locked, this was idea of a stuck door. Then when the player attacks the door it will unlock and open if they are strong enough. Similar to setting a variable but just using an attribute instead.

I also use a similar idea but extended, when you select a hovel to live it, it puts your name on the door, and thereafter only you can open that door. You need a hovel key which is where I set the variable, since it persists over server resets. Thereafter that key can only be used on that door, though others can get the keys the won't work on your door, and yours cannot be used on any othe door. In this way you don't have to make a bunch of seperate keys for each hovel door.

Modifié par ffbj, 30 août 2010 - 11:00 .


#17
Calgacus

Calgacus
  • Members
  • 122 messages
lots of good responses, nice to see the community is still going strong.

#18
Genisys

Genisys
  • Members
  • 525 messages
You like good responses? :D

Try this one...

// door_port_templ   (TEMPLATE SCRIPT)
//////////////////////////////////////////////
//Created By: Genisys (Guile)
//Created On: 8/30/10
///////////////////////////////////////////////////////////////////////////////
/*         This script goes in the OnFailToOpen or OnClicked

   Basically it allows you to teleport the clicking PC (and party possibly)
   to a waypoint or door (By using a door the PC may end up in the wrong direction).
   Make sure you set the door or object to be locked & require a fictious key
   to open it. (make up a fake key name)

   MAKE SURE you save this script under a new name BEFORE you edit it!
*/
///////////////////////////////////////////////////////////////////////////////
///////////////////IMPORTANT SETTINGS/////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//Set this to the (tagname) of the waypoint or door which is the destination
const string DOOR_OR_WAYPOINT = "tagname";
///////////////////////////////////////////////////////////////////////////////
//Set this to TRUE if you wish to check for a key or item..
const int CHECK_FOR_ITEM_FIRST = FALSE; //Default = FALSE (Don't check)
///////////////////////////////////////////////////////////////////////////////
//Set this to TRUE if you wish to remove the item or key after they are ported
const int TAKE_KEY_ITEM = FALSE; //Default = FALSE (Don't take the key / item)
///////////////////////////////////////////////////////////////////////////////
//Set this to the (tagname) of the item to be checked for..
const string TAGNAME_OF_KEY_ITEM = "tagname";
///////////////////////////////////////////////////////////////////////////////
//Set this to TRUE if you wish to use a VFX constant for visual effect..
const int USE_VFX = FALSE; //Default = FALSE (Don't use VFXs)
///////////////////////////////////////////////////////////////////////////////
//Set this to the Default VFX to use (This MUST be a constant!)
const int VFX_TO_USE = VFX_FNF_SUMMON_MONSTER_3;
///////////////////////////////////////////////////////////////////////////////
//Set this to TRUE if you wish to teleport the WHOLE PARTY!
const int TELEPORT_PARTY = FALSE; //Default = FALSE (Don't Teleport Party)
///////////////////////////////////////////////////////////////////////////////
//Set this to TRUE if the Party Members must to be in the same area!
const int MEMBERS_IN_AREA = FALSE; //Default = FALSE (Teleport All reguardless)
///////////////////////////////////////////////////////////////////////////////
//Set this to FALSE if you don't want to teleport Summons/Familiars Also.
const int SUMMONS_TELEPORT_TOO = TRUE; //Default = TRUE (Teleport All Summons)
///////////////////////////////////////////////////////////////////////////////
/////WARNING: DON'T TOUCH ANYTHING BELOW THIS LINE!!!/////////////////////////
/////////////////////////////////////////////////////////////////////////////

//Main Script
void main()
{
 object oPC = GetClickingObject();
 object oArea = GetArea(oPC);
 object oWay = GetObjectByTag(DOOR_OR_WAYPOINT);
 location lLoc = GetLocation(oWay);
 object oParty;
 object oKey;
 effect eVis;
 float f1 = 0.0;
 float f2 = 0.1;

//Only continue if it's a PC / DM or a DM Possessed Creature...
if (GetIsPC(oPC)|| GetIsDM(oPC) || GetIsDMPossessed(oPC))
{
 //First see if we are checking for an item or not...
 if(CHECK_FOR_ITEM_FIRST==TRUE)
 {
  oKey = GetItemPossessedBy(oPC, TAGNAME_OF_KEY_ITEM);

  //If they don't have the key, stop here..
  if(oKey == OBJECT_INVALID)
  {
   //Tell the PC why they failed..
   FloatingTextStringOnCreature("You do not have the proper item or key to use this door.", oPC, TRUE);
   return;
  }
  //Otherwise they have the key..
  else
  {
   //If we are suppose to kill the key, then do it here..
   if(TAKE_KEY_ITEM==TRUE)
   {
    DestroyObject(oKey, 0.0);
   }
  }
 //End Check for Item..
 }

 //If we are suppose to use VFXs..
 if(USE_VFX == TRUE)
 {
  eVis =  EffectVisualEffect(VFX_TO_USE, FALSE);
  ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC, 0.0);
  f1 = 2.5;
  f2 = 2.6;
 }

 //First see if we are teleporting the whole party..
 if(TELEPORT_PARTY==TRUE)
 {
   oParty = GetFirstFactionMember(oPC, SUMMONS_TELEPORT_TOO);
   while(GetIsObjectValid(oParty))
   {
    if(MEMBERS_IN_AREA==TRUE)
    {
     //If the Party Member is in the same area as the PC..
     if(GetArea(oParty)==oArea)
     {
      DelayCommand(f1, AssignCommand(oParty, ClearAllActions()));
      DelayCommand(f2, AssignCommand(oParty, ActionJumpToLocation(lLoc)));
     }
    }
    //Otherwise jump all party members!!
    else
    {
      DelayCommand(f1, AssignCommand(oParty, ClearAllActions()));
      DelayCommand(f2, AssignCommand(oParty, ActionJumpToLocation(lLoc)));
    }
    oParty = GetNextFactionMember(oPC, SUMMONS_TELEPORT_TOO);
   }

 //End Teleport Party Check..
 }

 //Otherwise see if we should teleport familiars & summons too
 else
 {
    //If we are suppose to teleport Summons / Familiars..
  if(SUMMONS_TELEPORT_TOO==TRUE)
  {
   oParty = GetFirstFactionMember(oPC, TRUE);
   while(GetIsObjectValid(oParty))
   {
    if(GetMaster(oParty)==oPC)
    {
     DelayCommand(f1, AssignCommand(oParty, ClearAllActions()));
     DelayCommand(f2, AssignCommand(oParty, ActionJumpToLocation(lLoc)));
    }
    oParty = GetNextFactionMember(oPC);
   }
  }
 }

 //Always teleport the PC / DM
 DelayCommand(f1, AssignCommand(oPC, ClearAllActions()));
 DelayCommand(f2, AssignCommand(oPC, ActionJumpToLocation(lLoc)));

//End valid check for PC / DM / Dm Possessed Creatures..
}

//Do nothing if it's not a PC / DM / or DM Possessed Creature..

//Main Script End
}

B)

Modifié par Genisys, 31 août 2010 - 01:21 .


#19
ehye_khandee

ehye_khandee
  • Members
  • 855 messages
Lots of errors in the script supplied. ... for example, lines 96-120 are totally hashed. oPC is set at start as "object oPC = GetClickingObject();" the lines 96-120 will ONLY function on the oPC, meanwhile it runs through all iterations of the oPC's party pointlessly. Though, somehow, you got the code fixed in the next section dealing with familiars.



I think you did not test this at all.




#20
Genisys

Genisys
  • Members
  • 525 messages
I didn't test it 100% no, sorry, and thank you for pointing out my errors.. :D



I hope it's fixed now.. :D

#21
Shadooow

Shadooow
  • Members
  • 4 465 messages

ehye_khandee wrote...

Lots of errors in the script supplied. ... for example, lines 96-120 are totally hashed. oPC is set at start as "object oPC = GetClickingObject();" the lines 96-120 will ONLY function on the oPC, meanwhile it runs through all iterations of the oPC's party pointlessly. Though, somehow, you got the code fixed in the next section dealing with familiars.

I think you did not test this at all.

I really wonder you even take the time. When someone throws there script, a really loong script without any description what it does, I ignore it.

#22
ehye_khandee

ehye_khandee
  • Members
  • 855 messages
It is my habit to 'read code like a novel' and run it in my brain. I spot LOADS of errors in other ppls scripts this way. :D



Always try to test your scripts before posting if at all, it avoids mis-informing others and wasting their time.


#23
Genisys

Genisys
  • Members
  • 525 messages
What's smoking?

#24
ehye_khandee

ehye_khandee
  • Members
  • 855 messages

Genisys wrote...

What's smoking?





If you smell smoke, get out of the building!

#25
Redunct

Redunct
  • Members
  • 49 messages
Genisys had the right idea, script in the onFailToOpen, require a key and no key specified.

This should work, put it in the OnFailToOpen:

Void Main()
{
object oPC = GetClickingObject();
if (GetLocalInt(OBJECT_SELF,"Opened")!=0)
{
return;
}

SetLocalInt(OBJECT_SELF,"Opened",1);

if (//Place Condtional Here)
{
ActionUnlockDoor(OBJECT_SELF);
ActionOpenDoor(OBJECT_SELF);
return;
}
// Place What to do on failure here.

DelayCommand(1.0f, SetLocalInt(OBJECT_SELF,"Opened",0));
}


The Local Integer prevents the infinite loop that this kind of script is prone to. If you would like to make a check every time the player tries to open the door, you'd do it like this:

Void Main()
{
object oPC = GetClickingObject();
if (GetLocalInt(OBJECT_SELF,"Opened")!=0)
{
return;
}

SetLocalInt(OBJECT_SELF,"Opened",1);
DelayCommand(1.0f, SetLocalInt(OBJECT_SELF,"Opened",0));
if (//Place Condtional Here)
{
ActionUnlockDoor(OBJECT_SELF);
ActionOpenDoor(OBJECT_SELF);
return;
}
// Place What to do on failure here.
}



Then, place a Lock command and a Close command on a trigger or something. I'm sure you can figure out the rest.

Modifié par Redunct, 31 août 2010 - 10:20 .