Author Topic: Please help me script this interface trick  (Read 683 times)

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« on: September 21, 2010, 10:51:36 am »


               When playing the solo game, I discovered that I could send my associates to attack a foe like so:

1. Start a melee attack on that foe from a distance, which starts me moving toward the foe.

2. Use a hotkey to order all associates to Guard Me, which starts them moving toward the foe also.

3. Click behind myself so I'm now running away from the foe.

Result: associates charge in to engage the foe for me while I use spells, engage another foe, or just plain run away.

Now, running a VPnP game, I want to create an item that will do the same thing - send associates to attack - when the item is activated and a foe is clicked on.

Unfortunately, I'm not quite sure what happens when the Guard Me command is issued through the interface.  I've looked in the Lexicon, and the best guess I've come up with is to use DetermineCombatRound().  However, using this line in a script sometimes works, often doesn't, and I can't quite figure out why:

AssignCommand(oAssociate, DetermineCombatRound(oClicked));

I'm stumped.  Ideally, I'd like the function to be able to let the standard AI decide how to attack, but when I start looking at functions like TalentMeleeAttack and TalentSpellAttack, I feel like I'm trying to rewrite DetermineCombatRound(), and I doubt that's the right thing to do.

Any ideas how I can do this?
               
               

               
            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #1 on: September 21, 2010, 11:07:02 am »


               Here's the script function, in case it helps:

void bchSicEm(object oWielder, object oClicked, int bHenchmen = FALSE, int bSummoned = FALSE, int bFamiliar = FALSE, int bAnimalCompanion = FALSE, int bDominated = FALSE){

    object oAssociate;

    string sMessage = GetName(oWielder) + " orders associates to attack " + GetName(oClicked);
    FloatingTextStringOnCreature(sMessage, oWielder);

    if (bFamiliar){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oWielder);
        AssignCommand(oAssociate, DetermineCombatRound(oClicked));
    }

    if (bAnimalCompanion){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oWielder);
        AssignCommand(oAssociate, DetermineCombatRound(oClicked));
    }

    if (bSummoned){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oWielder);
        AssignCommand(oAssociate, DetermineCombatRound(oClicked));
    }

    if (bDominated){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oWielder);
        AssignCommand(oAssociate, DetermineCombatRound(oClicked));
    }

    if (bHenchmen){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oWielder, 1);

        if (GetIsObjectValid(oAssociate)) {
            AssignCommand(oAssociate, DetermineCombatRound(oClicked));

            // if we have one hench, check for more
            int i;
            for (i = 2; i < 7; i++){
                oAssociate = GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oWielder, i);
                AssignCommand(oAssociate, DetermineCombatRound(oClicked));
            }
        }
    }
}
               
               

               


                     Modifié par BCH, 21 septembre 2010 - 10:07 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Please help me script this interface trick
« Reply #2 on: September 21, 2010, 12:39:36 pm »


               

BCH wrote...

Unfortunately, I'm not quite sure what happens when the Guard Me command is issued through the interface. 


When you give any of the voice commands, the only thing the PC does is shout the command.

From there it is up to the NPC/compaion to react.  That is handled by the copmaions OnConversation event and the listening patterns it is set up to listen for.

Sorry I dont have the time to give a better answer right now.

Hope that helps.
               
               

               
            

Legacy_Mudeye

  • Full Member
  • ***
  • Posts: 238
  • Karma: +0/-0
Please help me script this interface trick
« Reply #3 on: September 21, 2010, 04:55:16 pm »


               Here's something you might try:

Set all the henchmen to guard me when you're walking around.

In your script instead of:  AssignCommand(oAssociate, DetermineCombatRound(oClicked));

Put:

    AssignCommand(oAssociate,ClearAllActions());
    DelayCommand(1.0, AssignCommand(oAssociate,ActionAttack( oClicked )));

This tells the associates to attack the oClicked.  If they are already attacking then they will continue to do so.  If you want them to leave the current attack then replace the ClearAllActions line with:
AssignCommand(oAssociate,ClearAllActions(TRUE));
               
               

               
            

Legacy_Mudeye

  • Full Member
  • ***
  • Posts: 238
  • Karma: +0/-0
