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

Legacy_Mudeye

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


               Could you post the exact script you are using?
               
               

               
            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #16 on: September 30, 2010, 04:06:41 am »


               Here ya go.  This appears to work fine for physical attacks with equipped weapons (melee, ranged, or creature weapons). 

All the problems seem to occur in the "attack with magic" parts.  Associates do nothing if they are out of range of the spell or ability chosen by the script, until they are walked within range of the enemy, at which point they start casting.

#include "NW_I0_GENERIC"

// runs a function that returns an integer and discards the return value
void bchFunctionIgnoreInt(int FunctionThatReturnsInt){ }




void bchGetEm(object oAssociate, object oClicked, object oWielder, int bCast = FALSE){


    //--------------------------------------------------------------------------
    // This (setting associates to Stand Your Ground = No, Guard Me = No)
    //  seems to be necessary.  Without this, TalentSpellAttack and ActionAttack
    //  don't seem to work except randomly, occasionally.
    // Not sure if other settings would work as well.
    // Maybe they just need *something* set?

    SetAssociateState(NW_ASC_MODE_STAND_GROUND, FALSE);
    SetAssociateState(NW_ASC_MODE_DEFEND_MASTER, FALSE);
    //--------------------------------------------------------------------------

    if(bCast){  // this associate should attack with magic

        // make the associate hostile to the target (so they are more willing to attack?)
        //SetIsTemporaryEnemy(oClicked, oAssociate);

        // make the target hostile to the associate,
        //  so their spells will affect them,
        //  even if they start out neutral or friendly
        SetIsTemporaryEnemy(oAssociate, oClicked);

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

        // hopefully, this will work for all spell-like abilities as well as spells
        //  currently, it only seems to work when an enemy is within range of their spells
        AssignCommand(oAssociate, bchFunctionIgnoreInt(TalentSpellAttack(oClicked) ) );

    }else{

        // this works for equipped weapons (ranged or melee)
        AssignCommand(oAssociate, WrapperActionAttack(oClicked) );
    }
}





// Commands some or all associates to attack oClicked
// First five switches control which associates receive the command.
// bCast == TRUE causes a spell or magic ability attack,
// bCast == FALSE causes a physical attack.
void bchSicEm(object oWielder, object oClicked, int bHenchmen = FALSE,
                int bSummoned = FALSE, int bFamiliar = FALSE,
                int bAnimalCompanion = FALSE, int bDominated = FALSE, int bCast = FALSE){

    object oAssociate;

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

    if (bFamiliar){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_FAMILIAR, oWielder);
        if(GetIsObjectValid(oAssociate)){
            bchGetEm(oAssociate, oClicked, oWielder, bCast);
        }
    }

    if (bAnimalCompanion){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_ANIMALCOMPANION, oWielder);
        if(GetIsObjectValid(oAssociate)){
            bchGetEm(oAssociate, oClicked, oWielder, bCast);
        }
    }

    if (bSummoned){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_SUMMONED, oWielder);
        if(GetIsObjectValid(oAssociate)){
            bchGetEm(oAssociate, oClicked, oWielder, bCast);
        }
    }

    if (bDominated){
        oAssociate = GetAssociate(ASSOCIATE_TYPE_DOMINATED, oWielder);
        if(GetIsObjectValid(oAssociate)){
            bchGetEm(oAssociate, oClicked, oWielder, bCast);
        }
    }

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

        if (GetIsObjectValid(oAssociate)) {
            bchGetEm(oAssociate, oClicked, oWielder, bCast);

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


               
               

               


                     Modifié par BCH, 30 septembre 2010 - 03:22 .
                     
                  


            

Legacy_Mudeye

  • Full Member
  • ***
  • Posts: 238
  • Karma: +0/-0
Please help me script this interface trick
« Reply #17 on: September 30, 2010, 05:16:03 pm »


               You said:
      if(GetDistanceBetween(oAssociate, oClicked) > 19.0 ){
               AssignCommand(oAssociate, ClearAllActions() );
               AssignCommand(oAssociate, ActionMoveToObject(oClicked, FALSE, 19.0)  );
           }

           // hopefully, this will work for all spell-like abilities as well as spells
           //  currently, it only seems to work when an enemy is within range of their spells
           AssignCommand(oAssociate, bchFunctionIgnoreInt(TalentSpellAttack(oClicked) ) );


This line looks questionable to me:
AssignCommand(oAssociate, bchFunctionIgnoreInt(TalentSpellAttack(oClicked) ) );

I'm not sure that it captures the TalentSpellAttack(oClicked) call.  It might be trying to call TalentSpellAttack immediately and pass the result into  bchFunctionIgnoreInt which is then called later.  That would also explain why it only works if you are already within spell range.  If you are too far away, then the immediate call to TalentSpellAttack doesn't do anything since it actually happens before the move command.



How about trying these two things.
----------------------------
1) make a new function:
void MyCast( object target )
{
    SpeakString("Casting Spell");
    ActionCastSpellAtObject(SPELL_MAGIC_MISSILE, target, METAMAGIC_ANY, TRUE );
}

Replace the line:
AssignCommand(oAssociate, bchFunctionIgnoreInt(TalentSpellAttack(oClicked) ) );
with
AssignCommand(oAssociate, MyCast(oClicked) );

See if that runs.  Hopefully the speak and the spell will get cast.
--------------------------------------
2) If the first one works then make a new function:

#include "x0_i0_talent"

void MySpellAttack( object target )
{
   TalentSpellAttack(target);
}

Replace the line:
AssignCommand(oAssociate, bchFunctionIgnoreInt(TalentSpellAttack(oClicked) ) );
with
AssignCommand(oAssociate, MySpellAttack(oClicked) );
               
               

               


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


            

Legacy_BCH

  • Full Member
  • ***
  • Posts: 160
  • Karma: +0/-0
Please help me script this interface trick
« Reply #18 on: October 09, 2010, 05:25:09 am »


               Sorry for the delay... real life getting in the way.

Mudeye, I think you were right about that recommendation, and I think that I was not successfully putting TalentSpellAttack() into the associates action queues.

Unfortunately, it seems that there's a lot more to my problem.  The more I test, the more I think that my attempts are being thwarted by the associate AI that are already running, but I don't know how to properly hook into that AI to give the right commands.

Thanks for all your help, though.  I'll just have to keep reading through Bioware's code until I find out the proper way to do this.  There must be something I'm missing in DetermineCombatRound(), as that seems to be Bioware's go-to function for making attacks happen.