Jump to content

Need help with conditions in abi_base.gda


linus04

Recommended Posts

Hey guys,

 

I need a little help with abi_base.gda.

 

There is a column for conditions that must be met for spell/talent to be available for use. For example, 128 for 2h weapon equipped, 3 for 1h+shield, 16 for specific modal to be active etc. I'm trying to create a new condition, one that requires a specific modal to NOT be activated, but I can't get it to work.

 

I found out that these conditions are specified in 'ability_h.nss', but when I try to add a new condition number or edit one that is already there, it doesn't work. I got an error in the toolset when I tried to export the script:

 

"script must contain either a main or startingconditional"

 

And even when I managed to export it, it had no effect. Is there something I am doing wrong? Is there something else I need to do? Any help would be appreciated.

Link to comment
Share on other sites

Based on what you've said, I'm going to assume you're trying to edit the function Ability_CheckUseConditions in ability_h.nss to add a condition for modal ability NOT active.

 

Assuming you've done that correctly and the code is all well and good...

 

this message: "script must contain either a main or startingconditional" generally just tells you that the toolset didn't detect anything wrong with your code but also did not compile it into an executable.

 

Files with _h at the end of the name are aka "header" files, aka "include" files. They don't create executables by themselves, but are included in other executables when they are compiled.

 

In order for the code you've changed to take effect, the other files that use that header file need to be re-compiled. If you right-click on the name of the file and select properties, you'll see "References" (other files included by this file) and "Referenced By" (other files that include this file) tabs - and there are usually quite a few other files that include these _h files. They'll need to be recompiled. I would suggest "export with dependent resources".

Link to comment
Share on other sites

Thanks for advices guys, I tried to get it working, but still had no success... What I'm trying to do in the end, is that with Combat Magic active you can't use primal spells.
I edited this part from "ability_h.nss", just to see if it works:
    // -------------------------------------------------------------------------
    // CONDITION_ACTIVE_MODAL_ABILITY - A specific modal ability needs to be active
    // -------------------------------------------------------------------------
    if ((nCondition & 16) == 16)
    {
        int nModalAbility = GetM2DAInt(TABLE_ABILITIES_TALENTS,"condition_mode",nAbility);
        if (nModalAbility != 0)
        {
            bRet = bRet && IsModalAbilityActive(oCaster,nModalAbility);
            #ifdef DEBUG
            Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Mode Active: "+ ((bRet)?"TRUE":"FALSE"));
            #endif
        }

        if (!bRet)
        {
            return FALSE;
        }

    }

and changed it to:

    // -------------------------------------------------------------------------
    // CONDITION_ACTIVE_MODAL_ABILITY - A specific modal ability needs to be active
    // -------------------------------------------------------------------------
    if ((nCondition & 16) == 16)
    {
        int nModalAbility = GetM2DAInt(TABLE_ABILITIES_TALENTS,"condition_mode",nAbility);
        if (nModalAbility == 0)
        {
            bRet = bRet && IsModalAbilityActive(oCaster,nModalAbility);
            #ifdef DEBUG
            Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Mode Active: "+ ((bRet)?"TRUE":"FALSE"));
            #endif
        }

        if (!bRet)
        {
            return FALSE;
        }

    }

Then I recompiled all scripts that use ability_h (quite a few of them, do I really need to recompiled them all?):

 

abi_templates.nss
ability_core.nss
ability_summon_h.nss
ai_conditions_h.nss
ai_main_h_2.nss
aoe_effects_h.nss
bhn200tr_gilmore_entrance.nss
item_aoe_duration.nss
item_trap.nss
item_trap_lure.nss
module_core.nss
monster_aoe_duration.nss
monster_poison_spit.nss
monster_talent_aura.nss
monster_talent_brood.nss
monster_talent_dog_charge.nss
monster_talent_dog_grab.nss
monster_talent_dog_growl.nss
monster_talent_dragon.nss
monster_talent_grab.nss
monster_talent_large.nss
monster_talent_ogre.nss
monster_talent_overwhelm.nss
monster_talent_sylvan.nss
monster_talent_web.nss
ntb330cr_ghostly_elf.nss
null_spell.nss
orz540_gas_aoe.nss
orz540_lava_aoe.nss
player_core.nss
puzzle_aoe.nss
rules_core.nss
rules_h.nss
scattershot_singletarget.nss
showeffects.nss
skill_crafting.nss
skill_shapeshift.nss
skill_stealth.nss
skill_trap.nss
spell_aoe_duration.nss
spell_aw2_aoe.nss
spell_aw2_blizzard.nss
spell_aw2_chain.nss
spell_balance_aoe.nss
spell_balance_blizzard.nss
spell_blizzard.nss
spell_branka1.nss
spell_chainlightning.nss
spell_deathmagic.nss
spell_deathsyphon.nss
spell_shapeshift.nss
talent_aoe_duration.nss
talent_arrow_slaying.nss
talent_null.nss
talent_pet.nss
talent_scattershot.nss
test_petert.nss
Then I created abi_base_test.gda just for Flame Blast with condition 16 and condition_mode 17023 (Combat Magic), but it did not work. It's like if the game doesn't recognize my changes and I still need to activate Combat Magic to use Flame Blast (like original condition 16).
Link to comment
Share on other sites