Please help me script this interface trick
« Reply #4 on: September 21, 2010, 05:04:44 pm »


               Another thing.  There seems to be an internal function to set the state of the henchmen to defend you.
#include "x0_i0_assoc"

SetAssociateState( NW_ASC_MODE_DEFEND_MASTER, TRUE );

So that would be:
AssignCommand( oAssociate, SetAssociateState( NW_ASC_MODE_DEFEND_MASTER, TRUE ));
               
               

               


                     Modifié par Mudeye, 21 septembre 2010 - 04:05 .
                     
                  


            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #5 on: September 21, 2010, 08:18:24 pm »


               Thanks!  I will try those things, and come crawling back here if I don't get them to work. ':unsure:'
               
               

               
            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #6 on: September 23, 2010, 02:18:57 am »


               Sorry, I need to ask for more help...

Lightfoot8 - I think I can figure out how to script a "Guard Me" shout, but that will not get me the whole effect I'm looking for.  With the Attack > Guard Me > Retreat interface trick I described, the end result is the same as saying "associates, attack that exact enemy."  That's what I can't figure out how to do.

Mudeye - Since I last posted, I've tried using ActionAttack() and WrapperActionAttack(), but those only seem to work for attacks with equipped weapons.  This is good, but it does not seem to include spells or spell-like abilities.  One of my test associates is a summoned fire beetle with Fire Bolt and Fire Stream, and it does not use these when commanded with ActionAttack or WrapperActionAttack.  However, it does use it normal combat, where it is picking it's own targets, so I know the AI is choosing those attacks somehow.

I've tried using variations on DetermineCombatRound() and ChooseTactics(), but they only work sporadically, for reasons I have not yet been able to puzzle out.  Anyone got any idea why those would not work in my script above?

My next step is adding script to decide whether the associate should use TalentSpellAttack() or something similar, but since I can't find extensive documentation on all these TalentBlahBlah combat functions, I fear I may end up on a long wild goose chase.

Again, thanks for any help anyone can offer!
               
               

               
            

Legacy_Mudeye

  • Full Member
  • ***
  • Posts: 238
  • Karma: +0/-0
Please help me script this interface trick
« Reply #7 on: September 23, 2010, 06:00:18 pm »


               Have you looked at the SetCombatCondition and SpecialTactics functions?

I believe this tells your associate to use ranged tactics:
SetCombatCondition( X0_COMBAT_FLAG_RANGED, TRUE, oAssociate );

This determines the tactics as set above to used on the target oClicked:
SpecialTactics( oClicked );

The combat conditions are:
  X0_COMBAT_FLAG_AMBUSHER
  X0_COMBAT_FLAG_COWARDLY
  X0_COMBAT_FLAG_DEFENSIVE
  X0_COMBAT_FLAG_RANGED

For simple Melee they are all set to false.
               
               

               


                     Modifié par Mudeye, 23 septembre 2010 - 05:01 .
                     
                  


            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #8 on: September 23, 2010, 11:11:12 pm »


               Mudeye, I've gotten that to work with ranged equipped weapons like bows, but not with spellcasting.  Getting spellcasting to work is my current problem.

(Sorry, not trying to be difficult!  :innocent: )

Since the last time I posted, I've seen very limited success using TalentSpellAttack().  Using that in the script, associates will attack with spells sometimes.  It appears that if they are out of range for the spell or spell-like ability that the function chooses, they do nothing.

I'm still trying to find the AI that tells associates "if you are out of range of that target, move into range and cast."  If there is such a thing.

I'm also still trying to puzzle out why DetermineCombatRound() and ChooseTactics() aren't working for me.
               
               

               
            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #9 on: September 24, 2010, 09:13:07 am »


               Okay, I think I've gotten a bit closer to understanding this problem... if anyone has an idea after reading this, please let me know!

After more testing, it appears that TalentSpellAttack() does not cause my associates to do anything... until I walk them within range of whatever spell was just chosen by the AI for them to cast.

