Jump to content

Home

scripting woes...


Simbacca

Recommended Posts

ok, here is what i am trying to do: the PC sees two custom characters locked in battle. lets just call one "Face" and the other "Heel".

 

i have set "Face's" faction to Prey and "Heel's" faction to Predator. i have ran a script and they both spawn at the same time about 5 steps away from each other, but they both just stand there, they do not engage in battle.

 

at Darth333's suggestion, i added this bit of code to one of the spawn scripts:

 

AssignCommand(GetObjectByTag("Attacker_tag"),ActionAttack(GetObjectByTag("Prey_Tag")));

 

so now Heel's spawn script is this:

 

#include "k_inc_debug"
#include "k_inc_utility"

void main() 
{
float x=31.14f;  
float y=32.48f;
float z=1.75f;
float r=0.0f;
vector vecNPC=Vector(x,y,z);
location locNPC=Location(vecNPC, r);
CreateObject(OBJECT_TYPE_CREATURE,"x_heel",locNPC);
AssignCommand(GetObjectByTag("x_heel"),ActionAttack(GetObjectByTag("x_face")));
}

 

but even with the addition of Darth333 recommended line, they still do nothing, they still just stand there.

 

what am i missing?

Link to comment
Share on other sites

It works for me. I just tried that:

void main()
{
//these 3 lines don't matter, it's just that I spawned them near my pc. Spawn them wherever you want
object oPC=GetFirstPC();
CreateObject(OBJECT_TYPE_CREATURE, "x", GetLocation(oPC));
CreateObject(OBJECT_TYPE_CREATURE, "y", GetLocation(oPC));

DelayCommand(0.5, AssignCommand(GetObjectByTag("x"),ActionAttack(GetObjectByTag("y"))));
}

