Aller au contenu

Photo

SUCCESS! - Adding new classes and strings!


  • Veuillez vous connecter pour répondre
44 réponses à ce sujet

#26
Poubo

Poubo
  • Members
  • 145 messages
looking great so far! i am rather impressed, now the origin story behind this would be rather awesome to see aswell.

#27
jo_cool69

jo_cool69
  • Members
  • 76 messages

Reynen Starfyre wrote...

YES I've figured out how to completely do classes and skills now! WOHOO
MAN it is COMPLICATED!!! It took two days to do this with all the code I had to change!


From what you have learned so far do you think the game mechanic can be changed enough to do something like not need weapons or have hand type weapons for a Monk class.  I have a lot of stuff written up already for a Monk and I don't just want to reskin a fighter without weapon slots and call it a Monk.  I actually want to work in the fist weapons or at least the fist and foot damage with nothing there (because I realize I'd have to create the 2da files for the new items).

Seems like calling something another class with a combination of spells/skills/talents/subclasses would be more doable (although still time consuming) than creating another one that doesn't even work the same way.

Thanks for your insight.

later

#28
Reynen Starfyre

Reynen Starfyre
  • Members
  • 52 messages
I've already got a monk class going in.  So to answer all your monk questions
OH YEAH.    CAAAAAAA CHAAA!!  WWWHHHAAAAAA!

:)

#29
Kunikos

Kunikos
  • Members
  • 97 messages
* makes some bruce lee noises *

#30
jo_cool69

jo_cool69
  • Members
  • 76 messages

Kunikos wrote...

* makes some bruce lee noises *


I think that just happened above you!  ;-)

#31
sajahVarel

sajahVarel
  • Members
  • 160 messages
By the way in the ABI_base, the wiki says there are column used for conditions (like abilities working only with certain weapon types etc...), I found the columns "condition_mode", "condition_group" and "condition".

The "mode" is for restricting the talent to a substained ability (like final blow only available while berserk is on), the "group" is to auto desactivate abilities when another get activated(like the shield stances or bard songs), and "condition" seems to restrict the ability to a certain weapon type or magic state,I figured out 128 is two handers, 64 is dualwield, 17 for melee weapons, 4 for ranged, 3 for shield + weapon.

I thought there would be a 2DA or a include file with the complete list, cause I want to add a row with a 1H weapon and empty off hand (to make a fencer ability group for the rogue), and since there seems to be a way to properly make weapon restrictions with the 2DA, I didn't want to overload the scripts with further (useless) checks, but I didn't find it and unfortunately it is one of these few variables who are not described in the wiki >.> (I checked the BITEM_base as well but no luck this far).

#32
eiham

eiham
  • Members
  • 38 messages
My guess is they are binary flags.



1 is either sword or shield

2 is either sword or shield

4 is ranged weapon

8 ???

16 maybe daggers?

32 ???

64 dual wielding

128 two hander



and to combine them you add them. Example, sword and shield are 3 (1+2) and sword/daggers are 17. This is just a guess and I have no way to prove/check this. There's got to be a list of constants somewhere.

#33
sajahVarel

sajahVarel
  • Members
  • 160 messages
