local PenguinCardUtils = {} PenguinCardUtils.GameState = { Start = 0, Prepare = 1, Dealing = 2, Flip = 3, Settlement = 4, Complete = 5, Quest = 6 } PenguinCardUtils.SuitName = { [GameEnum.PenguinBaseCardSuit.Blue] = "", [GameEnum.PenguinBaseCardSuit.Red] = "", [GameEnum.PenguinBaseCardSuit.Green] = "" } function PenguinCardUtils.CheckTriggerAble(nTriggerType, tbTriggerParam, nTriggerProbability, mapTriggerSource, nEffectType) local randomValue = math.random(0, 100) local bAble = false if nTriggerType == GameEnum.PenguinCardTriggerType.None then bAble = true elseif mapTriggerSource then if nTriggerType == GameEnum.PenguinCardTriggerType.SuitCards and mapTriggerSource.SuitCards then local nAimCount = #tbTriggerParam local nHasCount = 0 for _, nAimSuit in ipairs(tbTriggerParam) do for _, nHasSuit in ipairs(mapTriggerSource.SuitCards) do if nAimSuit == nHasSuit then nHasCount = nHasCount + 1 end end end if nAimCount <= nHasCount then bAble = true end elseif nTriggerType == GameEnum.PenguinCardTriggerType.SuitCount and mapTriggerSource.SuitCount then for k, nAimCount in pairs(tbTriggerParam) do if not mapTriggerSource.SuitCount[tonumber(k)] or nAimCount > mapTriggerSource.SuitCount[tonumber(k)] then return false end end bAble = true elseif nTriggerType == GameEnum.PenguinCardTriggerType.HandRankSuitCount and mapTriggerSource.HandRankSuitCount then for k, nAimCount in pairs(tbTriggerParam) do if not mapTriggerSource.HandRankSuitCount[tonumber(k)] or nAimCount > mapTriggerSource.HandRankSuitCount[tonumber(k)] then return false end end bAble = true elseif nTriggerType == GameEnum.PenguinCardTriggerType.BaseCardId and mapTriggerSource.BaseCard then for _, v in ipairs(tbTriggerParam) do if mapTriggerSource.BaseCard.nId == v then bAble = true break end end if nEffectType == GameEnum.PenguinCardEffectType.ReplaceBaseCard then if mapTriggerSource.BaseCard.bReplaced == true then return false elseif bAble and nTriggerProbability >= randomValue then mapTriggerSource.BaseCard.bReplaced = true end end elseif nTriggerType == GameEnum.PenguinCardTriggerType.RepeatHandRank and mapTriggerSource.HandRankCount and mapTriggerSource.HandRank then bAble = false for id, count in pairs(mapTriggerSource.HandRankCount) do if mapTriggerSource.HandRank == id and 2 <= count then bAble = true break end end elseif nTriggerType == GameEnum.PenguinCardTriggerType.HandRank and mapTriggerSource.HandRank then for _, v in ipairs(tbTriggerParam) do if mapTriggerSource.HandRank == v then bAble = true break end end end end return bAble and nTriggerProbability >= randomValue end function PenguinCardUtils.CheckGrowthLayer(nGrowthTriggerType, tbGrowthTriggerParam, mapTriggerSource) local nAdd = 0 if nGrowthTriggerType == GameEnum.PenguinCardGrowthTriggerType.None then nAdd = 1 elseif nGrowthTriggerType == GameEnum.PenguinCardGrowthTriggerType.HandRank and mapTriggerSource.HandRank then for _, v in ipairs(tbGrowthTriggerParam) do if mapTriggerSource.HandRank == v then nAdd = 1 break end end elseif nGrowthTriggerType == GameEnum.PenguinCardGrowthTriggerType.LevelCount and mapTriggerSource.PenguinCardLevel then nAdd = mapTriggerSource.PenguinCardLevel elseif nGrowthTriggerType == GameEnum.PenguinCardGrowthTriggerType.SuitCountInCard and mapTriggerSource.BaseCard then local nAimSuit = tbGrowthTriggerParam[1] local mapCfg = ConfigTable.GetData("PenguinBaseCard", mapTriggerSource.BaseCard.nId) if mapCfg then for i = 1, 3 do if 0 < mapCfg["Suit" .. i] and 0 < mapCfg["SuitCount" .. i] and nAimSuit == mapCfg["Suit" .. i] then nAdd = mapCfg["SuitCount" .. i] break end end end end return nAdd end function PenguinCardUtils.SetEffectDesc(mapCfg, nGrowthLayer) local nTriggerType = mapCfg.TriggerType local nEffectType = mapCfg.EffectType local nGrowthTriggerType = mapCfg.GrowthTriggerType nGrowthLayer = nGrowthLayer or 0 local sError = "Error:Parameter mismatch" local ParseTriggerParam = function(tbParam, nIndex) if nTriggerType == GameEnum.PenguinCardTriggerType.SuitCards then local nSuit = tbParam[nIndex] if nSuit == nil then return sError end return PenguinCardUtils.SuitName[nSuit] elseif nTriggerType == GameEnum.PenguinCardTriggerType.BaseCardId then local nBaseCardId = tbParam[nIndex] if nBaseCardId == nil then return sError end local mapBase = ConfigTable.GetData("PenguinBaseCard", nBaseCardId) if mapBase then return mapBase.Title end elseif nTriggerType == GameEnum.PenguinCardTriggerType.SuitCount or nTriggerType == GameEnum.PenguinCardTriggerType.HandRankSuitCount then local mapSuit = {} for k, v in pairs(tbParam) do local nSuit = tonumber(k) if nSuit then mapSuit[nSuit] = v end end local i = 1 for nSuit, v in ipairsSorted(mapSuit) do if i == nIndex then local sName = "" for _ = 1, v do sName = sName .. PenguinCardUtils.SuitName[nSuit] end return sName end i = i + 1 end elseif nTriggerType == GameEnum.PenguinCardTriggerType.HandRank then if tbParam[nIndex] == nil then return sError end local mapHandRank = ConfigTable.GetData("PenguinCardHandRank", tbParam[nIndex]) if mapHandRank then return mapHandRank.Title end end end local ParseEffectParam = function(tbParam, nIndex) if nEffectType == GameEnum.PenguinCardEffectType.AddBaseCardWeight or nEffectType == GameEnum.PenguinCardEffectType.ReplaceBaseCard then local tbId = {} for k, _ in pairs(tbParam) do local nId = tonumber(k) if nId then table.insert(tbId, nId) end end table.sort(tbId, function(a, b) return a < b end) local nBaseCardId = tbId[nIndex] if nBaseCardId == nil then return sError end local mapBase = ConfigTable.GetData("PenguinBaseCard", nBaseCardId) if mapBase then return mapBase.Title end elseif nEffectType == GameEnum.PenguinCardEffectType.RollSpecificCard then local nCardId = tbParam[nIndex] if nCardId == nil then return sError end local mapCard = ConfigTable.GetData("PenguinCard", nCardId) if mapCard then return mapCard.Title end elseif nEffectType == GameEnum.PenguinCardEffectType.IncreaseBasicChips or nEffectType == GameEnum.PenguinCardEffectType.IncreaseMultiplier or nEffectType == GameEnum.PenguinCardEffectType.MultiMultiplier or nEffectType == GameEnum.PenguinCardEffectType.UpgradeDiscount or nEffectType == GameEnum.PenguinCardEffectType.AddRound or nEffectType == GameEnum.PenguinCardEffectType.BlockFatalDamage or nEffectType == GameEnum.PenguinCardEffectType.UpgradeRebate then if tbParam[nIndex] == nil then return sError end return math.abs(tbParam[nIndex]) end end local ParseGrowthTriggerParam = function(tbParam, nIndex) if nGrowthTriggerType == GameEnum.PenguinCardGrowthTriggerType.SuitCountInCard then if tbParam[nIndex] == nil then return sError end return PenguinCardUtils.SuitName[tbParam[nIndex]] elseif nGrowthTriggerType == GameEnum.PenguinCardGrowthTriggerType.HandRank then if tbParam[nIndex] == nil then return sError end local mapHandRank = ConfigTable.GetData("PenguinCardHandRank", tbParam[nIndex]) if mapHandRank then return mapHandRank.Title end end end local ParseTotalEffectParam = function(tbEffectParam, tbGrowthParam, nIndex) if nEffectType == GameEnum.PenguinCardEffectType.IncreaseBasicChips or nEffectType == GameEnum.PenguinCardEffectType.IncreaseMultiplier or nEffectType == GameEnum.PenguinCardEffectType.MultiMultiplier or nEffectType == GameEnum.PenguinCardEffectType.UpgradeDiscount or nEffectType == GameEnum.PenguinCardEffectType.AddRound or nEffectType == GameEnum.PenguinCardEffectType.UpgradeRebate then if tbEffectParam[nIndex] == nil or tbGrowthParam[nIndex] == nil then return sError end local nValue = tbEffectParam[nIndex] + nGrowthLayer * tbGrowthParam[nIndex] if nValue < 0 then nValue = 0 end return nValue end end local result = string.gsub(mapCfg.Desc, "%b{}", function(token) local content = string.match(token, "^{(.-)}$") local sParameterKey, lang, langIdx = ParseLanguageParam(content) if lang ~= nil then token = string.format("{%s}", sParameterKey) end if token == "{TriggerProbability}" then return mapCfg.TriggerProbability elseif token == "{TriggerLimitParam}" then return mapCfg.TriggerLimitParam elseif token == "{DurationParam}" then return mapCfg.DurationParam end local trigIdx = string.match(token, "^{TriggerParam_(%d+)}$") if trigIdx then local idx = tonumber(trigIdx) local str = ParseTriggerParam(decodeJson(mapCfg.TriggerParam), idx) str = LanguagePost(lang, langIdx, str) return str end local effectIdx = string.match(token, "^{EffectParam_(%d+)}$") if effectIdx then local idx = tonumber(effectIdx) local str = ParseEffectParam(decodeJson(mapCfg.EffectParam), idx) str = LanguagePost(lang, langIdx, str) return str end local trigGrowthIdx = string.match(token, "^{GrowthTriggerParam_(%d+)}$") if trigGrowthIdx then local idx = tonumber(trigGrowthIdx) local str = ParseGrowthTriggerParam(decodeJson(mapCfg.GrowthTriggerParam), idx) str = LanguagePost(lang, langIdx, str) return str end local effectGrowthIdx = string.match(token, "^{GrowthEffectParam_(%d+)}$") if effectGrowthIdx then local idx = tonumber(effectGrowthIdx) local str = ParseEffectParam(decodeJson(mapCfg.GrowthEffectParam), idx) str = LanguagePost(lang, langIdx, str) return str end local effectTotalIdx = string.match(token, "^{TotalEffectParam_(%d+)}$") if effectTotalIdx then local idx = tonumber(effectTotalIdx) local str = ParseTotalEffectParam(decodeJson(mapCfg.EffectParam), decodeJson(mapCfg.GrowthEffectParam), idx) str = LanguagePost(lang, langIdx, str) return str end return token end) return result end function PenguinCardUtils.WeightedRandom(tbId, tbWeight, n, tbExcludeGroupId, bDuplicate) if #tbId ~= #tbWeight then printError("tbId 和 tbWeight 长度必须相同") end tbExcludeGroupId = tbExcludeGroupId or {} local tbExcludeSet = {} for _, v in ipairs(tbExcludeGroupId) do tbExcludeSet[v] = true end local tbCandidates = {} for i = 1, #tbId do local id = tbId[i] local w = tbWeight[i] if next(tbExcludeSet) == nil then table.insert(tbCandidates, {id = id, weight = w}) else local mapCfg = ConfigTable.GetData("PenguinCard", id) if mapCfg and not tbExcludeSet[mapCfg.GroupId] then table.insert(tbCandidates, {id = id, weight = w}) end end end if #tbCandidates == 0 then return {} end local result = {} if bDuplicate then local totalWeight = 0 for _, item in ipairs(tbCandidates) do totalWeight = totalWeight + item.weight end for _ = 1, n do local r = math.random() * totalWeight local cum = 0 for _, item in ipairs(tbCandidates) do cum = cum + item.weight if r < cum then table.insert(result, item.id) break end end end else local actualN = math.min(n, #tbCandidates) for _ = 1, actualN do local totalWeight = 0 for _, item in ipairs(tbCandidates) do totalWeight = totalWeight + item.weight end if totalWeight <= 0 then break end local r = math.random() * totalWeight local cum = 0 for i, item in ipairs(tbCandidates) do cum = cum + item.weight if r < cum then table.insert(result, item.id) table.remove(tbCandidates, i) break end end end end return result end return PenguinCardUtils