Kexikus 995 Posted August 26, 2015 So, I'm trying to force an NPC to leave a module by going through the same door the player goes through when changing the module. But since that door is locked at that time, I want the NPC to open the door and close it once he went through it. I managed to open the door, close the door, lock it and to force the NPC to go somewhere but no matter what I do, he does not go through the open! door even when the coordinates set are behind the door. Is there something I'm missing? Here's the (probably pretty bad) script I have so far: void main(){ object oNPC=GetObjectByTag("kor33b_belaya"); float x=88.44; float y=-5.2; float z=53.51; int bRun=TRUE; vector vExit=Vector(x,y,z); location lExit=Location(vExit,0.0f); object oDoor = GetObjectByTag("k33b_dor_academy", 0); SetLocked(oDoor, FALSE); AssignCommand (oDoor,ActionWait(0.0)); AssignCommand (oDoor,ActionOpenDoor(oDoor)); ActionDoCommand(SetCommandable(TRUE,oNPC)); AssignCommand (oNPC,ActionForceMoveToLocation(lExit,bRun)); AssignCommand (oNPC,ActionDoCommand(AssignCommand(oDoor,ActionCloseDoor(oDoor)))); AssignCommand (oNPC,ActionDoCommand(SetLocked(oDoor,TRUE))); AssignCommand (oNPC,ActionDoCommand(DestroyObject(oNPC))); } Any help would be great Quote Share this post Link to post Share on other sites
Fair Strides 509 Posted August 26, 2015 So, I'm trying to force an NPC to leave a module by going through the same door the player goes through when changing the module. But since that door is locked at that time, I want the NPC to open the door and close it once he went through it. I managed to open the door, close the door, lock it and to force the NPC to go somewhere but no matter what I do, he does not go through the open! door even when the coordinates set are behind the door. Is there something I'm missing? Here's the (probably pretty bad) script I have so far: void main(){ object oNPC=GetObjectByTag("kor33b_belaya"); float x=88.44; float y=-5.2; float z=53.51; int bRun=TRUE; vector vExit=Vector(x,y,z); location lExit=Location(vExit,0.0f); object oDoor = GetObjectByTag("k33b_dor_academy", 0); SetLocked(oDoor, FALSE); AssignCommand (oDoor,ActionWait(0.0)); AssignCommand (oDoor,ActionOpenDoor(oDoor)); ActionDoCommand(SetCommandable(TRUE,oNPC)); AssignCommand (oNPC,ActionForceMoveToLocation(lExit,bRun)); AssignCommand (oNPC,ActionDoCommand(AssignCommand(oDoor,ActionCloseDoor(oDoor)))); AssignCommand (oNPC,ActionDoCommand(SetLocked(oDoor,TRUE))); AssignCommand (oNPC,ActionDoCommand(DestroyObject(oNPC))); } Any help would be great Perhaps this might work? void main(){ object oNPC=GetObjectByTag("kor33b_belaya"); float x=88.44; float y=-5.2; float z=53.51; int bRun=TRUE; vector vExit=Vector(x,y,z); location lExit=Location(vExit,0.0f); object oDoor = GetObjectByTag("k33b_dor_academy", 0); SetLocked(oDoor, FALSE); AssignCommand (oDoor,ActionOpenDoor(oDoor)); SetCommandable(TRUE,oNPC); DelayCommand(2.0, AssignCommand (oNPC,ActionForceMoveToLocation(lExit,bRun))); DelayCommand(10.0, AssignCommand(oDoor,ActionCloseDoor(oDoor))); DelayCommand(11.5, SetLocked(oDoor,TRUE)); DelayCommand(12.0, DestroyObject(oNPC)); } EDIT: If that above doesn't work, examine this: http://www.lucasforums.com/showpost.php?p=2791878&postcount=15 Quote Share this post Link to post Share on other sites
Kexikus 995 Posted August 26, 2015 That doesn't work either. I have the feeling that the NPC can't go through the door for some reason even though it's open, because no matter how I edit the coordinates to be behind the door, the NPC will always stop right in front of it. So, my guess would be that the script is basically working and either I'm too dumb to enter the right coordinates or there is something blocking the NPC from going through that door... Edit: Checked your link and made some tests and it seems like the issue is that the door is not fully opened when the NPC starts moving, resulting in the behavior I described. Quote Share this post Link to post Share on other sites
DarthTyren 103 Posted August 26, 2015 Then add another vector that is in front of the door and start by moving the NPC to that vector instead. Then, change the DelayCommand for moving the NPC from 2.0 to 4.0. If that doesn't help, let us know. Quote Share this post Link to post Share on other sites
Kexikus 995 Posted August 26, 2015 Thanks for the tip but I already managed to do it Here's the script that worked in the end: void main(){ object oNPC=GetObjectByTag("kor33b_belaya"); float x=88.44; float y=-5.2; float z=58.51; int bRun=FALSE; vector vExit=Vector(x,y,z); location lExit=Location(vExit,0.0f); object oDoor = GetObjectByTag("k33b_dor_academy", 0); ActionPauseConversation(); SetLocked(oDoor, FALSE); DelayCommand(4.0, AssignCommand (oDoor,ActionOpenDoor(oDoor))); SetCommandable(TRUE,oNPC); DelayCommand(0.0, AssignCommand (oNPC,ActionForceMoveToLocation(lExit,bRun))); DelayCommand(7.0, AssignCommand (oNPC,ActionForceMoveToLocation(lExit,bRun))); DelayCommand(8.5, AssignCommand(oDoor,ActionCloseDoor(oDoor))); DelayCommand(8.5, SetLocked(oDoor,TRUE)); DelayCommand(11.0, DestroyObject(oNPC)); DelayCommand(3.5, ActionResumeConversation()); } I also paused the conversation for 3.5 seconds to stop the player from cheating himself through a door that's supposed to be locked^^ But I have two new and somewhat related questions: Is there a way to stack commands? What I mean is that for example, the first command forces an NPC to walk somewhere and the second one does something else. Is there a way to make it so that the second one is triggered only after the first command is done, i.e. the NPC has walked to his destination. And the second question is: How do I make it so that a dialogue is triggered once the player is near enough? Quote Share this post Link to post Share on other sites
Hassat Hunter 571 Posted August 28, 2015 I assume the NPC 'jumps' past the door? Since from what I know if a door is opened inside a conversation, only after the conversation is over and the real game starts does the game stops blocking at that specific section. An extremely cheatery work-around would be to open the door before the conversation, then close it during the conversation, then do the regular "open/close" stuff as regular. (This is pretty much how the Atris door scene is done) Quote Share this post Link to post Share on other sites
Kexikus 995 Posted August 28, 2015 I assume the NPC 'jumps' past the door? Since from what I know if a door is opened inside a conversation, only after the conversation is over and the real game starts does the game stops blocking at that specific section. An extremely cheatery work-around would be to open the door before the conversation, then close it during the conversation, then do the regular "open/close" stuff as regular. (This is pretty much how the Atris door scene is done) No, she just stops right infront of the door. But as I said, I managed to "fix" it. Quote Share this post Link to post Share on other sites
DarthTyren 103 Posted August 29, 2015 To answer your second question, the best way to "trigger" a conversation based on proximity is to add a trigger, which will point to a script, which will look something like this: void main() { object oNPC = GetObjectByTag("tag_of_npc"); object oTrig = GetObjectByTag("tag_of_trigger"); string sDialog = "name_of_dlg"; AssignCommand(GetFirstPC(), ActionStartConversation(oNPC, sDialog); DestroyObject(oTrig, 1.0); } Obviously, you'd replace everything in quotations with the appropriate info, leaving the quotation marks. What this will (should) do is fire the dialog once you walk into the trigger, then it will destroy the trigger, preventing the game from trying to fire the dialog again. Quote Share this post Link to post Share on other sites
Fair Strides 509 Posted August 29, 2015 To answer your second question, the best way to "trigger" a conversation based on proximity is to add a trigger, which will point to a script, which will look something like this: void main() { object oNPC = GetObjectByTag("tag_of_npc"); object oTrig = GetObjectByTag("tag_of_trigger"); string sDialog = "name_of_dlg"; AssignCommand(GetFirstPC(), ActionStartConversation(oNPC, sDialog); DestroyObject(oTrig, 1.0); } Obviously, you'd replace everything in quotations with the appropriate info. What this will (should) do is fire the dialog once you walk into the trigger, then it will destroy the trigger, preventing the game from trying to fire the dialog again. Oh, that's the part I forgot! I walked him through triggers this morning in the chat, but I forgot to do the DestroyObject part in the script... Quote Share this post Link to post Share on other sites
Kexikus 995 Posted August 29, 2015 To answer your second question, the best way to "trigger" a conversation based on proximity is to add a trigger, which will point to a script, which will look something like this: void main() { object oNPC = GetObjectByTag("tag_of_npc"); object oTrig = GetObjectByTag("tag_of_trigger"); string sDialog = "name_of_dlg"; AssignCommand(GetFirstPC(), ActionStartConversation(oNPC, sDialog); DestroyObject(oTrig, 1.0); } Obviously, you'd replace everything in quotations with the appropriate info, leaving the quotation marks. What this will (should) do is fire the dialog once you walk into the trigger, then it will destroy the trigger, preventing the game from trying to fire the dialog again. Oh, that's the part I forgot! I walked him through triggers this morning in the chat, but I forgot to do the DestroyObject part in the script... Thanks, both of you I haven't had the time to try the trigger but I was wondering if it wouldn't trigger the conversation everytime you go there. But with that additional part of the script I should be able to make it work. Quote Share this post Link to post Share on other sites
Hassat Hunter 571 Posted August 29, 2015 OE rather doesn't destroy the trigger, but rather adds a local to it, then checks if it's already set. If not, trigger is available. Very handy if you want to use the same trigger for multiple events (like say, the exit trigger in Dxun's Mandalorian Camp or the EH enter trigger on Nar Shaddaa). Quote Share this post Link to post Share on other sites
VarsityPuppet 1,085 Posted August 29, 2015 Also, starting dialogs with triggers can very occasionally crash your game. Quote Share this post Link to post Share on other sites
DrMcCoy 40 Posted September 2, 2015 Hmm, I have a question there, regarding how the game works: does that work, moving an NPC through a door into another module? I.e. after the creature left the module, does it appear in the target module when the PC then also moves through the door? Or do you need to fake that, by creating a copy of the creature in the target module (either statically, or from a script)? Somewhat relatedly, does GetObjectByTag() (and similar functions) work for objects outside the current module? I.e. if the PC is in module Foo1, and there's a module Foo2 with an object Bar2 in it, can I call, while inside Foo1, GetObjectByTag("Bar2") and have it return the object inside Foo2? I've always assumed that doesn't work; is that assumption correct? Quote Share this post Link to post Share on other sites
Fair Strides 509 Posted September 2, 2015 OE rather doesn't destroy the trigger, but rather adds a local to it, then checks if it's already set. If not, trigger is available. Very handy if you want to use the same trigger for multiple events (like say, the exit trigger in Dxun's Mandalorian Camp or the EH enter trigger on Nar Shaddaa). Yeah, K1 does that too. I believe it's UT_GetTrapTriggered or something like that from the k_inc_generic or k_inc_utility. Hmm, I have a question there, regarding how the game works: does that work, moving an NPC through a door into another module? I.e. after the creature left the module, does it appear in the target module when the PC then also moves through the door? Or do you need to fake that, by creating a copy of the creature in the target module (either statically, or from a script)? Somewhat relatedly, does GetObjectByTag() (and similar functions) work for objects outside the current module? I.e. if the PC is in module Foo1, and there's a module Foo2 with an object Bar2 in it, can I call, while inside Foo1, GetObjectByTag("Bar2") and have it return the object inside Foo2? I've always assumed that doesn't work; is that assumption correct? The KotOR games operate only on the loaded level, so faking it is very necessary. That should also answer your second question. Quote Share this post Link to post Share on other sites
DrMcCoy 40 Posted September 2, 2015 The KotOR games operate only on the loaded level, so faking it is very necessary. That should also answer your second question. Okay, thanks. So those assumptions I made (based on my more in-depth knowledge of NWN) are correct, then. Quote Share this post Link to post Share on other sites
DarthTyren 103 Posted September 2, 2015 GetObjectByTag() can, however, access objects in BIF files or the Override folder, if an object isn't made more specific in the GIT files (the way waypoints are). Quote Share this post Link to post Share on other sites
DrMcCoy 40 Posted September 2, 2015 Wait, what? Does that mean that GetObjectByTag() reads all object template files (.ut?) the game has access to, and checks their tags? EDIT: And since GetObjectByTag() returns an object, does it mean it creates an object according to the template? Quote Share this post Link to post Share on other sites
Fair Strides 509 Posted September 2, 2015 A slight misunderstanding, I believe. The GetObjectByTag() function can only be used in a module and only on the objects spawned in the module. The CreateObject function, however, can use files from the Override, the module, and the BIF archives, in that order. Quote Share this post Link to post Share on other sites
DrMcCoy 40 Posted September 2, 2015 Ah, okay, that would make more sense, yes (and again matches that huge list of mine with unverified assumptions ). Thanks. Quote Share this post Link to post Share on other sites
DarthTyren 103 Posted September 2, 2015 A slight misunderstanding, I believe. The GetObjectByTag() function can only be used in a module and only on the objects spawned in the module. The CreateObject function, however, can use files from the Override, the module, and the BIF archives, in that order. Oops. CreateObject() is what I meant. My bad. Quote Share this post Link to post Share on other sites