[英]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.