One .utc had the prey faction and the other the predator faction (11 and 12 or vice versa, I don't remember).

 

However, make sure that you have the correct event or "behavior "scripts in your .utc files (those that start with k_def_blabla , such as k_def_heartbt01 in the heartbeat script per example) otherwise the attacker will just perform one attack round and the "battle" will stop.

Link to comment
Share on other sites

finally got it to work, but i have a new question.

 

when i did finally figure out the problem, i was to say the least angry. i mean, it was so simple i am way to embarrassed to say.

 

anywoo, my new question pertains to the battle these two npc's have. see "Face" and "Heel" are quite proficient in the ways of the force, yet in their battle, they only engage in melee attacks.

 

is their anyway, maybe by copying then altering the appropriate k_def script to make a new script or perhaps another means any of you are aware of, to cause them to use the force abilities more in this battle?

Link to comment
Share on other sites

anywoo, my new question pertains to the battle these two npc's have. see "Face" and "Heel" are quite proficient in the ways of the force, yet in their battle, they only engage in melee attacks.

 

is their anyway, maybe by copying then altering the appropriate k_def script to make a new script or perhaps another means any of you are aware of, to cause them to use the force abilities more in this battle?

 

Provided that the NPCs have a Jedi/Sith class and have force powers assigned in their template, this modified variant of the script Darth333 posted above would probably work:

 

void main() {
   location lLoc = GetLocation(GetFirstPC());
   object oFace = CreateObject(OBJECT_TYPE_CREATURE, "x", lLoc);
   object oHeel = CreateObject(OBJECT_TYPE_CREATURE, "y", lLoc);

   SetNPCAIStyle(oFace, NPC_AISTYLE_JEDI_SUPPORT);
   SetNPCAIStyle(oHeel, NPC_AISTYLE_JEDI_SUPPORT);
   SetLocalBoolean(oFace, 89, TRUE);
   SetLocalBoolean(oHeel, 89, TRUE);

   DelayCommand(0.5, ExecuteScript("k_ai_master", oFace, 1003));
   DelayCommand(0.5, ExecuteScript("k_ai_master", oHeel, 1003));
}

Link to comment
Share on other sites

Provided that the NPCs have a Jedi/Sith class and have force powers assigned in their template, this modified variant of the script Darth333 posted above would probably work:

 

void main() {
   location lLoc = GetLocation(GetFirstPC());
   object oFace = CreateObject(OBJECT_TYPE_CREATURE, "x", lLoc);
   object oHeel = CreateObject(OBJECT_TYPE_CREATURE, "y", lLoc);

   SetNPCAIStyle(oFace, NPC_AISTYLE_JEDI_SUPPORT);
   SetNPCAIStyle(oHeel, NPC_AISTYLE_JEDI_SUPPORT);
   SetLocalBoolean(oFace, 89, TRUE);
   SetLocalBoolean(oHeel, 89, TRUE);

   DelayCommand(0.5, ExecuteScript("k_ai_master", oFace, 1003));
   DelayCommand(0.5, ExecuteScript("k_ai_master", oHeel, 1003));
}

 

actually it did work for a minute. after spawning, they fight with force powers for a little while, but eventually they end up just swinging at each other nonstop again. it is a great start though, thanks stoffe -mkb-!

 

(edit: i removed the SetLocalBoolean lines and i removed the DelayCommand lines from the script and recompiled. the spawning still works fine and they still fight just fine. also the continue to use the Jedi Support AI style always so that also solves my above comment)

 

though i do have another question. i am trying to understand how the right script works just as much as i am trying to get the right scripts. so, what does the SetLocalBoolean(oFace, 89, TRUE) line do? could you break down what this line means, please?

Link to comment
Share on other sites

ideally, i would like to be able to add and remove my new recruit to and from the party through conversation with him. i wish that when the PC speaks to him, the player could ask him to go wait aboard the Ebon Hawk, effectively removing him from the party, but having him be onboard whenever the PC goes abroad and available for conversation and rerecruitment. however i did not thing this is possible as it would require a script to run from the conversation that would both spawn the new recruit in the Ebon Hawk module while the conversation actually took place in one of the planets' modules, and guaranting he would be there whenever the PC goes aboard.

 

am i right in thing that this may not be possible or is that just because of my rookiness with scripting?

Link to comment
Share on other sites

ideally, i would like to be able to add and remove my new recruit to and from the party through conversation with him. i wish that when the PC speaks to him, the player could ask him to go wait aboard the Ebon Hawk, effectively removing him from the party, but having him be onboard whenever the PC goes abroad and available for conversation and rerecruitment. however i did not thing this is possible as it would require a script to run from the conversation that would both spawn the new recruit in the Ebon Hawk module while the conversation actually took place in one of the planets' modules, and guaranting he would be there whenever the PC goes aboard.

 

am i right in thing that this may not be possible or is that just because of my rookiness with scripting?

 

I don't think you have to run a scipt to spawn the NPC back on the EH when you 'dismiss' them. Rather, perhaps you would have a script that runs on entering the EH module that checks if you have the (an) NPC available *and* that you 'sent' them there (via a global boolean set it the prior-mentioned dialogue). Just a thought...

Link to comment
Share on other sites

though i do have another question. i am trying to understand how the right script works just as much as i am trying to get the right scripts. so, what does the SetLocalBoolean(oFace, 89, TRUE) line do? could you break down what this line means, please?

 

object oFace = CreateObject(OBJECT_TYPE_CREATURE, "x", lLoc);

 

Spawns a new creature from the x.utc template at the location specified in the lLoc variable, and stores a reference to it in the oFace variable.

 

SetNPCAIStyle(oFace, NPC_AISTYLE_JEDI_SUPPORT);

 

Sets the Combat AI style of the NPC to Jedi Support, which makes it use force powers more often, and makes it use defensive/buffing force powers as well. (Default AI only uses offensive force powers, and only does so occasionally.)

 

SetLocalBoolean(oFace, 89, TRUE);

 

Enables the "Boss" Combat AI for the creature which makes them a bit more agressive in that they use force powers, both offensive and defensive, (or grenades for non-forceusers) a lot more often.

 

DelayCommand(0.5, ExecuteScript("k_ai_master", oFace, 1003));

 

Runs the OnCombatRound event script (with a 0.5 sec delay) for the creature referenced by oFace, which will initiate the Combat AI and make them look for nearby enemies to attack.

Link to comment
Share on other sites

  • 2 weeks later...

Simbacca

 

I haven't tried this so no gurantees.

 

I think you have to use the creature events for the two fighting critters, see http://www.lucasforums.com/showthread.php?t=143452. You'll have to set it so when they detect your PC, the script attached to the event makes them neutral and tells them to stop fighting. Might get some ideas for how to do that here, http://www.lucasforums.com/showthread.php?t=126615. You'll need to use the on userdefined event and in the onspawn event uncomment either on perceive or on heartbeat. If you use onperceive than you will probably have to force them to stop fighting as soon as they notice your PC. If you use on heartbeat, you could set it to check the distance of your PC and keep them fighting until your PC closes to a certain distance.

 

Good luck.

Link to comment
Share on other sites

whoa, this seems like a lot of learning and a lot of work.

 

thanks for the tip clydeski, i will try to figure this out.

 

in the mean time, if anyone has an example for this or can walk me through it, i would greatly appreciate it. i have been working on this mod far too long.

Link to comment
Share on other sites

ok well for my first attempt all i tried to do was get them to stop fighting when the PC approaches and their factions to change to neutral. this attempt has been unsuccessful. here is what i did:

 

first i extracted k_def_spawn01.nss, then i removed the slashes from this line:

GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_PERCEPTION);

 

