Fair Strides

Fair Strides' Script Shack

Recommended Posts

Nope! The GetPartyMemberByIndex function works off of the current party you're walking around with. It starts at 0 (the character the player is controlling) and goes up to 2. When it hits 3, the object doesn't exist and the while section is done.

 

Also, you'll want to correct my typo...

 

Inside the while block, I have:

iIndex++;

oTarget = GetPartyMemberByindex(iIndex);

 

You'll want to change that to this:

 

iIndex++;
oTarget = GetPartyMemberByIndex(iIndex);

Share this post


Link to post
Share on other sites

Might try changing "ActionJumpToLocation" to "ActionForceJumpToLocation".

 

Otherwise, just change the coordinates in the module.ifo file. Also, are you using the coordinates I posted above, or are you using 200 as the X? If so, I don't think that's a valid coordinate (as far as the walkmesh is concerned), so you might try the 244.

Share this post


Link to post
Share on other sites

I'd actually forgotten to change it, but no, there didn't appear to be any change. 244 is still in the room, but the change was quite noticeable when I changed it via the IFO (it's just in front of the door).

 

I'll play around with it some more, more so for getting my head around scripting than anything else.

 

Edit: Interesting. I tried this:

void main() {
	if ((GetIsPC(GetEnteringObject()) == 1))
	{
		int iIndex = 0;
		while(iIndex <= 8)
		{
			RemovePartyMember(iIndex);
			(iIndex++);
		}
		AssignCommand(GetFirstPC(), ActionStartConversation(GetObjectByTag("DarthMalak"), "scene_06", 0, 0, 1, "", "", "", "", "", ""));
		PlayRoomAnimation("StuntRoom40d", 1);
    }
}
On the Leviathan the whole party was still standing in the middle of the room. However, in the subsequent Ebon Hawk scene the party (Zaalbar and Canderous in this case) were gone. So the script worked, just to no effect in the Leviathan level. The IFO edit will hide them, but I'm very curious as to what exactly the cause of their appearance is, and why they resist being scripted away.

 

Edit 2: If I add

AssignCommand(GetFirstPC(), JumpToObject(GetObjectByTag("WP03", 0), 1));
I can get the player to jump to that waypoint (which is off to the side a bit). However, if I try

AssignCommand(GetPartyMemberByIndex(0), JumpToObject(GetObjectByTag("WP03", 0), 1));
for any index 0, 1, 2, nothing happens (with or without the party remove loop). I also tried GetNextPC(), but that didn't have any effect either.

 

Edit 3: Adding

AssignCommand(GetFirstPC(), JumpToObject(GetObjectByTag("WP03", 0), 1));
AssignCommand(GetObjectByTag("Zaalbar", 0), JumpToObject(GetObjectByTag("WP03", 0), 1));
AssignCommand(GetObjectByTag("Cand", 0), JumpToObject(GetObjectByTag("WP03", 0), 1));
works, jumping all of my current party to the waypoint.

 

Edit 4: Seems like teleporting is stuck within the confines of the walkmesh however. IFO editing it is.

Share this post


Link to post
Share on other sites

Nope! The GetPartyMemberByIndex function works off of the current party you're walking around with. It starts at 0 (the character the player is controlling) and goes up to 2. When it hits 3, the object doesn't exist and the while section is done.

 

That's actually incorrect for some reason. I learned that when I tried to fix the second party member spawning in the middle of the Korriban academy when you enter it and it is hostile. And the vanilla OnEnter script used GetPartyMemberByIndex(1) and GetPartyMemberByIndex(2) to teleport the entrance the player comes from. This however didn't work. Only when I changed the indices to 0 and 1 it did.

 

That said, given the gravity of the situation surrounding the escape, I think it would make sense in the EH scene if everyone were in the cockpit. There are two passenger seats, so perhaps Mission and Canderous could be seated on those, with Zaalbar and T3 standing out of the way in the back corner (behind Bastila). Looking at m12aa_01q, the room animation appears to only be switching out the skybox (which is actually pretty clever). The character animations for Carth and Bastila would seem to be all done via scene_start.dlg, so presumably additional ones could be added for the rest of the team, with extra waypoints for positioning. For the script side of things, would it just be a case of duplicating the existing entries for the rest of the team?

 

 

Without looking at the module itself, stunt modules usually use waypoints to position their characters. So instead of adding a new script, you could just move the waypoints inside the cockpit to have them appear there. Then you'd of course need to add some script that makes Mission and Canderous sit down but that still seems easier than teleporting all characters.

Share this post


Link to post
Share on other sites

Yeah I'll just add in extra waypoints for the locations I need. I have already despawned the party in previous module via the script I posted above, so now it should just be a case of duplicating the existing spawning and positioning scripts for Bastila and Carth and changing them as needed for the rest of the party.

Share this post


Link to post
Share on other sites

I should've looked at the module before making my last post as I expected the stunt module to have waypoints for all the characters but it seems like they didn't use waypoints for this scene setup. That would've made things easier though.

Share this post


Link to post
Share on other sites

Then you'd of course need to add some script that makes Mission and Canderous sit down but that still seems easier than teleporting all characters.

 

Sitting cannot be scripted in K1. To have Mission and Canderous sit in that scene would require new cutscene animation models.

Share this post


Link to post
Share on other sites

Sitting cannot be scripted in K1. To have Mission and Canderous sit in that scene would require new cutscene animation models.

 

Oh right, that's because there's no sitting animation? Or is there some other reason?

Share this post


Link to post
Share on other sites

There are plenty of animations available, just no convenient one on the supermodel that anybody can use anywhere like K2 has. In K1 all sitting is done either through a cutscene animation or with an animation on the model itself (usually an animated placeable). I'm not sure why they did it that way, seems really inefficient. For example, every single bridge officer on the Leviathan uses a different cutscene model.

 

So there's no lack of sources for sitting animations, but the way cutscene animations work you'd need a new model for each character, so it can be a pain. K1 has another big problem in that there are a very limited number of animations that can be scripted. So even if you wanted to mess around with the supermodel to add a generic animation, you'd be limited to utilizing one of the unused animation constants, such as ANIMATION_LOOPING_KNEEL_TALK_ANGRY. So that's even more of a pain than making new cutscene animations.

 

Or you can teleport them out of the scene. :D

Share this post


Link to post
Share on other sites

I've been trying to figure out this one script for the past few hours now for kotor 1. I've created a basic conversation with a custom NPC in which the player talks to the NPC, and the NPC offers to take the PC somewhere. The player has the choice to either accept or decline. Upon accepting the PC is supposed to be warped to another module, this is where I'm stuck. I've set a script to fire upon the agreement dialogue ending and nothing seems to happen. I'm not very good at scripting as of yet, since I've just started doing it for kotor. I spent a good few minutes reading this whole thread to see what I find, and used what seemed to be relevant, and this is what I've got as a script so far:

void main(){

SetGlobalBoolean("EH_WARP", TRUE);
StartNewModule("tat_m17mg");

}

I've noticed also that when I try and compile my scripts, a message comes up stating that it was "Unable to open input file 'C:\Users\USER\Desktop\kotor modding\mods\dan_m13_2\k_dan_swoop.ncs". So I don't know if maybe this has something to do with it.

Share this post


Link to post
Share on other sites
etc...

Assuming you edited the dlg file using the dlgeditor and put the script in the Script Fire section, and placed it into the override folder. Then I think your issue is saving the script.

 

SetGlobalBoolean("EhWarp",TRUE); /// This is completely useless.

Booleans in kotor work on referencing the globalcat.2da file, like memory keys, they have to exist in the globalcat.2da file, else they won't have any impact.

However, I'd recommend not including this at all merely because it is completely unnecessary to warp the player from one location to another. 

 

Unless you have a good reason to do so, then you'd want to edit the global.2da and add a line to that with your tag "EhWarp" and label it as a Boolean. 

 

The rest of your script is correct,

void main() {

StartNewModule("tag of module goes here");
}

 

 

However, you'll need the nwsscript.nss in your override, which you can extract using the Kotor Tool in the source script section of the BIFs.

Finally, you'll want to set the script to K1 script, then compile it by selecting "compile" which will ask you to save it somewhere, save it as "whatever.nss" the .nss is very important, then it will compile as a .ncs file. You'll end up with two files, the .ncs is the compiled/working version, while the .nss is the source script.

 

After you've finished remember to put all the files in the necessary folders within kotor, in this case 2da files, scripts, dlg files can all go into the override. 

  • Like 1

Share this post


Link to post
Share on other sites
etc...

Thank you so much! I did everything you suggested and it worked. Would never have thought of that myself. I genuinely can't thank you enough.

  • Like 1

Share this post


Link to post
Share on other sites

I am trying to make Starting Conditional which checks if my PC has equipped cartain item and here's my attempt. Could somebody tell me what is wrong with it? (I wanted it to check the main hand but to be honest i don't know if i have the right number in GetItemInSlot() function)