This is what I thought first since critical stike (2H) is 129 (128+1 but why a 1 on a 2H skill Oo), but there are actually odd values in the process, 512 are mages consumables (like lyrium potion), 256 are the dog consumables, every monster grab is 32 (like the one the dragon uses to eat you), and the oddest of all is the 16 which is related to the blood magic spells (blood sacrifice, wound and control, the first has no requierement). 1 may be melee cause berserk and deadly strike use it, but duelist and berserker active skills are 17 (so 16+1 ? but then what is that 16 ? modal ability ? but the "conditions_mode" does that job too, this is why I said it's an odd structure...).

Modifié par sajahVarel, 24 novembre 2009 - 11:10 .


#34
eiham

eiham
  • Members
  • 38 messages
it is odd. Maybe we can poke a dev into giving us some insight here.

#35
eiham

eiham
  • Members
  • 38 messages
AHAH!

Don't know if this ended up in the engine, as per the quote, but it gives us SOME insight.

/**
* @brief Determine whether or not all conditions for the current talent are met
*
* This is temporary, it will go into the engine at some point
* Check the use conditions for the ability, e.g. melee only
* Later this should be
* done mostly in the UI (e.g. don't even allow to use it)
* 0   None
* 1   Melee
* 2   Shield
* 4   Ranged
* 8   Behind Target
* 16  Mode active
*
*
* @author Georg
*/
int Ability_CheckUseConditions(object oCaster, object oTarget, int nAbility, object oItem = OBJECT_INVALID)
{

    string sItemTag = IsObjectValid(oItem)?GetTag(oItem):"";
    int nAbilityType = GetAbilityType(nAbility);

    int nCondition = GetM2DAInt(TABLE_ABILITIES_SPELLS, "conditions", nAbility);
    int bRet = TRUE;

    float fCooldown = GetRemainingCooldown(oCaster, nAbility,sItemTag );
    if (fCooldown>0.0f)
    {
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY, "Ability_CheckUseConditions", "Trying to execute ability with cooldown " +ToString(fCooldown) + " remaining ability which is already active. FALSE.");
        #endif
        return FALSE;
    }
    else

    // If nAbility is modal and active already - do nothing
    if(IsModalAbilityActive(oCaster, nAbility))
    {
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY, "Ability_CheckUseConditions", "Trying to execute modal ability which is already active. FALSE.");
        #endif
        return FALSE;
    }


    // -------------------------------------------------------------------------
    // No conditions? bail right here
    // -------------------------------------------------------------------------
    if (nCondition == 0)
    {
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions","TRUE (no condition)");
        #endif
        return TRUE;
    }

    // -------------------------------------------------------------------------
    // CONDITION_MELEE_WEAPON - Caster needs a melee weapon in main hand
    // -------------------------------------------------------------------------
    if ((nCondition & 1) == 1)
    {

        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Melee: " + ((bRet)?"TRUE":"FALSE"));
        #endif
        bRet  = bRet &&   IsUsingMeleeWeapon(oCaster);

        if (!bRet)
        {
            return FALSE;
        }

    }

    // -------------------------------------------------------------------------
    // CONDITION_SHIELD - Caster needs a shield in the offhand
    // -------------------------------------------------------------------------
    if ((nCondition & 2) == 2)
    {
        bRet  = bRet && IsUsingShield(oCaster);
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Shield: "+ ((bRet)?"TRUE":"FALSE"));
        #endif

        if (!bRet)
        {
            return FALSE;
        }

    }

   // -------------------------------------------------------------------------
    // CONDITION_RANGED_WEAPON - Caster needs a ranged weapon in main hand
    // -------------------------------------------------------------------------
    if ((nCondition & 4) == 4)
    {
        bRet = bRet && IsUsingRangedWeapon(oCaster);
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Ranged: "+ ((bRet)?"TRUE":"FALSE"));
        #endif

        if (!bRet)
        {
            return FALSE;
        }

    }


    // -------------------------------------------------------------------------
    // CONDITION_BEHIND_TARGET - Caster needs to be located behind the target
    // -------------------------------------------------------------------------
    if ((nCondition & 8) == 8)
    {
        float fAngle = GetAngleBetweenObjects(oTarget, oCaster);

        bRet = bRet && (fAngle>=90.0f && fAngle <= 270.0f);
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Back: "+ ((bRet)?"TRUE":"FALSE"));
        #endif

        if (!bRet)
        {
            return FALSE;
        }

    }

    // -------------------------------------------------------------------------
    // 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;
        }

    }

    // -------------------------------------------------------------------------
    // CONDITION_TARGET_HUMANOID - Target is humanoid
    // -------------------------------------------------------------------------
    if ((nCondition & 32) == 32)
    {
        bRet = bRet && IsHumanoid(oTarget);

        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "IsHumanoid: "+ ((bRet)?"TRUE":"FALSE"));
        #endif

        if (!bRet)
        {
            return FALSE;
        }


    }

    // -------------------------------------------------------------------------
    // CONDITION_DUAL_WEAPONS
    // -------------------------------------------------------------------------
    if ((nCondition & 64) == 64)
    {
        bRet = bRet && GetWeaponStyle(oCaster) == WEAPONSTYLE_DUAL;
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "UsingDualWeapons: "+ ((bRet)?"TRUE":"FALSE"));
        #endif

        if (!bRet)
        {
            return FALSE;
        }
    }

    // -------------------------------------------------------------------------
    // CONDITION_DUAL_WEAPONS
    // -------------------------------------------------------------------------
    if ((nCondition & 128) == 128)
    {
        bRet = bRet && GetWeaponStyle(oCaster) == WEAPONSTYLE_TWOHANDED;
        #ifdef DEBUG
        Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "Using2HWeapon: "+ ((bRet)?"TRUE":"FALSE"));
        #endif
        if (!bRet)
        {
            return FALSE;
        }

    }


    #ifdef DEBUG
    Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", (bRet)?"TRUE":"FALSE" + " condition: " + IntToHexString(nCondition));
    #endif

    return bRet;

}



