GameState ApplyEffect(string effectName, int power, TargettingInfo targettingInfo, GameState state)
        {
            var character = CharacterResolver.Create(targettingInfo.TargetID, state);

            if (character.Item.HasEffect(effectName))
            {
                return(ExtendEffect(effectName, power, character, state));
            }
            else
            {
                return(AddNewEffect(effectName, power, character, state));
            }
        }
        public GameState Apply(TargettedAction targettedAction, GameState state)
        {
            TargettingInfo targettingInfo = targettedAction.TargetInfo;
            Character      invoker        = state.AllCharacters.WithIDOrNull(targettingInfo.InvokerID);

            if (invoker == null || !invoker.IsAlive)
            {
                return(state);
            }

            Action     action = targettedAction.Action;
            ActionType type   = action.Type;

            if (type.HasFlag(ActionType.Damage) || type.HasFlag(ActionType.Heal))
            {
                Character target = state.AllCharacters.WithIDOrNull(targettingInfo.TargetID);
                if (target == null || !target.IsAlive)
                {
                    return(state);
                }
            }

            if (type.HasFlag(ActionType.Damage))
            {
                state = ApplyDamage(action.Power, CharacterResolver.Create(targettingInfo.TargetID, state), state);
            }

            if (type.HasFlag(ActionType.Heal))
            {
                state = ApplyHeal(action.Power, CharacterResolver.Create(targettingInfo.TargetID, state), state);
            }

            if (type.HasFlag(ActionType.Cooldown))
            {
                state = ApplyCooldown(targettingInfo, state);
            }

            if (type.HasFlag(ActionType.Effect))
            {
                state = ApplyEffect(action.EffectName, action.Power, targettingInfo, state);
            }

            if (type.HasFlag(ActionType.RemoveEffect))
            {
                state = RemoveEffect(action.EffectName, targettingInfo, state);
            }

            return(state);
        }