I've consistently seen the following:
 - I order my two associates to TalentSpellAttack() while 30-40 meters from the target.
 - They do nothing.  (Actually, the sorcerer puts away his crossbow and draws his sickle, then does nothing.)
 - Then I wander closer to the target.
 - At a distance of about 20 meters, both associates start casting spells.  The sorcerer starts with Protection from Evil, then Sleep, then Fireball.  The fire beetle goes straight to alternating Fire Bolt and Fire Stream.

Then I added a few lines to the script, hoping to send the associates in on their own, like so:

        if(GetDistanceBetween(oAssociate, oClicked) > 19.0 ){
            AssignCommand(oAssociate, ActionMoveToObject(oClicked, FALSE, 19.0) );
        }

As a result of this new code... no change.  The associates do not seem to respond to the ActionMoveToObject function at all.

I've tried adding SetIsTemporaryEnemy() to the script to make the associates hate the target, and to make the target hate my associates.  The target responds by attacking!  My associates still stand there like idiots.

Any ideas?  It's almost like the associates are holding the TalentSpellAttack in their action queues, but aren't willing to leave my side.
               
               

               
            

Legacy_Mudeye

  • Full Member
  • ***
  • Posts: 238
  • Karma: +0/-0
Please help me script this interface trick
« Reply #10 on: September 27, 2010, 05:46:00 pm »


               Here's a couple of thoughts.



You might try looking at the perception range of your associates.  They might not be perceiving the enemy yet.



Does the location you tell them to move to conflict with the the distance they are supposed to stay from the PC?



You might want to put a clear actions before the move. If they have other stuff in their action queue it could prevent them from taking the action.
               
               

               
            

Legacy_Baragg

  • Sr. Member
  • ****
  • Posts: 496
  • Karma: +0/-0
Please help me script this interface trick
« Reply #11 on: September 28, 2010, 01:34:42 am »


               I have not opened this up and looked it over but doing so may help you better understand what you can do.



http://nwvault.ign.c....Detail&id=1600
               
               

               
            

Legacy_Baragg

  • Sr. Member
  • ****
  • Posts: 496
  • Karma: +0/-0
Please help me script this interface trick
« Reply #12 on: September 28, 2010, 01:39:39 am »


               Forget what I posted above, I opened that up and found that it is very involved.
               
               

               
            

Legacy_Baragg

  • Sr. Member
  • ****
  • Posts: 496
  • Karma: +0/-0
Please help me script this interface trick
« Reply #13 on: September 28, 2010, 01:42:08 am »


               I remember reading something about this on the old forums, I believe, but could be wrong, the idea grew up to be a series of if statements where it read out like:



if(the caster has XXXspell)

{

 cast it

}

if(the caster has XXXspell)

{

cast it

}



So on and so forth with buffs being the first, unless of course you are going to check the closeness of enemies and want to cast spells to freeze them in place first, then buff, then blast.
               
               

               
            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #14 on: September 29, 2010, 06:14:00 pm »


               

Mudeye wrote...

Here's a couple of thoughts.

You might try looking at the perception range of your associates.  They might not be perceiving the enemy yet.

Does the location you tell them to move to conflict with the the distance they are supposed to stay from the PC?

You might want to put a clear actions before the move. If they have other stuff in their action queue it could prevent them from taking the action.


I'm pretty sure the associates can see their targets... I haven't changed their perception ranges, and they do have good ranks in Spot and Listen.  In some cases, I've used enemies that started off Neutral rather than Hostile, so it was possible to walk my associates right past the target before ordering the attack.

Technically, yes, they would have to leave my side to attack the target, so that does conflict with their set following distances.  However, when they decide to attack on their own, they have no problems chasing after enemies.  They just don't respond to the ActionMoveToObject() function when I add it to the manual attack script.

I did try ClearAllActions() and ClearAllActions(TRUE) in the script.  Sorry, I should have specified that.  Still no success on my part.

Baragg wrote...
I remember reading something about this on the old forums, I believe,
but could be wrong, the idea grew up to be a series of if statements
where it read out like: [snip]


Yeah, that's basically how ChooseTactics() reads.  Unfortunately, I can't find the line or lines in ChooseTactics() that is keeping the associates from doing what I want them to do.

Thanks, though.  I appreciate the help.