#36
Kunikos

Kunikos
  • Members
  • 97 messages
 That's nasty. They should be using constants in-line in their code not numbers. BAD PROGRAMMING! :sick:

#37
eiham

eiham
  • Members
  • 38 messages
Like the comment says, this may be a function that doesn't actually get used, but it shows us what the numbers mean, anyway.



1 - Character must have a melee weapon

2 - Character must have a shield

4 - Character must have a ranged weapon

8 - Backstab

16 - modal ability (id in condition_mode) must be active

32 - Target must be humanoid

64 - Dual weapons

128 - Two handed



and it appears if any ONE of the conditions or'ed together are false it returns false.

#38
ladydesire

ladydesire
  • Members
  • 1 928 messages
Kunikos, they are reading a value from the abilities 2da file using GetM2DAInt(), so they need to have specific values there instead of having to convert them from a constant to an integer; in a sense, the numbers are the constant.



eiham, what file is that in? I'd like to take a look at it myself.

#39
eiham

eiham
  • Members
  • 38 messages
ability_h.nss

#40
Kunikos

Kunikos
  • Members
  • 97 messages
No, you set it up like this:



Original code:

if ((nCondition & 128) == 128)



New code:

#define CONDITION_DUAL_WEAPONS 128

if((nCondition & CONDITION_DUAL_WEAPONS) == CONDITION_DUAL_WEAPONS)



done.

#41
sajahVarel

sajahVarel
  • Members
  • 160 messages
good news, If that works, adding new fighting styles shouldn't be that hard (skill code put aside)... but they should have put some #define or at least a 2DA to list all the numbers used by the game, cause if someone carelessly pick an already reserved number (I didn't see anything past 512 though, and that one shouldn't be needed since the lyrium items are class restricted from another script), there will be some odd stuff in his module...

Edit : after some test, the "conditions" var, doesn't seems to work properly, while the base numbers are working perfectly (I tried with 128 and 64, and they both locked the skills when the conditions were not met), my new test in the script is not, I added a 4096 for an empty off hand check and the script doesn't seems to be used...

    // -------------------------------------------------------------------------
    // CONDITION_FENCING
    // -------------------------------------------------------------------------
    if ((nCondition & 4096) == 4096)
    {
       bRet = bRet && IsUsingMeleeWeapon(oCaster) && GetWeaponStyle(oCaster) ==WEAPONSTYLE_SINGLE && !(IsUsingShield(oCaster)); 
       #ifdef DEBUG
       Log_Trace(LOG_CHANNEL_COMBAT_ABILITY,"CheckUseConditions", "UsingFencingStyle: "+ ((bRet)?"TRUE":"FALSE"));
       #endif
       if (!bRet)
       {
            return FALSE;
       }
    }

My test seems right (a melee weapon and a clean offhand), so I think the script got eventualy moved to the UI engine -_-".

well whatever, at worst case I'll change the abilities so that they do nothing if the condition is not met... poor gameplay but better than nothing XD. 

Modifié par sajahVarel, 25 novembre 2009 - 06:57 .


#42
PendragonV

PendragonV
  • Members
  • 91 messages
Lol was also thinking about that too, a monk class with magical powers plus staff combat would rock.

#43
PendragonV

PendragonV
  • Members
  • 91 messages
Make sure to have classes set in packages to pick and choose them.
Also the cleric should be restricted to maces and hammers etc.:happy:

#44
PendragonV

PendragonV
  • Members
  • 91 messages
Would you add mace only weapons then as restriction?

#45
sajahVarel

sajahVarel
  • Members
  • 160 messages
Adding custom restrictions are a bit of work actually, since the skill tests are now located in the engine (the restriction script in ability_h is actually useless, not even called by the module), so the best you can do with a regular script is to force no-action when you click on the skill (but I feel it pretty ugly since the guy can smash-click the skill but nothing happens next XD), so I got an other idea, and I'm working on polyvalent skills, like "does normal damage. If you are using X weapon it will add Y effect", since you can pretty much test anything of an object.

Modifié par sajahVarel, 08 décembre 2009 - 02:56 .