简体   繁体   English

C ++检查枚举标志

[英]C++ checking enum flags

In one of my classes, I have an integer that stores a set of enum flags like so: 在我的一个类中,我有一个存储一组枚举标志的整数,如下所示:

enum AttackFlags
{
    Contact = 1,                        //Move connects with target
    Projectile = 2,                         //Attack is projectile based
    Unblockable = 4,                        //Attack can not be blocked
    UncounterableLv1 = 8,                   //Attack can't be countered except by extreme counter attack skills/status effects
    UncounterableLv2 = 16,                  //Attack can not be countered
    Flinches = 32,                          //Has a chance to stun the enemy, pushing back their next turn
    Unreflectable = 64,                     //Attack penetrates reflect. Only checked for Magic attacks
    IgnoreDefenderStatusEffects = 128,      //Ignores active status effects on the defender
    IgnoreAttackerStatusEffects = 256,      //Ignores active status effects on the attacker
    IgnoreDefenderAbilities = 512,          //Ignore the defenders abilities
    IgnoreAttackerAbilities = 1024,         //Ignore the attackers abilities
    IgnoreArmorRating = 2048,               //Ignore the defensive boosts of armor
    IgnoreWeaponRating = 4096,              //Ignore the attack boost from weapons
    HighCritical = 8192,                    //The move has an increased chance to crit
    CausesStatus = 16384,                   //Can the move cause status effects?
    Elemental = 32768,                      //Is the move elemental based?
    Unimplemented = 65536,                  //has the move been implemented yet?
    ModsTimer = 131072,                     //Does it have an effect on the target or users timer?
    Heals = 262144,                         //Does the move heal?
    SecondaryEffects = 524288,              //Attack has additional effects besides basic attack
    PhysicalAttackFlag = 1048576,           //Is the Class Physically based? I.E. blocked by Protect and Shield
    MagicAttackFlag = 2097152,              //Is the move Magically Based? I.E. is it affected by things like Shell
    MultiHit = 4194304,                     //Does it enxcapsulate more then 1 hit
    SingleUse = 8388608,                    //Attack can only be used once per battle
    DoesNotCauseDamage = 16777216
};

class Attack
{
   int AtkFlags; //Stores AttackFlags |'d together

}

I'd like to add a method to my Attack class with the following signature 我想使用以下签名为我的Attack类添加一个方法

bool HasAttackFlags(int flags);

flags would be numerous AttackFlags |'d together. 标志将是众多的AttackFlags |'d在一起。 If I only wanted to check against a single flag, I could just & AtkFlags and flags together, but because I have to check against multiple possible flags this won't work. 如果我只想检查一个标志,我可以和AtkFlags和标志一起,但因为我必须检查多个可能的标志,这将无法正常工作。 How can I properly check for multiple flags? 如何正确检查多个标志? I'd like to avoid passing a vector/set of flags to check against as simply |'ing a set of flags together is simpler then constructing a vector/set 我想避免传递一个矢量/一组标志进行检查,因为简单地将一组标志放在一起就更简单了然后构建一个矢量/集合

Thanks in advance 提前致谢

EDIT: 编辑:

To clarify what I mean, I might have the following 为了澄清我的意思,我可能会有以下内容

Attack atk;
atk.AtkFlags = Contact | Projectile | Heals | MagicAttackFlag;

Then later, I'd want to check the flags on atk like so: 然后,我想检查atk上的标志,如下所示:

bool res = atk.HasAttackFlags(Contact | Projectile);

res should be true and conversely res应该是真实的,反之亦然

bool res = atk.HasAttackFlags(Contact | Unreflectable);

should be false becase AtkFlags does not contain both Contact adn Unreflectable. 应该是假的,因为AtkFlags不包含联系人adn Unreflectable。

I am not sure I am following your question, because you seem to mention the obvious solution. 我不确定我是否关注你的问题,因为你似乎提到了明显的解决方案。 So what is wrong with this as a solution, obviously add whatever additional flags you wish: 所以作为解决方案有什么问题,显然添加你想要的任何其他标志:

bool HasAttackFlags(int flags) {
    return (flags&(contact|projectile))!=0;
}

