-- Rush Duel 条件
RushDuel = RushDuel or {}

-- 条件: 卡片是否处于"极大模式"
function RushDuel.IsMaximumMode(card)
    return card:IsLocation(LOCATION_MZONE) and card:IsSummonType(SUMMON_TYPE_MAXIMUM) and card:GetOverlayCount() > 0
end
-- 条件: 这张卡召唤的回合
function RushDuel.IsSummonTurn(card)
    return card:IsReason(REASON_SUMMON) and card:IsStatus(STATUS_SUMMON_TURN) and card:GetFlagEffect(FLAG_NOT_SUMMON_TURN) == 0
end
-- 条件: 这张卡特殊召唤的回合
function RushDuel.IsSpecialSummonTurn(card)
    return card:IsReason(REASON_SPSUMMON) and card:IsStatus(STATUS_SPSUMMON_TURN) and card:GetFlagEffect(FLAG_NOT_SUMMON_TURN) == 0
end
-- 条件: 玩家的LP在 lp 以上
function RushDuel.IsLPAbove(player, lp)
    return Duel.GetLP(player) >= lp
end
-- 条件: 玩家的LP在 lp 以下
function RushDuel.IsLPBelow(player, lp)
    return Duel.GetLP(player) <= lp
end
-- 条件: 玩家的LP比对方少 lp 以上
function RushDuel.IsLPBelowOpponent(player, lp)
    return Duel.GetLP(player) <= Duel.GetLP(1 - player) - (lp or 0)
end
-- 条件: 守备力为 def
function RushDuel.IsDefense(card, def)
    return card:IsDefense(def) and not RushDuel.IsMaximumMode(card)
end
-- 条件: 守备力在 def 以上
function RushDuel.IsDefenseAbove(card, def)
    return card:IsDefenseAbove(def) and not RushDuel.IsMaximumMode(card)
end
-- 条件: 守备力在 def 以下
function RushDuel.IsDefenseBelow(card, def)
    return card:IsDefenseBelow(def) and not RushDuel.IsMaximumMode(card)
end
-- 条件: 可否改变守备力
function RushDuel.IsCanChangeDef(card)
    return card:IsDefenseAbove(0) and not RushDuel.IsMaximumMode(card)
end
-- 条件: 可否改变表示形式
function RushDuel.IsCanChangePosition(card)
    return card:IsCanChangePosition() and not RushDuel.IsMaximumMode(card)
end
-- 条件: 可否特殊召唤
function RushDuel.IsCanBeSpecialSummoned(card, effect, player, position)
    return card:IsCanBeSpecialSummoned(effect, 0, player, false, false, position)
end
-- 条件: 可否加入手卡或特殊召唤
function RushDuel.IsAbleToHandOrSpecialSummon(card, effect, player, position)
    return card:IsAbleToHand() or (Duel.GetLocationCount(player, LOCATION_MZONE) > 0 and RushDuel.IsCanBeSpecialSummoned(card, effect, player, position))
end

-- 条件: 位置变化前的控制者
function RushDuel.IsPreviousControler(card, player)
    return card:GetPreviousControler() == player
end
-- 条件: 位置变化前的类型
function RushDuel.IsPreviousType(card, type)
    return (card:GetPreviousTypeOnField() & type) ~= 0
end
-- 条件: 位置变化前的属性
function RushDuel.IsPreviousAttribute(card, attr)
    return (card:GetPreviousAttributeOnField() & attr) ~= 0
end
-- 条件: 位置变化前的种族
function RushDuel.IsPreviousRace(card, race)
    return (card:GetPreviousRaceOnField() & race) ~= 0
end

-- 条件: 可以攻击
function RushDuel.IsCanAttack(card)
    return not card:IsHasEffect(EFFECT_CANNOT_ATTACK)
end
-- 条件: 可否赋予效果 - 直接攻击
function RushDuel.IsCanAttachDirectAttack(card)
    return RushDuel.IsCanAttack(card) and not card:IsHasEffect(EFFECT_DIRECT_ATTACK) and not card:IsHasEffect(EFFECT_CANNOT_DIRECT_ATTACK)
end
-- 条件: 可否赋予效果 - 贯通
function RushDuel.IsCanAttachPierce(card)
    return RushDuel.IsCanAttack(card) and not card:IsHasEffect(EFFECT_PIERCE)