then i extracted k_def_userdef01.nss, and added the green below:

 

#include "k_inc_generic"
#include "k_inc_debug"
#include "k_inc_utility"
void main()
{
   int nUser = GetUserDefinedEventNumber();

   if(nUser == 1001) //HEARTBEAT
   {

   }
   else if(nUser == 1002) // PERCEIVE
   {
      [color=lime]object oCreature = GetLastPerceived();
      if (GetLastPerceptionSeen() && GetIsPC(oCreature))
      {
         object oFace=GetObjectByTag("n_face");
         object oHeel=GetObjectByTag("n_heel");
         ChangeToStandardFaction(oFace, STANDARD_FACTION_NEUTRAL);
         ChangeToStandardFaction(oHeel, STANDARD_FACTION_NEUTRAL);
      }[/color]
   }
   else if(nUser == 1003) // END OF COMBAT
   {

   }
   else if(nUser == 1004) // ON DIALOGUE
   {

   }
   else if(nUser == 1005) // ATTACKED
   {

   }
   else if(nUser == 1006) // DAMAGED
   {

   }
   else if(nUser == 1007) // DEATH
   {

   }
   else if(nUser == 1008) // DISTURBED
   {

   }
   else if(nUser == 1009) // BLOCKED
   {

   }
   else if(nUser == 1010) // SPELL CAST AT
   {

   }
   else if(nUser == 1011) //DIALOGUE END
   {

   }
   else if(nUser == HOSTILE_RETREAT)
   {
       UT_ReturnToBase();
   }
}

 

i then renamed them k_def_spawn33.nss and k_def_userdef33.nss respectively. i compiled them, with the include scripts. i changed the utc file of one of the battling NPCs, "Face's", and then put everything in the override.

 

they spawn as usual, they fight as usual, and when i walk right between them, they still ignore me and continue fighting. what am i doing wrong?

Link to comment
Share on other sites

ok well for my first attempt all i tried to do was get them to stop fighting when the PC approaches and their factions to change to neutral. this attempt has been unsuccessful. here is what i did:

(snip)

i then renamed them k_def_spawn33.nss and k_def_userdef33.nss respectively. i compiled them, with the include scripts. i changed the utc file of one of the battling NPCs, "Face's", and then put everything in the override.

 

they spawn as usual, they fight as usual, and when i walk right between them, they still ignore me and continue fighting. what am i doing wrong?

 

 

In addition to changing factions, try make them call the SurrenderToEnemies() function and call the CancelCombat() function for them as well as ClearAllActions(). That should definitely make them stop fighting if the script is run at all.

 

You may also want to use GetIsPartyLeader() instead of GetIsPC() in the check to make sure they stop fighting as soon as they perceive the character the player is currently controlling.

 

Also, check the perception range of the NPCs set in the UTC files. This determines at which distance they will spot you and stop fighting.

 

Finally, when you are testing this, make sure the NPCs aren't already spawned in a savegame from before you altered their AI scripts, or they will not use your new scripts. Characters already present in the game world in a savegame won't reflect such changes made to their UTC templates.

Link to comment
Share on other sites

stoffe, thanks for the reply but it is still not working.

 

first off, i went and changed the script to this:

 

else if(nUser == 1002) // PERCEIVE
   {
      object oCreature = GetLastPerceived();
      if (GetLastPerceptionSeen() && GetIsPartyLeader(oCreature))
      {
         SurrenderToEnemies();
         CancelCombat();
         ClearAllActions();
         object oFace=GetObjectByTag("n_face");
         object oHeel=GetObjectByTag("n_heel");
         ChangeToStandardFaction(oFace, STANDARD_FACTION_NEUTRAL);
         ChangeToStandardFaction(oHeel, STANDARD_FACTION_NEUTRAL);
      }
   }

 

this script would not even compile, i received two errors. the first error was Undeclared Identifier "GetIsPartyLeader". the second error was Required Argument Missing In Call To "CancelCombat". because of my greenness to scripting i don't really know what these errors mean.

 

so i went and changed the script to this:

 

   else if(nUser == 1002) // PERCEIVE
   {
      object oCreature = GetLastPerceived();
      if(GetIsObjectValid(oCreature))
      {
         if (GetLastPerceptionSeen() && GetIsPC(oCreature))
         {
            SurrenderToEnemies();
            ClearAllActions();
            object oYoda=GetObjectByTag("x_boda");
            object oZoka=GetObjectByTag("x_zoka");
            ChangeToStandardFaction(oYoda, STANDARD_FACTION_NEUTRAL);
            ChangeToStandardFaction(oZoka, STANDARD_FACTION_NEUTRAL);
         }
      }
   }

 

