# How can I imbue an ability system with information about how abilities interact and can be targetted?

I am making a turn based game where player chooses a team of heroes with specific abilities for each of them. (ex. stun one enemy, deal 20 damage to all enemies, heal 10 HP to one ally,...)
The design right now is that every non-instant effect (direct heal and damage are instant) is placed as a buff/debuff on the hero. So once a spell affects an enemy it can apply a stun for 2 turns or a DoT for 3 turns, etc.

My problem is that whenever you click on an ability in the GUI, the game should show you who you can target, but enemies can have immunities to certain effects like immune to stun or immune to damage.
My first thought was to make an interface AbilityStun and then once I start checking for viable targets check in the immunity buff if the ability is an instance of a stun and if yes, don't show it as a viable target.

But I soon realized this is a bad solution because I have an ability which damages my own team member and stuns an opponent and it would show him as not viable. Or I want to apply a debuff that will disable healing abilities. Or I want to stun and deal damage.
Suddenly interfaces piled up and I would end up with 50 of them and a systems that feels like a hack.

I am pretty sure there is a better way of doing this but I simply can't figure it out even after looking through other similar articles. Maybe you guys (and girls) who are more experienced can be of more help and point me in the right direction.

EDIT:

Current Solution

So I created a system based on CamH's answer. I have an ability which has information like cooldown, manacost, target, etc. and I added a group of effects to it. Effects can be either stun effect, heal effect, or any other effect in the future with required parameters like heal amount or stun duration as part of the effect.

Most importantly the effect has a group of checks that know what to look for in a group of buffs/debuffs and returns true/false based on whether the target passes the test.

Example: Hero A wants to cast a stun and damage spell on Hero B who is immune to stun. On target selection the Stun effect performs a check against Hero B's buffs and returns false since he is immune. The Damage check passes and since at least one check passed Hero B is a valid target.
After the ability lands every effect is applied separately and checks are performed again this time the stun won't apply and the damage takes place.

The system is more complex than this but this part shows how I solved my problem with targeting and applying abilities.

You could use some tags to determine what the immunities are of the opponent and what the effects are of the attack.

For example, you could give the opponent a tag "stun" and the attack a tag of "damage,stun". You could then check if the attack tag is equal to the opponent's tag and if so, prevent the move.

In the example, even though the enemy is immune to stun, they can still take damage. The attack will stun and do damage, however, the stun wouldn't work because it's immune to stun. So it will cancel the stun and still perform the damage. The opponents tags would be the immunities and the move's tags would be the effects so when running the move you can add effects appropriately.

I think you only need only one interface which you implement with all your abilities and which has only the method bool canTarget(combatTarget).

Each ability would have an own implementation which checks if the target is a valid target. That check should be based on its allegiance and active immunities (although the implementation also allows more unique conditions).

Your target selection gui would check all available combat targets with that method and only show those where it returns true. Combat targets can also be "all allies" (abilities which affect the whole party), "all enemies" (abilities which affect all enemies) or "no particular target" (for abilities which affect all combatants equally or no combatants in particular).

• Would you check each ability or just have each aility check each effect? Wouldnt the former require you to hardcode all your abilities? – Niels Mar 29 '16 at 5:52