PDA

View Full Version : [K1] Scripting problem


Silveredge9
07-15-2008, 09:58 AM
I've been using the following script to make an NPC walk towards another NPC and then kill then using an attack animation. After which they walk to another NPC and perform the same function. But the problem is the NPC will only perform the CutsceneAttack function once, so if he uses it on the first guy, he doesn't use it on the second, and if I comment it out the first time around, he will use it on the second. I was wondering if someone could take a look at my script and see if there are any problems, or suggest some alterations? I have a feeling it may have something to do with combat rounds, but I'm not certain.

The script is fired from the onspawn slot in the utc of the "killer" NPC.

object oDie1 = GetObjectByTag("wst_die1b");
object oDie2 = GetObjectByTag("wst_die2b");
object oDie3 = GetObjectByTag("wst_die3b");
object oDie4 = GetObjectByTag("wst_die4b");
object oDie5 = GetObjectByTag("wst_die5b");

object oSelf = GetObjectByTag("wst_killer");

// Guy 1

AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionForceMoveToLocation(Loca tion(Vector(216.16,144.20,0.00), 0.0),FALSE));
AssignCommand(oSelf,ActionDoCommand(SetFacing(270. 0)));
AssignCommand(oSelf,ActionWait(3.0));
AssignCommand(oSelf,ActionDoCommand(SetCommandable (TRUE,OBJECT_SELF)));
AssignCommand(oSelf,CutsceneAttack(oDie1,87,1,10)) ;
AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionWait(0.5));
AssignCommand(oSelf,ActionDoCommand(ApplyEffectToO bject(DURATION_TYPE_INSTANT, EffectDeath(), GetObjectByTag("wst_die1"))));
AssignCommand(oSelf,ActionWait(3.0));

// Guy 2

AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionForceMoveToLocation(Loca tion(Vector(213.78,144.20,0.00), 0.0),FALSE));
AssignCommand(oSelf,ActionDoCommand(SetFacing(270. 0)));
AssignCommand(oSelf,ActionWait(3.0));
AssignCommand(oSelf,ActionDoCommand(SetCommandable (TRUE,OBJECT_SELF)));
AssignCommand(oSelf,CutsceneAttack(oDie2,87,1,10)) ;
AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionWait(0.5));
AssignCommand(oSelf,ActionDoCommand(ApplyEffectToO bject(DURATION_TYPE_INSTANT, EffectDeath(), GetObjectByTag("wst_die2"))));
AssignCommand(oSelf,ActionWait(3.0));

Thanks in advance for any help you can give. :)

glovemaster
07-15-2008, 04:09 PM
I suggest you try a ClearAllActions() after guy 1. That generally solves the problem ;)

stoffe
07-15-2008, 06:23 PM
I was wondering if someone could take a look at my script and see if there are any problems, or suggest some alterations? I have a feeling it may have something to do with combat rounds, but I'm not certain.

Try this variant of your script and see if it makes any difference:


void ST_MoveAndAttack(object oTarget, location lLoc, float fFace);


void main() {
object oDie1 = GetObjectByTag("wst_die1");
object oDie2 = GetObjectByTag("wst_die2");
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack(oDie1, Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack(oDie2, Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(object oTarget, location lLoc, float fFace) {
ActionDoCommand(SetCommandable(TRUE));
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
CutsceneAttack(oTarget, 87, 1, 10);
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), oTarget));
ActionWait(3.0);
ActionDoCommand( CancelCombat(OBJECT_SELF) );
}

Silveredge9
07-15-2008, 07:04 PM
Try this variant of your script and see if it makes any difference:


void ST_MoveAndAttack(object oTarget, location lLoc, float fFace);


void main() {
object oDie1 = GetObjectByTag("wst_die1");
object oDie2 = GetObjectByTag("wst_die2");
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack(oDie1, Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack(oDie2, Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(object oTarget, location lLoc, float fFace) {
ActionDoCommand(SetCommandable(TRUE));
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
CutsceneAttack(oTarget, 87, 1, 10);
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), oTarget));
ActionWait(3.0);
ActionDoCommand( CancelCombat(OBJECT_SELF) );
}


You could be on the right track, but I'm having some difficulty applying to to the situation.

#include "k_inc_generic"
#include "k_inc_debug"
void main()
{
object oDie1 = GetObjectByTag("wst_die1b");
object oDie2 = GetObjectByTag("wst_die2b");
object oDie3 = GetObjectByTag("wst_die3b");
object oDie4 = GetObjectByTag("wst_die4b");
object oDie5 = GetObjectByTag("wst_die5b");

object oSelf = GetObjectByTag("wst_killer");

// Guy 1

AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionForceMoveToLocation(Loca tion(Vector(216.16,144.20,0.00), 0.0),FALSE));
AssignCommand(oSelf,ActionDoCommand(SetFacing(270. 0)));
AssignCommand(oSelf,ActionWait(3.0));
AssignCommand(oSelf,ActionDoCommand(SetCommandable (TRUE,OBJECT_SELF)));
AssignCommand(oSelf,CutsceneAttack(oDie1,87,1,10)) ;
AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionWait(0.5));
AssignCommand(oSelf,ActionDoCommand(ApplyEffectToO bject(DURATION_TYPE_INSTANT, EffectDeath(), GetObjectByTag("wst_die1"))));
AssignCommand(oSelf,ActionWait(3.0));

// Guy 2

AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionForceMoveToLocation(Loca tion(Vector(213.78,144.20,0.00), 0.0),FALSE));
AssignCommand(oSelf,ActionDoCommand(SetFacing(270. 0)));
AssignCommand(oSelf,ActionWait(3.0));
AssignCommand(oSelf,ActionDoCommand(SetCommandable (TRUE,OBJECT_SELF)));
AssignCommand(oSelf,CutsceneAttack(oDie2,87,1,10)) ;
AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionWait(0.5));
AssignCommand(oSelf,ActionDoCommand(ApplyEffectToO bject(DURATION_TYPE_INSTANT, EffectDeath(), GetObjectByTag("wst_die2"))));
AssignCommand(oSelf,ActionWait(3.0));

// Guy 3

AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionForceMoveToLocation(Loca tion(Vector(211.5,144.20,0.00), 0.0),FALSE));
AssignCommand(oSelf,ActionDoCommand(SetFacing(270. 0)));
AssignCommand(oSelf,ActionWait(3.0));
AssignCommand(oSelf,ActionDoCommand(SetCommandable (TRUE,OBJECT_SELF)));
AssignCommand(oSelf,CutsceneAttack(oDie3,87,1,10)) ;
AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionWait(0.5));
AssignCommand(oSelf,ActionDoCommand(ApplyEffectToO bject(DURATION_TYPE_INSTANT, EffectDeath(), GetObjectByTag("wst_die3"))));
AssignCommand(oSelf,ActionWait(3.0));

// Guy 4

AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionForceMoveToLocation(Loca tion(Vector(209.22,144.20,0.00), 0.0),FALSE));
AssignCommand(oSelf,ActionDoCommand(SetFacing(270. 0)));
AssignCommand(oSelf,ActionWait(3.0));
AssignCommand(oSelf,ActionDoCommand(SetCommandable (TRUE,OBJECT_SELF)));
AssignCommand(oSelf,CutsceneAttack(oDie4,87,1,10)) ;
AssignCommand(oSelf,ActionDoCommand(SetCommandable (FALSE,OBJECT_SELF)));
AssignCommand(oSelf,ActionWait(0.5));
AssignCommand(oSelf,ActionDoCommand(ApplyEffectToO bject(DURATION_TYPE_INSTANT, EffectDeath(), GetObjectByTag("wst_die4"))));
AssignCommand(oSelf,ActionWait(3.0));

}

The above is the full script I've been using, there are 4 guys that the "killer" NPC walks towards and attacks. The "wst_dieNUMBER" creatures in the EffectDeath functions are separate entities altogether from the wst_dieNUMBERb things that are attacked. They are invisible placeables, and are used because if I script the Killer to attack the actual Creature NPC's with the CutsceneAttackFunction, it doesn't work, so I've scripted the killer to attack invisible placeables that are placed in the same location as the Creature NPC's, which works.

I'm wondering if you could rework your script based on my script above?