end
-- 条件: 可否赋予效果 - 多次攻击
function RushDuel.IsCanAttachExtraAttack(card, value)
    if not RushDuel.IsCanAttack(card) then
        return false
    end
    local values = RushDuel.GetEffectValues(card, EFFECT_EXTRA_ATTACK)
    for _, val in ipairs(values) do
        if val >= value then
            return false
        end
    end
    return true
end
-- 条件: 可否赋予效果 - 多次攻击 (怪兽限定)
function RushDuel.IsCanAttachExtraAttackMonster(card, value)
    if not RushDuel.IsCanAttack(card) then
        return false
    end
    local values = RushDuel.GetEffectValues(card, EFFECT_EXTRA_ATTACK_MONSTER)
    for _, val in ipairs(values) do
        if val >= value then
            return false
        end
    end
    return true
end
-- 条件: 可否赋予效果 - 全体攻击
function RushDuel.IsCanAttachAttackAll(card, value)
    return RushDuel.IsCanAttack(card)
end
-- 条件: 可否赋予效果 - 双重解放
function RushDuel.IsCanAttachDoubleTribute(card, value)
    if Duel.IsPlayerAffectedByEffect(card:GetControler(), EFFECT_CANNOT_DOUBLE_TRIBUTE) then
        return false
    end
    if card:IsHasEffect(EFFECT_UNRELEASABLE_SUM) then
        return false
    end
    local values = RushDuel.GetEffectValues(card, EFFECT_DOUBLE_TRIBUTE)
    return RushDuel.CheckValueDoubleTribute(values, value)
end
-- 条件: 可否赋予效果 - 三重解放
function RushDuel.IsCanAttachTripleTribute(card, value)
    if Duel.IsPlayerAffectedByEffect(card:GetControler(), EFFECT_CANNOT_DOUBLE_TRIBUTE) then
        return false
    end
    if card:IsHasEffect(EFFECT_UNRELEASABLE_SUM) then
        return false
    end
    local values = RushDuel.GetEffectValues(card, EFFECT_TRIPLE_TRIBUTE)
    return RushDuel.CheckValueDoubleTribute(values, value)
end
-- 条件: 可否赋予效果 - 使用对方的怪兽解放
function RushDuel.IsCanAttachOpponentTribute(card, player, flag)
    if Duel.IsPlayerAffectedByEffect(player, EFFECT_CANNOT_SINGLE_TRIBUTE) and Duel.IsPlayerAffectedByEffect(player, EFFECT_CANNOT_DOUBLE_TRIBUTE) then
        return false
    end
    return not card:IsHasEffect(EFFECT_UNRELEASABLE_SUM) and card:GetFlagEffect(flag) == 0
end
-- 条件: 可否赋予效果 - 战斗破坏抗性
function RushDuel.IsCanAttachBattleIndes(card, value)
    local values = RushDuel.GetEffectValues(card, EFFECT_INDESTRUCTABLE_BATTLE)
    for _, val in ipairs(values) do
        if val == 1 then
            return false
        end
    end
    return true
end
-- 条件: 可否赋予效果 - 效果破坏抗性
function RushDuel.IsCanAttachEffectIndes(card, player, value)
    local swap = card:GetOwner() ~= player
    local values = RushDuel.GetEffectValues(card, EFFECT_INDESTRUCTABLE_EFFECT)
    return RushDuel.CheckValueEffectIndesType(swap, values, value)
end
-- 条件: 可否赋予效果 - 永续效果无效化
function RushDuel.IsCanAttachDisableContinuous(card)
    local has_effect = card.continuous_effect
    if RushDuel.IsMaximumMode(card) then
        card:GetOverlayGroup():ForEach(function(tc)
            has_effect = has_effect or tc.continuous_effect
        end)
    end
    return has_effect and not card:IsHasEffect(EFFECT_DISABLE)
end

-- 条件: 玩家是否能够使用特定种族进行攻击
function RushDuel.IsPlayerCanUseRaceAttack(player, race)
    if Duel.IsPlayerAffectedByEffect(player, EFFECT_PLAYER_CANNOT_ATTACK) then
        return false
    end
    local effects = {Duel.IsPlayerAffectedByEffect(player, EFFECT_PLAYER_RACE_CANNOT_ATTACK)}
    for i, effect in ipairs(effects) do
        if (race & effect:GetValue()) == race then
            return false
        end
    end
    return true
end

-- 额外条件: 最后的操作是否包含某种卡
function RushDuel.IsOperatedGroupExists(filter, count, expect)
    return filter == nil or Duel.GetOperatedGroup():IsExists(filter, count, expect)
end