that ObjectValid was an idea from http://www.nwnlexicon.com/, which does not help as you will see.

 

this one compiled fine. i made this script both Face's and Heel's OnUserDefine script, as well as the unslashed k_def_spawn10.ncs i made. i also made sure that both of their Perception Ranges were set to Long, and they both already were. however, there is still no change. even if i walk right in between the two of them, they continue their endless battle.

 

i don't understand this. these two characters are not already spawned in the game save. when i load up the save, my PC is aboard the Ebon Hawk. just to use for testing this mod, i have set things up this way: i walk over to Mission quarters, speak to hear, select "Nothing, Nevermind." which runs the NPCs' spawn script, Face and Heel spawn in the cargo hold, i walk all the way over to the cargo hold, i see them fighting, i walk up to them and even between them, they continue fighting, ignoring me.

 

i hate to be a pain, but i am going to need more help. looks like this will be my scripting WIP and education thread :p

Link to comment
Share on other sites

...really a continuation from the last post, here is yet a thrid way i have now tried this and still does not work:

 

   else if(nUser == 1002) // PERCEIVE
   {
      object oCreature = GetLastPerceived();
      if(GetIsObjectValid(oCreature))
      {
         if (GetLastPerceptionSeen() && GetIsPC(oCreature))
         {
            CancelCombat (OBJECT_SELF);
            ClearAllActions();
            ChangeToStandardFaction(OBJECT_SELF, 5);
         }
      }
   }

 

what has been wrong with these 3 ways i have tried?

Link to comment
Share on other sites

ok after the frustration of the above three attempts not working, i decided to scrap the scripts and try a new approach. this time i un-\\ GN_SetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT); and changed my user defined script to this:

void main()
{
   int nUser = GetUserDefinedEventNumber();

   if(nUser == 1001) //HEARTBEAT
   {
      object oPC = GetFirstPC();
      if(GetDistanceBetween(oPC, OBJECT_SELF) <= 2.0)
      {
         CancelCombat(OBJECT_SELF);
         ClearAllActions();
         ChangeToStandardFaction(OBJECT_SELF, 5);
      }
   }
   else if(nUser == 1002) // PERCEIVE
   {

   }

 

SUCCESS, finally!

now on to the next scripting challenge. to see what i want to do, lets take a look at this earlier post:

 

ideally, i would like to be able to add and remove my new recruit to and from the party through conversation with him. i wish that when the PC speaks to him, the player could ask him to go wait aboard the Ebon Hawk, effectively removing him from the party, but having him be onboard whenever the PC goes abroad and available for conversation and rerecruitment. however i did not thing this is possible as it would require a script to run from the conversation that would both spawn the new recruit in the Ebon Hawk module while the conversation actually took place in one of the planets' modules, and guaranting he would be there whenever the PC goes aboard.

 

am i right in thing that this may not be possible or is that just because of my rookiness with scripting?

 

I don't think you have to run a scipt to spawn the NPC back on the EH when you 'dismiss' them. Rather, perhaps you would have a script that runs on entering the EH module that checks if you have the (an) NPC available *and* that you 'sent' them there (via a global boolean set it the prior-mentioned dialogue). Just a thought...

 

anyone know how i would get started scripting this?

Link to comment
Share on other sites

now on to the next scripting challenge. to see what i want to do, lets take a look at this earlier post:

 

(Dismiss an NPC back to the Ebon Hawk after removing them from the party)

 

anyone know how i would get started scripting this?

 

Hmm, I am not sure I understand correctly what you want to do. Do you want to remove the NPC from the active 3-person party, or from the whole party entirely when you dismiss them back to the Ebon Hawk?

 

If it's the latter (remove them from the party table), then it's impossible to do in KotOR1, and will require you to use the PUP-table as a workaround in K2:TSL.

 

You can only move NPCs in the Party Table (or in K2:TSLs case, the PUP table) between modules. All other NPCs are stuck in the module they are in. All instances where an NPC is seemingly moving from one module to another is done by destroying the NPC in the first module and then spawning a new instance of it in the other. This, of course, won't really work to do with party members since they'd lose all their leveled-up levels and items they've been equipped with (as well as any locals set on them to keep track of their game state).

 

Thus, the only way to get this to work in KotOR1 (which I'm guessing you are modding) would be to make sure the player only is able to switch this party member in or out while on board the Ebon Hawk.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...