Scripting an Area Transition?.?.?
#1
Posté 08 mai 2011 - 06:28
#2
Posté 09 mai 2011 - 03:17
#3
Posté 09 mai 2011 - 03:54
#4
Posté 09 mai 2011 - 10:45
Lightfoot8 wrote...
Yes, you can script that. You just need to place a script in the OnAreaTransitionClick Event for the door to control where it goes to. Any door with a script in this event will override the standard transition for the door.
AS already stated. Yes, You can script that.
For script help you realy should be posting in the scripting section. But since we are already here. You would place something like this in the OnAreaTransitionClick Event.
#include "X0_I0_TRANSPORT"
void main()
{
object oClicker = GetClickingObject();
object oTarget = GetLocalObject(OBJECT_SELF,"TRANS_TARGET");
TransportToWaypoint(oClicker,oTarget);
}
Then your transistion will take you to what ever object the local is set to. If it is not set you will go nowhere.
it is a simple script that only supports up to one of each companion type. If you allow more then one summons or henchman or use X3 horses the script will need to be modified.
#5
Posté 10 mai 2011 - 04:43
The way you seem to be saying your responses are that you place that script(or one like it) in the door's OnAreaTransitionClick BEFORE the module is played. ie: I load up the toolset, I bring up the script for the door's OnAreaTransitionClick and put that in(making sure it goes to the destination I want), save the module. Then load the module and play it, where now that I am playing the module, when I click that door open then click the Area Transition I go to the place it goes to.
That is not what I am wanting. I want it that when I play the module, I click on the door and there is NO Area Transition set for the door. THEN I go talk to an npc and tell him to set up the door's destination. THEN I go to the door and there is an Area Transition for it. I want to have a script in run by the specific part in the conversation that set's up that door's Area Transition.
I want it to where I can have multiple areas in a module, but set it up through a conversation which area that door goes to(this can change each time the module is started from the beginning).
I am glad for your responses to my different posts topics. They have been helpful. I am wanting this one to be where I got a number of different areas and through conversation(s), the player can set up what area specific doors go to(instead of me as the module creator setting that door's destination to a specific spot beforehand)
"Knowledge knows no bounds! But hindsight might wish there had been!"
#6
Posté 10 mai 2011 - 05:12
#7
Posté 10 mai 2011 - 08:07
In your conversation lines you could use scripts like this to set a string on the player that will tell which waypoints the player will travel to:
void main()
{
object oPC = GetPCSpeaker();
SetLocalString(oPC, "DESTINATION", "tag of waypoint");//Put the correct tag of your WP here
}
Then in your door or trigger's OnClick event you could put something like this:
void main()
{
object oPC = GetClickingObject();
string sWP = GetLocalString(oPC, "DESTINATION");
object oWP = GetWaypointByTag(sWP);
AssignCommand(oPC, ActionJumpToObject(oWP));
}
If the destiantion needs to be more permanent you can do a couple other things. Instead of putting the string variable for the destination on the player you could use the database or an item the player will always have.
Hope that helps. Good luck.
Modifié par GhostOfGod, 10 mai 2011 - 08:12 .
#8
Posté 10 mai 2011 - 04:49
I got to thinking after my last post, that what I was asking most likely wasn't possible in the way I was asking, so I started thinking of ways to get around it and still do what I was wanting.
Although, now that I think about it, the way you are saying might be slightly better than mine. It avoids the if statement(s) I mentioned.
edit-using the if statement(s) though can mean using them for each script, for each area(which includes getting back to the start. If I use the if statements, I can have in the starting area script, if x=1 then port to area 1, while in area 1, if x=1 then port back to the start. I will have to think on this.
-----------------------------
"Knowledge knows no bounds! But hindsight might wish there had been some!"
Modifié par datamaster, 10 mai 2011 - 04:52 .
#9
Posté 11 mai 2011 - 03:23
I have the variable(s) set via the conversation. Then I have the door's OnOpen script using an if statement, check that variable. If it is one thing, teleport the PC to the correct area(a waypoint in that area). Else if it is another thing, teleport them to a different area, and so on. Then shut the door.
Each door that I have being part of this has it's own NPC near it to set the destination for it(using a different variable for each door).
I have it set where once the destination is picked, it can't be changed without starting the module again(this is an easy fix if you want the door to be changeable after the first destination is set).
#10
Posté 11 mai 2011 - 09:51
datamaster wrote...
I have the variable(s) set via the conversation. Then I have the door's OnOpen script using an if statement, check that variable. If it is one thing, teleport the PC to the correct area(a waypoint in that area). Else if it is another thing, teleport them to a different area, and so on.
I think you are making it over complacated. Why set an int. Setting an Int only make you have to create another logic structure to figure out what the int means. Just use the first script I gave you in the OnAreaTransitionClick Event. The door will not go anywhere when the module starts. The local object is not yet set, therefore the dore has no destnation. In you Action Taken conversation Event just set the local object on the door to where you want it to go.
Ok let me assume that you have 5 doors with the tags RandomDoor1,RandomDoor2, ect... and an NPC with a conversation standing next to each door. One of you Action Taken scripts for setting the NPC's door(The one Nearest to the NPC) to go to door 5, could look like this.
void main()
{
// Get the Object for each door.
object oNPCsDoor = GetNearestObject(OBJECT_TYPE_DOOR);
object oDestDoor = GetObjectByTag("RandomDoor5");
//Set oDestDoor as the destnation for oNPC's door.
SetLocalObject ( oNPCsDoor,"TRANS_TARGET",oDestDoor);
// Set oNPC's door as the Destnation for oDestDoor
SetLocalObject ( oDestDoor,"TRANS_TARGET",oNPCsDoor);
}
Modifié par Lightfoot8, 11 mai 2011 - 09:53 .
#11
Posté 13 mai 2011 - 06:23
What I am thinking is that if you talk to the NPC for a door(the door being the one closest to the NPC), and you tell him to set this door to the door #5(RandomDoor5) with this door being #1, the Action Taken script for that line in the conversation is that script you just posted(and the OnAreaTransition Script for each door being the first script you posted here and the tags of the doors being RandomDoor1, RandomDoor2, etc). If you tell him instead to set it to door #2, then it is the same script but oDestDoor is set to RandomDoor2.
I think one problem I was having understanding was that you were mentioning one door, I don't see anywhere about setting it differently based on what is picked in the conversation, just that the choice is set in conversation.
So I think I have it now.
If I have any other problems with this, I will let you know. But as I said, I think I have it.
And yes, the way I am understanding it from your posts, is that this way is better scripting that what I was thinking.
Also is this #include "X0_I0_TRANSPORT" what must be in all OnAreaTransitionClick scripts for it to appear/work?
#12
Posté 14 mai 2011 - 03:11
#include "X0_I0_TRANSPORT"
void main()
{
object oClicker = GetClickingObject();
object oTarget = GetLocalObject(OBJECT_SELF,"TRANS_TARGET");
TransportToWaypoint(oClicker,oTarget);
}
And this script is in the Actions Taken for the conversation:
void main()
{
// Get the Object for each door.
object oNPCsDoor = GetNearestObject(OBJECT_TYPE_DOOR);
object oDestDoor = GetObjectByTag("RandomDoor5");
//Set oDestDoor as the destnation for oNPC's door.
SetLocalObject ( oNPCsDoor,"TRANS_TARGET",oDestDoor);
// Set oNPC's door as the Destnation for oDestDoor
SetLocalObject ( oDestDoor,"TRANS_TARGET",oNPCsDoor);
}
The conversation has three choices(with the RandomDoor5 changed appropriately in each).
The destination doors ARE made.
The problem I am having is that when I click to open the door, there is NO area transition clickie highlight there. This was one problem I ran into earlier, before I decided to put the solution I had had into the OnOpen script and have it teleport the PC. I believe yours should work, if the area transition highlight shows up on opening the door.
edit-I also tried something else with another door and 3 more areas(all forests). I tried having it randomly select between them(yes I used an if statement for this). I told it to set an int to a die roll result of a d6. If that result is a 1 or a 2, run the scriptlines you have but to a certain forest, or if it is 3 or 4, another forest, else a third.
Modifié par datamaster, 14 mai 2011 - 03:16 .
#13
Posté 14 mai 2011 - 04:08
#14
Posté 15 mai 2011 - 03:02
#15
Posté 15 mai 2011 - 03:47
The random side is occasionally working. I think I know the problem.
This is my script for the random select door(the script on the door is the same as the other door, but this is the script in the conversation's Actions Taken script).
void main()
{
int seconddoor = d6();
// Get the Object for each door.
object oNPCsDoor = GetNearestObject(OBJECT_TYPE_DOOR);
object oDestDoor;
if ((seconddoor == 1) || (seconddoor == 2))
{
oDestDoor = GetObjectByTag("RandomDoor9");
}
else if ((seconddoor == 3) || (seconddoor == 4))
{
oDestDoor = GetObjectByTag("RandomDoor11");
}
else
{
oDestDoor = GetObjectByTag("RandomDoor13");
}
//Set oDestDoor as the destination for oNPC's door.
SetLocalObject(oNPCsDoor,"TRANS_TARGET",oDestDoor);
// Set oNPC's door as the Destination for oDestDoor
SetLocalObject(oDestDoor,"TRANS_TARGET",oNPCsDoor);
}
I think the problem is in the if statements.
ex. take this one:
if ((seconddoor == 1) || (seconddoor == 2))
Now the seconddor ==1 is fine, but I think my OR statement is wrong(or using the wrong symbols or something).
I have been trying to find out what the AND, OR, etc. commands for if statements are in the NWN scripting language. No luck. I tried looking up Boolean Algebra and c# programming, and it says the OR symbol is +, but that not always working either.
Also, I am wondering, is the second SetLocalObject supposed to set the destination door back to this door? ex. You set door1 to door2(you are standing at door1 though), does this set door2 back to door1 if you click on door2?
If it doesn't, I figure it should be reasonably ok, somehow, to tell the script that sets the objects to get the destination door it is going to use and set it's destination back to this one.
---------------------------
"Knowledge knows no bounds! But hindsight might wish there had been some!"
#16
Posté 15 mai 2011 - 02:44
datamaster wrote...
With current tests, the door that sets the destination to where the PC says for it to go, is working.
The random side is occasionally working. I think I know the problem.
This is my script for the random select door(the script on the door is the same as the other door, but this is the script in the conversation's Actions Taken script).
I do not see any problem with the script you posted. If it is occasionally working. It sounds like you may have a misspelling in one of your tags double check them.
I think the problem is in the if statements.
ex. take this one:
if ((seconddoor == 1) || (seconddoor == 2))
Now the seconddor ==1 is fine, but I think my OR statement is wrong(or using the wrong symbols or something).
I have been trying to find out what the AND, OR, etc. commands for if statements are in the NWN scripting language. No luck. I tried looking up Boolean Algebra and c# programming, and it says the OR symbol is +, but that not always working either.
You can fing the sentax for NWN in the lexicon.
Logical Operators/Truth Tests
Your statment as written is reading
If seconddoor == 1 or seconddoor ==2 then set the door destination. That is correct and what you are looking for.
Here is a pic to review the Truth Tables.

Also, I am wondering, is the second SetLocalObject supposed to set the destination door back to this door? ex. You set door1 to door2(you are standing at door1 though), does this set door2 back to door1 if you click on door2?
If it doesn't, I figure it should be reasonably ok, somehow, to tell the script that sets the objects to get the destination door it is going to use and set it's destination back to this one.
You are correct the second SetLocal is to compleate the two way connection between the two doors.
#17
Posté 15 mai 2011 - 06:32
void main()
{
int seconddoor = d6();
string diceroll;
object oPC = GetPCSpeaker();
// Get the Object for each door.
object oNPCsDoor = GetNearestObject(OBJECT_TYPE_DOOR);
object oDestDoor;
if ((seconddoor == 1) || (seconddoor == 2))
{
oDestDoor = GetObjectByTag("RandomDoor9");
//This is to let the PC know what the number rolled is.
diceroll = IntToString(seconddoor);
FloatingTextStringOnCreature("The dice roll is:", oPC);
SendMessageToPC(oPC, diceroll);
}
else if ((seconddoor == 3) || (seconddoor == 4))
{
oDestDoor = GetObjectByTag("RandomDoor11");
//This is to let the PC know what the number rolled is.
diceroll = IntToString(seconddoor);
FloatingTextStringOnCreature("The dice roll is:", oPC);
SendMessageToPC(oPC, diceroll);
}
else if ((seconddoor == 5) || (seconddoor == 6))
{
oDestDoor = GetObjectByTag("RandomDoor13");
//This is to let the PC know what the number rolled is.
diceroll = IntToString(seconddoor);
FloatingTextStringOnCreature("The dice roll is:", oPC);
SendMessageToPC(oPC, diceroll);
}
else
return;
//Set oDestDoor as the destination for oNPC's door.
SetLocalObject(oNPCsDoor,"TRANS_TARGET",oDestDoor);
// Set oNPC's door as the Destination for oDestDoor
SetLocalObject(oDestDoor,"TRANS_TARGET",oNPCsDoor);
}
I set it where it tells the PC what number the dice rolled. It works on a 1-4 but on a 5 or 6, it does NOT send
the PC to his door. I have double checked and triple checked the tags. That door IS "RandomDoor13".
RandomDoor13 is a bridge door. I am not sure what else to check.
There is nothing in the way of the PC when they click on the random door, so they are not having trouble getting to it.
------------------------
"Knowledge knows no bounds! But hindsight might have wished for some!"
#18
Posté 15 mai 2011 - 07:38
else if ((seconddoor == 5) || (seconddoor == 6))
{
oDestDoor = GetObjectByTag("RandomDoor13");
//This is to let the PC know what the number rolled is.
diceroll = IntToString(seconddoor);
FloatingTextStringOnCreature("The dice roll is:", oPC);
SendMessageToPC(oPC, diceroll);
if (!GetIsObjectValid(oDestDoor))
SendMessageToPC(oPC, "RandomDoor13 is not a valid Object");
else
SendMessageToPC(oPC, "RandomDoor13 is in area "+ GetName(GetArea(oDestDoor)));
}
#19
Posté 16 mai 2011 - 12:48
edit-Would you like me to send you this module to look at yourself? It's not one I have on the vault.
Modifié par datamaster, 16 mai 2011 - 12:52 .
#20
Posté 16 mai 2011 - 12:50
#21
Posté 16 mai 2011 - 04:02
#22
Posté 16 mai 2011 - 04:03
#23
Posté 16 mai 2011 - 04:07
#24
Posté 17 mai 2011 - 01:28
Replace the First script I gave you with this one.
#include "X0_I0_TRANSPORT"
void main()
{
object oClicker = GetClickingObject();
object oTarget = GetLocalObject(OBJECT_SELF,"TRANS_TARGET");
float fFacing = GetFacing(oTarget)+180.0;
vector vPos =GetPosition(oTarget)+ AngleToVector(fFacing);
location lLoc = Location(GetArea(oTarget),vPos,fFacing);
TransportToLocation(oClicker,lLoc);
}
#25
Posté 17 mai 2011 - 02:34
Anyway, it worked. Thanks again for your help Lightfoot8.
Now to plan on what I had originally planned for this(that was just a test module to get it to work).
edit-One of the plans I have for this is a prefab world. A huge one.
Modifié par datamaster, 17 mai 2011 - 02:47 .





Retour en haut