glovemaster
07-16-2008, 02:27 AM
That shouldn't be too much of a problem, you can just add at the end of Stoffe's main()
AssignCommand(oSelf, ST_MoveAndAttack(oDie3, Location(Vector(211.5, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack(oDie4, Location(Vector(209.22, 144.20, 0.00), 0.0), 270.0));
You have an oDie5 but he doesn't die in your script, but if you wanted him to then you just need to add that line.

stoffe
07-16-2008, 07:43 AM
The "wst_dieNUMBER" creatures in the EffectDeath functions are separate entities altogether from the wst_dieNUMBERb things that are attacked. They are invisible placeables, and are used because if I script the Killer to attack the actual Creature NPC's with the CutsceneAttackFunction, it doesn't work, so I've scripted the killer to attack invisible placeables that are placed in the same location as the Creature NPC's, which works.

I'm wondering if you could rework your script based on my script above?

Oh, didn't notice that extra b in the tags. If you stick to that naming convention the following should hopefully work better :)


void ST_MoveAndAttack(string sTag, location lLoc, float fFace);


void main() {
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack("wst_die1", Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die2", Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(string sTag, location lLoc, float fFace) {
ActionDoCommand(SetCommandable(TRUE));
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
CutsceneAttack(GetObjectByTag(sTag + "b"), 87, 1, 10);
ActionDoCommand(SetCommandable(FALSE));
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), GetObjectByTag(sTag)));
ActionWait(3.0);
ActionDoCommand( CancelCombat(OBJECT_SELF) );
}


As for not getting CutsceneAttack to work if attacking the actual NPC, is the NPC hostile to the attacker? You can only attack someone who's hostile if I remember correctly, so if they aren't you could add a standard faction change to the script before issuing the attack action.

Silveredge9
07-16-2008, 08:44 AM
Oh, didn't notice that extra b in the tags. If you stick to that naming convention the following should hopefully work better :)


void ST_MoveAndAttack(string sTag, location lLoc, float fFace);


void main() {
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack("wst_die1", Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die2", Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(string sTag, location lLoc, float fFace) {
ActionDoCommand(SetCommandable(TRUE));
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
CutsceneAttack(GetObjectByTag(sTag + "b"), 87, 1, 10);
ActionDoCommand(SetCommandable(FALSE));
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), GetObjectByTag(sTag)));
ActionWait(3.0);
ActionDoCommand( CancelCombat(OBJECT_SELF) );
}


As for not getting CutsceneAttack to work if attacking the actual NPC, is the NPC hostile to the attacker? You can only attack someone who's hostile if I remember correctly, so if they aren't you could add a standard faction change to the script before issuing the attack action.

The script itself works fine, thanks. But it seems the original problem still remains.

This screenshot (http://img.photobucket.com/albums/v642/Silveredge9/swkotor2008-07-1519-25-05-28.jpg) is an actual screenshot of the NPC's that the script issues commands too. The problem is, the "killer" NPC can only ever use the CutsceneAttack once, and it doesn't matter which "wst_dieNUMBERb" it's used on. So for example, if the script you supplied is added to the game intact, the killer will move to the first guy, and use the CutsceneAttack without any problems. But when he moves to subsequent guys, he doesn't use the CutsceneAttack.

But if I comment out the Killers CutsceneAttack of the first "wst_dieNUMBERb", he will move to the next one in the line with the CutcceneAttack still activated, use it there, and then fail to use it on all other guys with the CutsceneAttack still commented in. That's why I believe it's a problem associated with combat rounds, that whenever the killer cutsceneattack's one of the guys, the combat round is somehow carried on to the next guy, which in turn prevents the cutsceneattack from firing their.

If I haven't explained the problem well enough, feel free to point it out and I'll try and explain it again. :)

Oh, and everything else in the script works perfectly, just the CutsceneAttack stuff I've mentioned.

Also, concerning your thoughts on attacking the actual NPC with cutscene attack, if I turned the NPC hostile to the killer, wouldn't they starting fighting using regular combat - Rather then continue to follow the scripted actions?

stoffe
07-16-2008, 09:28 AM
That's why I believe it's a problem associated with combat rounds, that whenever the killer cutsceneattack's one of the guys, the combat round is somehow carried on to the next guy, which in turn prevents the cutsceneattack from firing their.

The CancelCombat(OBJECT_SELF) function call should take the character out of combat mode so I don't think that would be the problem. You could try to disable the combat AI of both involved parties if you think it might be interfering with your scene. Like:

#include "k_inc_generic"

void ST_MoveAndAttack(string sTag, location lLoc, float fFace);


void main() {
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack("wst_die1", Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die2", Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(string sTag, location lLoc, float fFace) {
SetLocalBoolean(OBJECT_SELF, SW_FLAG_AI_OFF, TRUE);
SetCommandable(TRUE);
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
ActionDoCommand(CutsceneAttack(GetObjectByTag(sTag + "b"), 87, ATTACK_RESULT_AUTOMATIC_HIT, 10));
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), GetObjectByTag(sTag)));
ActionDoCommand( CancelCombat(OBJECT_SELF) );
ActionDoCommand( SetLocalBoolean(OBJECT_SELF, SW_FLAG_AI_OFF, FALSE) );
}



Also, have you checked that the Tag of the second NPC and placeable are correct, and that they are hostile towards the attacker?