The routine you are modifying - Ability_CheckUseConditions - is supposed to return TRUE if the conditions to use the talent/spell are met and FALSE if they are not.

 

I would also point out that there is a note at the top of it: "This is temporary, it will go into the engine at some point". It does not appear that ever happened, and this routine is still being used, but I think I would put a print statement in there just to be sure. To do that, create a plain text file named ECLog.ini in the bin_ship subdirectory of your game install directory, and make this the content of the file:

[LogTypes]
Script=1

Then temporarily insert a print statement at the top of that function so it will print to your log file, which will prove that the game is running the new code you have edited. The log file is in your Documents subdirectory, under BioWare > Dragon Age > Logs.

 

Here's a sample print statement:

PrintToLog("============== THE CODE I HAVE EDITED IS RUNNING! ===============");

Now let's look at your code changes and what they would do.

 

Firstly, I notice you're changing the behavior of condition value 16, which would break anything that already uses that value. Perhaps "break" isn't the correct word - it would use the new functionality you are creating, and if that is not your intent you might want to use a new value for the new functionality you intend to create here. Since the logic here uses bitwise operators (the single ampersand) and is using values that have a single bit set, I would suggest using 256, as it is the next value that fits that pattern.

 

The existing code looked for modal ability not zero:

if (nModalAbility != 0)

because it needed to check whether a modal ability was currently active to decide whether to allow a talent/spell to be used.

 

Your replacement code is looking for modal ability zero:

if (nModalAbility == 0)

even though you do want to check whether a modal ability is currently active to decide whether to allow a talent/spell to be used. So that's an error. The logic bracketed by that condition would never execute for anything that had the condition_mode in the database (gda) set to anything other than 0.

 

The existing code checked whether a modal ability was active

bRet = bRet && IsModalAbilityActive(oCaster,nModalAbility);

because that is what the check was for. It wanted to make sure a certain modal ability was active before it would allow a talent/spell to be used.

 

Your replacement code does the same thing, even though you want to make sure a modal ability is NOT active. So you'll need to flip it, and you can do that by inserting an exclamation point to "not" it:

bRet = bRet && !IsModalAbilityActive(oCaster,nModalAbility);

Hope I helped.

Link to comment
Share on other sites

Oh when you compile, all connected scripts export too (re-compiling can find errors in the corresponding scripts, I am not saying to not do this, it is helpful to make sure they work). You do not need the scripts/files you didn't change. I am constantly cleaning/deleting the extra files.

 

So it looks like condition 16 is when Blood Control is active. You probably should be creating your own condition number, instead of editing a pre-existing one.

  • conditions (looks like it is defined in the ability_h)
  • condition_mode (defined in the ai_abilities_cond.gda, if applicable)

And you want the reversed effect, so you'd have to switch the script around (at least in theory). I find in thinking and in execution can be tricky with scripting (at least for me LOL). But I'd think it be something like this:

    // -------------------------------------------------------------------------
    // CONDITION_ACTIVE_MODAL_ABILITY - A specific modal ability needs to be active
    // -------------------------------------------------------------------------
    if ((nCondition & 333) == 333) //try to use a number currently not used on ABI_Base.gda
    {
        int nModalAbility = GetM2DAInt(TABLE_ABILITIES_TALENTS,"condition_mode",nAbility);
        if (nModalAbility != 0) // != 0 probably means if you have a AI_abilities_cond.gda # defined (aka 17023) under "condition_mode", so do not remove the ! 
        {
            bRet = bRet && IsModalAbilityActive(oCaster,nModalAbility);
            #ifdef DEBUG
            Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Mode Active: "+ ((bRet)?"TRUE":"FALSE"));
            #endif
        }

        if (bRet) //!bRet should mean not this condition and bRet should mean this condition 
        {
            return FALSE;
        }

    }
Edited by HollownessDevoured
Link to comment
Share on other sites

Contrary to other advice you may receive, you really do need to re-compile any executables that use source code you've changed in order for your changes to take effect in the game. If you think about it, it should be self-evident.

 

Just as an fyi, this line in source code:

#include "filename"

 

 

is a compiler directive. It tells the pre-compiler to replace that line with the content of the named file before compiling the source code to create the executable.

 

Does that mean you have to re-compile every single file that includes ability_h?

 

Not necessarily, though it's usually considered good engineering practice to do so. But in practice, not every file that includes another file actually uses all of it. Some source files may be including ability_h only for its constants or to use some function(s) other than the specific one you're changing. What matters is that the files that include ability_h and *do* use the function you've changed get recompiled.

Link to comment
Share on other sites

I works now, thank you both so much! Strangely though, spells under this new condition are not "grey out" and unclickable like with other conditions, but when I try to cast them with Combat Magic active I get a "Can not use this ability." error. But that does not matter, I'm just happy it works :)


I did recompile every script that uses ability_h and then by trying to move them out one by one I found out that the only one important is "ability_core".

Link to comment
Share on other sites

I see that ability_core calls the function Ability_CheckUseConditions on line 213. That's why it was key to your changes showing up in game.

 

The other files that reference ability_h probably just use the constants or maybe some other function(s).

 

In any case, congrats on your success.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...