arsenalforever Posted March 26, 2013 Share Posted March 26, 2013 I made the following script by following a tutorial video on YouTube for TSL: void main() { object ONPC = GetObjectByTag("dgon"); int bPassive=FALSE; AssignCommand(ONPC, ActionAttack(GetFirstPC(), bPassive)); } How do I execute the above script? I'm using KOTOR tool and know C++ Link to comment Share on other sites More sharing options...
supreme kotor Posted March 26, 2013 Share Posted March 26, 2013 I will admit I am extremely new to modding in general but to me it seems your just trying to make a NPC attack you called from Dialog? If that is what your doing I would use this script then attach it in the dialog to script that fires when spoken. void main() { object oNPC=GetObjectByTag(your_NPC); ChangeToStandardFaction(oNPC, 1); } Just replace your_NPC with the NPC's tag hope this helps Link to comment Share on other sites More sharing options...
Fallen Guardian Posted March 26, 2013 Share Posted March 26, 2013 I made the following script by following a tutorial video on YouTube for TSL: void main() { object ONPC = GetObjectByTag("dgon"); int bPassive=FALSE; AssignCommand(ONPC, ActionAttack(GetFirstPC(), bPassive)); } How do I execute the above script? I'm using KOTOR tool and know C++ That script looks right... so what exactly is your question? Do you want to know how to compile the script or get it to actually play in-game (getting it to play in-game could be done in a number of ways, so it would be helpful to know where/when/during what event you intend to have this script executed)? Link to comment Share on other sites More sharing options...
arsenalforever Posted March 27, 2013 Author Share Posted March 27, 2013 I compiled the script, got no errors and saved an nss file on the desktop (got an ncs file too). Now how do I get it to run in the game? I just want to test if it's working correctly. Also, can you tell me what GetFirstPc() does? Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 27, 2013 Share Posted March 27, 2013 I compiled the script, got no errors and saved an nss file on the desktop (got an ncs file too). Now how do I get it to run in the game? I just want to test if it's working correctly. Also, can you tell me what GetFirstPc() does? The .nss file is the source code that you just compiled; the .ncs("c" is compiled, "s" in .nss is source) is what the game will need. The function GetFirstPC() starts cycling through the party, and selects the first player character(which is whoever you are controlling when the script runs). The partner function GetNextPC() continues to cycle through and gets the second party member. One uses those together if they wanted to select a certain party member based on their position in the party, for instance. If all you want to do is test the script, then you'll need the person with the tag "dgon", which is done in the .utc file, to exist by spawning him/her. Follow the tutorial link up above, by editing an existing file the way you want and saving it as something new, and when you get to the scripts, put the name of the modified version of your script in the OnSpawn section. Your modified script: void main() { object ONPC = OBJECT_SELF; int bPassive=FALSE; AssignCommand(ONPC, ActionAttack(GetFirstPC(), bPassive)); } Then edit the spells.2da file, preferably the one in your override folder if it exists, and copy an armband line and copy it into the bottom row(hint: double-click on the asterisk to add a new blank line). edit the entry in the "impactscript" column to be a script named something like "create_dgon"(NO extension!). For the script create_dgon, I would use this: void main() { string sDgon = ;\\ Whatever the template for dgon is(see .utc tutorial above) object oDgon = CreateObject(OBJECT_TYPE_CREATURE,sDgon, GetLocation(GetFirstPC())); } Then have an armband made with a property to activate an item and select the row you added to spells.2da. To be able to see the added row, you need to turn on an option to use .2da files found in override. P.S: Sorry for the absurdly long post, but I know it'll help you, especially the links. If you have any questions, feel free to ask. P.P.S: I know perl. Link to comment Share on other sites More sharing options...
arsenalforever Posted March 27, 2013 Author Share Posted March 27, 2013 Can you explain in more detail about what I need to do or could you suggest a place where I can learn from the very beginning? What I basically wanted to do is spawn an NPC in my current location, talk to him and then make him attack me. I wouldn't mind if the NPC looked like Mandalore or Atton or anyone else for that matter. Thanks EDIT: What is the OnSpawn section? I made the .utc file of the NPC I want thanks to the first link on your reply. And there is no spells.2da file in my Override folder. What should I do? Why did you replace object ONPC = GetObjectByTag("dgon"); with object ONPC = OBJECT_SELF; Link to comment Share on other sites More sharing options...
arsenalforever Posted March 29, 2013 Author Share Posted March 29, 2013 Okay, I've managed to write this piece of code thanks to zbyl2 on the Deadly Stream forums: void main() { object oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean", Location(Vector(25.0,34.0,65.0), 0.0f)); DelayCommand(5.0, AssignCommand(oNPC, ActionStartConversation(GetFirstPC(),"Gamorrean"))); } Now how do I get it to run once I'm on Onderon and go anywhere near the gammorean? Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 30, 2013 Share Posted March 30, 2013 Okay, I've managed to write this piece of code thanks to zbyl2 on the Deadly Stream forums: void main() { object oNPC = CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean", Location(Vector(25.0,34.0,65.0), 0.0f)); DelayCommand(5.0, AssignCommand(oNPC, ActionStartConversation(GetFirstPC(),"Gamorrean"))); } Now how do I get it to run once I'm on Onderon and go anywhere near the gammorean? You can make a custom OnHeartbeat script which will check if you are X meters away from him, and if so, execute the script. void main() { ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_DEFAULT_EVENT_ON_HEARTBEAT); if(GetLastPerceived() == GetFirstPC) { ExecuteScript("convstart", OBJECT_SELF); } } That code should work if placed as the OnHeartbeat script. All you have to do is replace "convstart" with the name of your and Zybl's script, while still being in quotes. If it son't work, come back and I'll try to help. Link to comment Share on other sites More sharing options...
arsenalforever Posted March 30, 2013 Author Share Posted March 30, 2013 The OnHeartBeat script should be a new one right? All I have to do is replace convstart with the name of my .ncs file? What about k_ai_master? Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 30, 2013 Share Posted March 30, 2013 The OnHeartBeat script should be a new one right? All I have to do is replace convstart with the name of my .ncs file? What about k_ai_master? Yeah, just enter a new name in the OnHeartbeat field. And yes on the convstart stuff, minus the .ncs. And no on the k_ai_master. That's a master script that controls ALL behavior for npc, pc, and creature things in the game. It's referenced from the default On* scripts. Link to comment Share on other sites More sharing options...
arsenalforever Posted March 30, 2013 Author Share Posted March 30, 2013 So my final code will be: void main() { ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_DEFAULT_EVENT_ON_HEARTBEAT); if(GetLastPerceived() == GetFirstPC) { ExecuteScript("talk", OBJECT_SELF); } } right? The script me and zbyl2 made is saved by the name of "talk.ncs" on the desktop. Also, I have a few questions regarding the above script: 1. What do the second and third parameter indicate in the ExecuteScript function? 2. Can you explain what the if condition actually means? What does it do? Thanks. 3. What name should I save the above script as? What should I do next? 4. What should I write in place of "KOTOR_DEFAULT_EVENT_ON_HEARTBEAT"? Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 30, 2013 Share Posted March 30, 2013 So my final code will be: void main() { ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_DEFAULT_EVENT_ON_HEARTBEAT); if(GetLastPerceived() == GetFirstPC) { ExecuteScript("talk", OBJECT_SELF); } } right? The script me and zbyl2 made is saved by the name of "talk.ncs" on the desktop. Also, I have a few questions regarding the above script: 1. What do the second and third parameter indicate in the ExecuteScript function? 2. Can you explain what the if condition actually means? What does it do? Thanks. 3. What name should I save the above script as? What should I do next? 4. What should I write in place of "KOTOR_DEFAULT_EVENT_ON_HEARTBEAT"? 1. They mean the target of the script and the script variable repectively. The script variable is a number or Constant(which can be words) and is passed to the script. The third arguement above will execute the code in the block following the arguement. An example is the spell system; it uses one execution script and one reference script that has all the spell code in it, just switched based on the Constant passed to it. 2. The if statement will perform a calculation based on data returned to it. It will compare the pieces of data(in this case whatever is returned by my functions) using a given operator(==, !=). It returns a 1(True) or 0(False). If it returns true, it does whatever's in the code block, if it returns false, the script skips the code block and continues. P.S: You can make an if statement do more than one calculation by using &&(which means "AND") and ||(which means "OR"). Useful for checking if a person is visible AND is the first pc, for instance. Another example: You check if the target is a Soldier OR a Scout. 3. Any name you want, so long as it matches the OnHeartbeat script's field. Now if it compiles, move the .ncs for it and the talk.ncs to your override folder, along with the .utc file. Follow this tutorial to make your guy spawn when you enter the module. Just use this code as the OnEnter script and you should be okay(though you'll have to know which module script it is, which you can get the same as the .utc but with a module's .ifo file under "Tsl or Kotor->rims-your module".): void main() { vector Spawn; \\ declare a vector Spawn.x = f; \\ Specify the x-coordinate Spawn.y = f; \\ Specify the y-coordinate Spawn.z = f; \\ Specify the z-coordinate float a = f; \\ Specify the float(direction the creature will face) CreateObject(OBJECT_TYPE_CREATURE, "dgon", location(Spawn, a)); \\ Easy made location with the vector and float all wrapped up ExecuteScript("Name of module's script here", OBJECT_SELF); } That oughta work, and if you don't understand what's going on here, then check my PM about the nwn lexicon. P.S: If you want the script to activate when you're 3 meters from the gamorrean, use this(just replace the 3 if you want a different distance): void main() { ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_DEFAULT_EVENT_ON_HEARTBEAT); if(GetLastPerceived() == GetFirstPC && GetDistanceToObject(GeFirstPC()) == 3) { ExecuteScript("talk", OBJECT_SELF); } } 4. Nothing. Keep it as it is. Link to comment Share on other sites More sharing options...
arsenalforever Posted March 30, 2013 Author Share Posted March 30, 2013 Is the second parameter of ExecuteScript() always OBJECT_SELF? What does the GetLastPerceived() function do? And I get an error when I'm compiling the first script. The error has something to do with the compiler not being able to identify KOTOR_DEFAULT_EVENT_ON_HEARTBEAT. Also, why have you not used KOTOR_DEFAULT_EVENT_ON_HEARTBEAT parameter in the if condition? Thanks for your reply Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 31, 2013 Share Posted March 31, 2013 Is the second parameter of ExecuteScript() always OBJECT_SELF? What does the GetLastPerceived() function do? And I get an error when I'm compiling the first script. The error has something to do with the compiler not being able to identify KOTOR_DEFAULT_EVENT_ON_HEARTBEAT. Also, why have you not used KOTOR_DEFAULT_EVENT_ON_HEARTBEAT parameter in the if condition? Thanks for your reply 1. You don't have to, but the second parameter is the target that calls the script. The caller is used by a lot of functions, but an example is giving the parameter as: object oAtton = GetObjectByTag("atton"); ExecuteScript("k_ai_master", oAtton, 1001); This will make any instances of "OBJECT_SELF" be Atton. 2. The GetLastPercieved() function will return the last creature percieved through any means. It will return the most recent creature detected by hearing, seeing, or a combination of a lack of one or the other. If you want to be more specific, there are functions to get the last percieved thing by sight or hearing(GetLastPercievedHeard() and GetLastPercievedSeen()). 3. There is a code loop syntax called the switch statement. It will take an integer variable and execute a section of code based on that integer. Here's a sample of code from K_ai_master to show you: /* //DEFAULT AI EVENTS int KOTOR_DEFAULT_EVENT_ON_HEARTBEAT = 1001; int KOTOR_DEFAULT_EVENT_ON_PERCEPTION = 1002; int KOTOR_DEFAULT_EVENT_ON_COMBAT_ROUND_END = 1003; int KOTOR_DEFAULT_EVENT_ON_ATTACKED = 1005; int KOTOR_DEFAULT_EVENT_ON_DAMAGE = 1006; int KOTOR_DEFAULT_EVENT_ON_DEATH = 1007; int KOTOR_DEFAULT_EVENT_ON_DISTURBED = 1008; int KOTOR_DEFAULT_EVENT_ON_BLOCKED = 1009; int KOTOR_DEFAULT_EVENT_ON_FORCE_AFFECTED = 1010; int KOTOR_DEFAULT_EVENT_ON_GLOBAL_DIALOGUE_END = 1011; int KOTOR_DEFAULT_EVENT_ON_PATH_BLOCKED = 1012; */ case 1001: //KOTOR_DEFAULT_EVENT_ON_HEARTBEAT { ... } case 1002: // KOTOR_DEFAULT_EVENT_ON_PERCEPTION { ... } So, for your compile error, try replacing the "KOTOR_DEFAULT_EVENT_ON_HEARTBEAT" with "1001". Also, I didn't use it in the if conditional because it wasn't needed. The script is the OnHeartbeat, so there's no point in calling the script your currently running. 4. And no problem. I'm happy to share my scripting knowledge. Link to comment Share on other sites More sharing options...
arsenalforever Posted March 31, 2013 Author Share Posted March 31, 2013 I showed zbyl2 your script and this is what he had to say: That latest script you posted suggests you'd like to fire a script through NPC's OnHeartbeat event; bad way to do it - OnHeartbeat script is fired by game's engine every six seconds and is often unpredictable (as is GetLastPerceived() function due to the way engine works, GetDistanceToObject() would be better). Again, triggers would be better. Here is a list of the scripts I have currently (I'll make the conversation scripts later. I just want to see if the Gammorean is spawning correctly): 1. Gamspawn101.nss void main() { object oEntering = GetEnteringObject(); object Gamtest = GetObjectByTag("g_gammorean01"); if(GetIsPC(oEntering)) { if(GetIsObjectValid(Gamtest)==FALSE) { ExecuteScript("gamspawn",OBJECT_SELF); } } ExecuteScript("k_501_enter",OBJECT_SELF); } 2. gamspawn.nss: void main() { vector Spawn; Spawn.x = 24.0; Spawn.y = 34.0; Spawn.z = 65.0; CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean01", Location(Spawn,0.0)); ExecuteScript("k_501_enter", OBJECT_SELF); } The OnEnter value for Iziz Airport was k_501_enter but why do I need to execute k_501_enter at the end of both the scripts? Are the above two scripts enough for me to be able to see the Gammorean in the Iziz Spaceport? Thanks. Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 31, 2013 Share Posted March 31, 2013 I showed zbyl2 your script and this is what he had to say: Here is a list of the scripts I have currently (I'll make the conversation scripts later. I just want to see if the Gammorean is spawning correctly): 1. Gamspawn101.nss void main() { object oEntering = GetEnteringObject(); object Gamtest = GetObjectByTag("g_gammorean01"); if(GetIsPC(oEntering)) { if(GetIsObjectValid(Gamtest)==FALSE) { ExecuteScript("gamspawn",OBJECT_SELF); } } ExecuteScript("k_501_enter",OBJECT_SELF); } 2. gamspawn.nss: void main() { vector Spawn; Spawn.x = 24.0; Spawn.y = 34.0; Spawn.z = 65.0; CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean01", Location(Spawn,0.0)); ExecuteScript("k_501_enter", OBJECT_SELF); } The OnEnter value for Iziz Airport was k_501_enter but why do I need to execute k_501_enter at the end of both the scripts? Are the above two scripts enough for me to be able to see the Gammorean in the Iziz Spaceport? Thanks. That ExecuteScript() part in the second one isn't necessary, sorry about that. Those two scripts should be enough, but there are two things to point out: 1. Each of the numbers for the spawn vector and the float in the location have to have an "f" on the end, like "0.0f". Otherwise the compiler might throw an error, and the game might not execute it correctly. 2. Did you get the coordinates from the game, or are these a guess? P.S: As to zybl2's comment, I don't have a problem with it. I was going to tell you about the triggers, but you were focused on testing it in-game and the triggers aren't one of the gff file types I'm particularly familiar with... Link to comment Share on other sites More sharing options...
arsenalforever Posted March 31, 2013 Author Share Posted March 31, 2013 The coordinates are a guess. How do I get the precise ones? And do all float values depicting vectors have to be followed by an f? And why is executing "k_501_enter" necessary in the first script? Link to comment Share on other sites More sharing options...
arsenalforever Posted March 31, 2013 Author Share Posted March 31, 2013 Okay so here are the final scripts: 1. gamspawn.nss: void main() { vector Spawn; Spawn.x = -23.47745f; Spawn.y = 80.85285f; Spawn.z = 12.74702f; float a = 0.99720; CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean01", Location(Spawn,a)); } 2. gamespawn101.nss void main() { object oEntering = GetEnteringObject(); object Gamtest = GetObjectByTag("g_gammorean01"); if(GetIsPC(oEntering)) { if(GetIsObjectValid(Gamtest)==FALSE) { ExecuteScript("gamspawn",OBJECT_SELF); } } ExecuteScript("k_501_enter",OBJECT_SELF); } I got the precise coordinates with the help of the whereami armband. But I'm still unable to see the Gamorrean? All I did was placed the .ncs files of the above scripts in the override folder. What am I doing wrong? Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted March 31, 2013 Share Posted March 31, 2013 Okay so here are the final scripts: 1. gamspawn.nss: void main() { vector Spawn; Spawn.x = -23.47745f; Spawn.y = 80.85285f; Spawn.z = 12.74702f; float a = 0.99720; CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean01", Location(Spawn,a)); } I got the precise coordinates with the help of the whereami armband. But I'm still unable to see the Gamorrean? All I did was placed the .ncs files of the above scripts in the override folder. What am I doing wrong? Need to add an f to the end of float a. I was waiting to explain this until youhad the scripts done. You need to use the erf editor to open the .mod file for your module from your modules folder(I'd back it up first). Then you need to extract the .ifo an open it with a gff editor and change the Mod_OnLoad field to the name of your custom script, minus the extension. Then you'll have to save the file and add it back to the .mod file. Now save said .mod file and then try it in-game. If you have any questions, just ask. Link to comment Share on other sites More sharing options...
arsenalforever Posted April 1, 2013 Author Share Posted April 1, 2013 I don't need to add the f after a in the Location function right? Only in the initialization of the float right? In this case, what is the name of my custom script? Is it gamspawn or gamspawn101? And why do we have to execute k_501_enter at the end of gamspawn101? Thanks Link to comment Share on other sites More sharing options...
arsenalforever Posted April 1, 2013 Author Share Posted April 1, 2013 I'm still not able to see the Gamorrean. I've tried setting the Mod_OnLoad value to gamspawn as well as gamspawn101. Final Scripts: 1. gamspawn.nss void main() { vector Spawn; Spawn.x = -23.47745f; Spawn.y = 80.85285f; Spawn.z = 12.74702f; float a = 0.99720f; CreateObject(OBJECT_TYPE_CREATURE, "g_gammorean", Location(Spawn,a)); } 2. gamspawn101.nss void main() { object oEntering = GetEnteringObject(); object Gamtest = GetObjectByTag("c_ithorian"); if(GetIsPC(oEntering)) { if(GetIsObjectValid(Gamtest)==FALSE) { ExecuteScript("gamspawn",OBJECT_SELF); } } ExecuteScript("k_501_enter",OBJECT_SELF); } Link to comment Share on other sites More sharing options...
arsenalforever Posted April 1, 2013 Author Share Posted April 1, 2013 Here's a copy of my module.ifo file: -1 [TopLevelStruct] = Type:IFO Ver:V3.2 Expansion_Pack [WORD] = 0 Mod_Area_list [List] = ... 0 [user-defined Struct: 6] = ... Area_Name [CResRef] = 501ond Mod_Creator_ID [iNT] = 2 Mod_CutSceneList [List] = ... Mod_DawnHour [bYTE] = 6 Mod_Description [CExoLocString] = 0 strings Mod_DuskHour [bYTE] = 18 Mod_Entry_Area [CResRef] = 501ond Mod_Entry_Dir_X [FLOAT] = 0.707107126713 Mod_Entry_Dir_Y [FLOAT] = -0.707106471062 Mod_Entry_X [FLOAT] = -41.779552459717 Mod_Entry_Y [FLOAT] = 118.903518676758 Mod_Entry_Z [FLOAT] = 12.746200561523 Mod_Expan_List [List] = ... Mod_GVar_List [List] = ... Mod_Hak [CExoString] = Mod_ID [binary] = ... Mod_IsSaveGame [bYTE] = 0 Mod_MinPerHour [bYTE] = 2 Mod_Name [CExoLocString] = 0 strings Mod_OnAcquirItem [CResRef] = Mod_OnActvtItem [CResRef] = Mod_OnClientEntr [CResRef] = Mod_OnClientLeav [CResRef] = Mod_OnHeartbeat [CResRef] = Mod_OnModLoad [CResRef] = gamspawn Mod_OnModStart [CResRef] = Mod_OnPlrDeath [CResRef] = Mod_OnPlrDying [CResRef] = Mod_OnPlrLvlUp [CResRef] = Mod_OnPlrRest [CResRef] = Mod_OnSpawnBtnDn [CResRef] = Mod_OnUnAqreItem [CResRef] = Mod_OnUsrDefined [CResRef] = Mod_StartDay [bYTE] = 1 Mod_StartHour [bYTE] = 13 Mod_StartMonth [bYTE] = 6 Mod_StartMovie [CResRef] = Mod_StartYear [DWORD] = 1372 Mod_Tag [CExoString] = 501OND Mod_Version [DWORD] = 3 Mod_VO_ID [CExoString] = 501 Mod_XPScale [bYTE] = 10 Link to comment Share on other sites More sharing options...
Fair Strides 2 Posted April 1, 2013 Share Posted April 1, 2013 Just to be safe, could you check these?: 1. Are the .ncs files of the scripts in your override folder, along with the .utc? 2. You packed the module.ifo back into the .mod, right? 3. Could you please post the contents of your .utc file? Link to comment Share on other sites More sharing options...
arsenalforever Posted April 1, 2013 Author Share Posted April 1, 2013 I just want to spawn a Gammorean. Which utc should I place in the override folder? What value should be assigned to Mod_OnModLoad? gamspawn101 or gamspawn? And yeah, I have packed the module.ifo back into the .mod using the ERF editor (Tools->Add resource->module.ifo) What value should I assign to Mod_OnModLoad? It's currently set to gamspawn. And why do we have to execute "k_501_enter" in gamspawn101? Link to comment Share on other sites More sharing options...
arsenalforever Posted April 1, 2013 Author Share Posted April 1, 2013 I'll make a video of what I'm doing and I'll post it here btw, I have TSLRCM 1.8.2, Skip Peragus and Skip Telos Surface mods installed Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.