Quote

int StartingConditional()
{
object oPC = GetFirstPC();
object item = GetItemInSlot(16, oPC);
object lsbr = GetObjectByTag("g1_w_lghtsbr01");
if(item == lsbr)
{
return TRUE;
}
return FALSE;

}

 

Share this post


Link to post
Share on other sites

I haven't verified that it would work, and I don't know the slot numbers, but it seems to me like you probably want to avoid object comparison, so maybe:

...
if (GetTag(item) == "g1_w_lghtsbr01") {
...

Also, I think this code would send the value of GetTag(item) to your in-game message log so you could see if you were getting the expected value (i.e. if your slot number is correct):

SendMessageToPC(oPC, GetTag(item));

 

Share this post


Link to post
Share on other sites

It's probably this one:

// 724. GetLastCombatFeatUsed
// Returns the last feat used (as a feat number that indexes the Feats.2da) by the given object
int GetLastCombatFeatUsed(object oAttacker = OBJECT_SELF);

But there are other similar functions:

// 317: Get the attack type (SPECIAL_ATTACK_*) of oCreature's last attack.
// This only works when oCreature is in combat.
int GetLastAttackType(object oCreature=OBJECT_SELF);

// 318: Get the attack mode (COMBAT_MODE_*) of oCreature's last attack.
// This only works when oCreature is in combat.
int GetLastAttackMode(object oCreature=OBJECT_SELF);

// 722. GetLastAttackAction
// Returns the last attack action for a given object
int GetLastAttackAction(object oAttacker = OBJECT_SELF);

I'm not sure what they do, if anything.

EDIT: GetLastCombatFeatUsed() does work. It returns the integer of the feat as defined in feat.2da. However, it is only updated when a feat is used. So if you use power attack, then perform a regular attack or cast a spell, then check what your last feat used was, it will still return as power attack. I don't know of any way to determine for certain if a feat was just used in the last combat round and if anybody does know of one, I'm interested to hear it.

GetLastAttackType() and GetLastAttackMode() are garbage. They always return 0 (invalid) despite others being defined.

The GetLastAttackAction() result is from the usual action table (e.g. ACTION_ATTACKOBJECT and ACTION_CASTSPELL).

Share this post


Link to post
Share on other sites

If I am scripting characters to run to a set destination, how do I toggle running instead of walking? I tried this (I could be completely off), but they still walk to the destination:

 

void main() {


object oCarth = GetObjectByTag("Carth");
object oCand = GetObjectByTag("Cand");
object oMission = GetObjectByTag("Mission");
object oZaalbar = GetObjectByTag("Zaalbar");

int  bRun = TRUE;

location lCandRun = Location(Vector(215.25, 333.43, 25.23), 0.0);
location lMissionRun = Location(Vector(217.01, 331.91, 24.92), 0.0);
location lZaalbarRun = Location(Vector(215.63, 330.38, 24.62), 0.0);
location lCarthRun = Location(Vector(214.22, 332.15, 24.97), 0.0);

DelayCommand(3.0, AssignCommand(oCand, ActionMoveToLocation(lCandRun)));
DelayCommand(3.8, AssignCommand(oZaalbar, ActionMoveToLocation(lZaalbarRun)));
DelayCommand(3.5, AssignCommand(oMission, ActionMoveToLocation(lMissionRun)));
DelayCommand(3.4, AssignCommand(oCarth, ActionMoveToLocation(lCarthRun)));

}

 

Share this post


Link to post
Share on other sites

Try

// 382: Force the action subject to move to lDestination.
void ActionForceMoveToLocation(location lDestination, int bRun=FALSE, float fTimeout=30.0f);
DelayCommand(3.0, AssignCommand(oCand, ActionForceMoveToLocation(lCandRun, TRUE)));

Or you can use a waypoint instead with

// 383: Force the action subject to move to oMoveTo.
void ActionForceMoveToObject(object oMoveTo, int bRun=FALSE, float fRange=1.0f, float fTimeout=30.0f);
object oObject = GetObjectByTag("CREATURE_TAG", 0);
object oWP = GetWaypointByTag("WAYPOINT_TAG");

AssignCommand(oObject, ActionForceMoveToObject(oWP, TRUE));

 

Share this post


Link to post
Share on other sites
7 minutes ago, DarthParametric said:

Try


// 382: Force the action subject to move to lDestination.
void ActionForceMoveToLocation(location lDestination, int bRun=FALSE, float fTimeout=30.0f);

DelayCommand(3.0, AssignCommand(oCand, ActionForceMoveToLocation(lCandRun, TRUE)));

 

Tried that, but I'm now getting this error at can't figure out what it meant.

My script is:

 

void main() {


object oCarth = GetObjectByTag("Carth");
object oCand = GetObjectByTag("Cand");
object oMission = GetObjectByTag("Mission");
object oZaalbar = GetObjectByTag("Zaalbar");

int  bRun = TRUE;

void ActionForceMoveToLocation(location lDestination, int bRun=FALSE, float fTimeout=30.0f);

location lCandRun = Location(Vector(215.25, 333.43, 25.23), 0.0);
location lMissionRun = Location(Vector(217.01, 331.91, 24.92), 0.0);
location lZaalbarRun = Location(Vector(215.63, 330.38, 24.62), 0.0);
location lCarthRun = Location(Vector(214.22, 332.15, 24.97), 0.0);

DelayCommand(3.0, AssignCommand(oCand, ActionForceMoveToLocation(lCandRun, TRUE)));
DelayCommand(3.8, AssignCommand(oZaalbar, ActionForceMoveToLocation(lZaalbarRun, TRUE)));
DelayCommand(3.5, AssignCommand(oMission, ActionForceMoveToLocation(lMissionRun, TRUE)));
DelayCommand(3.4, AssignCommand(oCarth, ActionForceMoveToLocation(lCarthRun, TRUE)));


}

2018-11-19 12_20_02-Text Editor - grouprun.nss.jpg

Share this post


Link to post
Share on other sites

Yeah you don't want to include the example syntax (edited my previous post to break them up). This compiles:

void main() {

object oCarth = GetObjectByTag("Carth");
object oCand = GetObjectByTag("Cand");
object oMission = GetObjectByTag("Mission");
object oZaalbar = GetObjectByTag("Zaalbar");

location lCandRun = Location(Vector(215.25, 333.43, 25.23), 0.0);
location lMissionRun = Location(Vector(217.01, 331.91, 24.92), 0.0);
location lZaalbarRun = Location(Vector(215.63, 330.38, 24.62), 0.0);
location lCarthRun = Location(Vector(214.22, 332.15, 24.97), 0.0);

DelayCommand(3.0, AssignCommand(oCand, ActionForceMoveToLocation(lCandRun, TRUE)));
DelayCommand(3.8, AssignCommand(oZaalbar, ActionForceMoveToLocation(lZaalbarRun, TRUE)));
DelayCommand(3.5, AssignCommand(oMission, ActionForceMoveToLocation(lMissionRun, TRUE)));
DelayCommand(3.4, AssignCommand(oCarth, ActionForceMoveToLocation(lCarthRun, TRUE)));
}

 

  • Thanks 1
  • Light Side Points 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.