Silveredge9
07-16-2008, 11:13 AM
The CancelCombat(OBJECT_SELF) function call should take the character out of combat mode so I don't think that would be the problem. You could try to disable the combat AI of both involved parties if you think it might be interfering with your scene. Like:

#include "k_inc_generic"

void ST_MoveAndAttack(string sTag, location lLoc, float fFace);


void main() {
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack("wst_die1", Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die2", Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(string sTag, location lLoc, float fFace) {
SetLocalBoolean(OBJECT_SELF, SW_FLAG_AI_OFF, TRUE);
SetCommandable(TRUE);
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
ActionDoCommand(CutsceneAttack(GetObjectByTag(sTag + "b"), 87, ATTACK_RESULT_AUTOMATIC_HIT, 10));
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), GetObjectByTag(sTag)));
ActionDoCommand( CancelCombat(OBJECT_SELF) );
ActionDoCommand( SetLocalBoolean(OBJECT_SELF, SW_FLAG_AI_OFF, FALSE) );
}



Also, have you checked that the Tag of the second NPC and placeable are correct, and that they are hostile towards the attacker?

The tags are correct, in fact the actual NPC isn't used in the CutsceneAttack stuff at all, just the placeable.

And I've used your script, but the CutsceneAttack function doesn't work at all now. :P

Below is the current script I'm using, which takes elements out of the script you posted, but still fires the CutsceneAttack function at least in the first occasion.


#include "k_inc_generic"

void ST_MoveAndAttack(string sTag, location lLoc, float fFace);


void main() {
object oSelf = GetObjectByTag("wst_killer");

AssignCommand(oSelf, ST_MoveAndAttack("wst_die1", Location(Vector(216.16, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die2", Location(Vector(213.78, 144.20, 0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die3", Location(Vector(211.5, 144.20,0.00), 0.0), 270.0));
AssignCommand(oSelf, ST_MoveAndAttack("wst_die4", Location(Vector(209.22, 144.20,0.00), 0.0), 270.0));
}



void ST_MoveAndAttack(string sTag, location lLoc, float fFace) {

object oSelf = GetObjectByTag("wst_killer");

SetLocalBoolean(GetObjectByTag(sTag + "b"), SW_FLAG_AI_OFF, TRUE);
SetLocalBoolean(oSelf, SW_FLAG_AI_OFF, TRUE);
ActionDoCommand(SetCommandable(TRUE));
ActionForceMoveToLocation(lLoc, FALSE);
ActionDoCommand(SetFacing(fFace));
ActionWait(3.0);
CutsceneAttack(GetObjectByTag(sTag + "b"), 87, 1, 10);
ActionDoCommand(DestroyObject(GetObjectByTag(sTag + "b")));
ActionDoCommand(SetCommandable(FALSE));
ActionWait(0.5);
ActionDoCommand(ApplyEffectToObject(DURATION_TYPE_ INSTANT, EffectDeath(), GetObjectByTag(sTag)));
ActionWait(3.0);
ActionDoCommand( CancelCombat(OBJECT_SELF) );
ActionDoCommand( ClearAllActions() );
SetLocalBoolean(GetObjectByTag(sTag + "b"), SW_FLAG_AI_OFF, FALSE);
ActionDoCommand( SetLocalBoolean(oSelf, SW_FLAG_AI_OFF, FALSE) );

}
I've added a DestroyObject function to get rid of the Placeable after it has been attacked, to remove any chances that it may be effecting the subsequent placeables when the Killer tries to attack them.

And the problem still exists, the "Killer" NPC is only able to perform the CutsceneAttack once, on whichever placeable it attacks first. Although, from testing It seems the CancelCombat function cancels the Killer NPC's queued actions if I remove or comment out the SetCommandable functions.

This is very confusing, I'm pretty much out of ideas. :P

Tiron
07-16-2008, 11:27 PM
well I've got two ideas...though I'm not sure if one of them would work, it's just an idea for the structure of it.

Have you tried breaking it into seperate scripts(or multiple calls to the same, smaller script) in sequence? I'm a little fuzzy on how you'd tie them together though...

The only other thing I can think of off the top of my head is...multiple killers. >P

Edit:
Oh, one more idea...
There's a cutscene in the lower city in kotor 1 where an NPC attacks(and kills) two different targets...but there's a 'cut' between them. The camera moves in such a way that the attacking NPC isn't visible anymore. What if they despawned the guy offscreen when the cut happened, then spawned in a new one to kill the second guy? Be a little tricky to pull off with four...

Edit2: Another thought. what if the problem isn't the attack commands...what if it's the TARGETING? Suppose the idiot NPC doesn't get the new victim targeted, and sits there trying to fire the attack at nothing?