EDIT: Oh... I think I just figured it out, do you want to check for the presence of 2 or more flags as a set? 编辑:哦......我想我刚想通了,你想检查是否存在2个或更多的标志作为一组? In which case you can simply modify the method to: 在这种情况下,您只需将方法修改为:

bool HasAttackFlags(int flags) {
    return (flags&(contact|projectile))==(contact|projectile);
}

This is my suggestion: 这是我的建议:

Note the usage of the enum definition to enable the machinery 请注意枚举定义的用法以启用机器

enum AttackFlags
{
    Contact                     = 1ul <<  0,  // Move connects with target
    Projectile                  = 1ul <<  1,  // Attack is projectile based
    Unblockable                 = 1ul <<  2,  // Attack can not be blocked
    UncounterableLv1            = 1ul <<  3,  // Attack can't be countered except by extreme counter attack skills/status effects
    UncounterableLv2            = 1ul <<  4,  // Attack can not be countered
    Flinches                    = 1ul <<  5,  // Has a chance to stun the enemy, pushing back their next turn
    Unreflectable               = 1ul <<  6,  // Attack penetrates reflect. Only checked for Magic attacks
    IgnoreDefenderStatusEffects = 1ul <<  7,  // Ignores active status effects on the defender
    IgnoreAttackerStatusEffects = 1ul <<  8,  // Ignores active status effects on the attacker
    IgnoreDefenderAbilities     = 1ul <<  9,  // Ignore the defenders abilities
    IgnoreAttackerAbilities     = 1ul << 10,  // Ignore the attackers abilities
    IgnoreArmorRating           = 1ul << 11,  // Ignore the defensive boosts of armor
    IgnoreWeaponRating          = 1ul << 12,  // Ignore the attack boost from weapons
    HighCritical                = 1ul << 13,  // The move has an increased chance to crit
    CausesStatus                = 1ul << 14,  // Can the move cause status effects?
    Elemental                   = 1ul << 15,  // Is the move elemental based?
    Unimplemented               = 1ul << 16,  // has the move been implemented yet?
    ModsTimer                   = 1ul << 17,  // Does it have an effect on the target or users timer?
    Heals                       = 1ul << 18,  // Does the move heal?
    SecondaryEffects            = 1ul << 19,  // Attack has additional effects besides basic attack
    PhysicalAttackFlag          = 1ul << 20,  // Is the Class Physically based? I.E. blocked by Protect and Shield
    MagicAttackFlag             = 1ul << 21,  // Is the move Magically Based? I.E. is it affected by things like Shell
    MultiHit                    = 1ul << 22,  // Does it enxcapsulate more then 1 hit
    SingleUse                   = 1ul << 23,  // Attack can only be used once per battle
    DoesNotCauseDamage          = 1ul << 24, 

    MaskAttack      = MagicAttackFlag | PhysicalAttackFlag,
    MaskIgnore      = IgnoreWeaponRating | IgnoreArmorRating | IgnoreAttackerAbilities | IgnoreDefenderAbilities | IgnoreAttackerStatusEffects,
    // etc
};

static bool HasAttackFlag(AttackFlags flags)
{
    return flags & MaskAttack;
}

static bool HasIgnoreFlag(AttackFlags flags)
{
    return flags & MaskIgnore;
}

As an added bonus, consider a way to return only 'miscellanous' (un-masked, so to speak) flags: 作为一个额外的好处,考虑一种方法只返回'miscellanous'(无掩盖,可以这么说)标志:

static AttackFlags MiscFlags(AttackFlags flags)
{
    return (AttackFlags) (flags & ~(MaskAttack | MaskIgnore));
}

As an example, you can do this: 例如,您可以这样做:

int v = Unblockable | UncounterableLv1| UncounterableLv;
if ((flags & v ) == v)
{
  //flags has all three: Unblockable, UncounterableLv1 and UncounterableLv
}
else if ( (flags & v ) ==  (Unblockable | UncounterableLv1))
{
  //flags has Unblockable and UncounterableLv1
}
else if ( (flags & v ) ==  Unblockable )
{
  //flags has Unblockable only
}
//and so on

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM