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.
Thank you for your help.
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.