local GFunc = {}
local EMPTY_TABLE = {}
local HASH_SEED = 31
local UINT_RANGE = 4294967296
local byte = string.byte
local DESIGN_RESOLUTION_WIDTH = CS.BF.GameConst.DESIGN_RESOLUTION_WIDTH
local DESIGN_RESOLUTION_HEIGHT = CS.BF.GameConst.DESIGN_RESOLUTION_HEIGHT
local UnityTime = CS.UnityEngine.Time
--获取unicode 字符串长度 和utf-8长度
function GFunc.getTextLen(str)
local byteLen = #str
local strLen = 0
local i = 1
local curByte
local byteCount = 1
while i <= byteLen do
curByte = byte(str, i)
byteCount = 1
if curByte > 0 and curByte <= 127 then
byteCount = 1
elseif curByte >= 192 and curByte < 223 then
byteCount = 2
elseif curByte >= 224 and curByte < 239 then
byteCount = 3
elseif curByte >= 240 and curByte <= 247 then
byteCount = 4
end
i = i + byteCount
strLen = strLen + 1
end
return strLen, i - 1
end
function GFunc.getTextLen2(str)
local byteLen = #str
local strLen = 0
local i = 1
local curByte
local byteCount = 1
while i <= byteLen do
curByte = byte(str, i)
byteCount = 1
if curByte > 0 and curByte <= 127 then
byteCount = 1
strLen = strLen + 1
elseif curByte >= 192 and curByte < 223 then
-- 中文算2个字节
byteCount = 2
strLen = strLen + 1
elseif curByte >= 224 and curByte < 239 then
byteCount = 3
strLen = strLen + 2
elseif curByte >= 240 and curByte <= 247 then
byteCount = 4
strLen = strLen + 1
end
i = i + byteCount
end
return strLen, i - 1
end
-- 判断字符串是不是全部都是空格,32是半角空格,227是全角空格
function GFunc.getIsAllSpaceStr(str)
local result = true
local byteLen = #str
local i = 1
local curByte
local byteCount = 1
while i <= byteLen do
curByte = byte(str, i)
byteCount = 1
if curByte > 0 and curByte <= 127 then
byteCount = 1
if curByte ~= 32 then
result = false
break
end
elseif curByte >= 192 and curByte < 223 then
byteCount = 2
result = false
break
elseif curByte >= 224 and curByte < 239 then
byteCount = 3
if curByte ~= 227 then
result = false
break
end
elseif curByte >= 240 and curByte <= 247 then
byteCount = 4
result = false
break
else
result = false
break
end
i = i + byteCount
end
return result
end
function GFunc.num2Str(count, dec)
if count >= 99999999999 then -- 前端限制最大显示99999M
if dec then
return "99999.99M"
else
return "99999M"
end
elseif count >= 10000000 then
if dec then
count = math.floor((count*10^dec)/1000000)/(10^dec)
return count .. "M"
else
count = count // 1000000
return count .. "M"
end
elseif count >= 100000 then
if dec then
count = math.floor((count*10^dec)/1000)/(10^dec)
return count .. "K"
else
count = count // 1000
return count .. "K"
end
else
return GFunc.parseDedundantNumber(count)
end
end
-- 超过千位就缩写,目前只有公会奖励用到 1K-5K
function GFunc.num2Str2(count, dec)
if count >= 99999999999 then -- 前端限制最大显示99999M
if dec then
return "99999.99M"
else
return "99999M"
end
elseif count >= 1000000 then
if dec then
count = math.floor((count*10^dec)/1000000)/(10^dec)
return count .. "M"
else
count = count // 1000000
return count .. "M"
end
elseif count >= 1000 then
if dec then
count = math.floor((count*10^dec)/1000)/(10^dec)
return count .. "K"
else
count = count // 1000
return count .. "K"
end
else
return GFunc.parseDedundantNumber(count)
end
end
-- 与num2Str类似 但是上限扩大3位至99999B
function GFunc.num2Str3(count, dec)
if count >= 99999999999999 then -- 前端限制最大显示99999B
if dec then
return "99999.99B"
else
return "99999B"
end
elseif count >= 10000000000 then
if dec then
count = math.floor((count*10^dec)/1000000000)/(10^dec)
return count .. "B"
else
count = count // 1000000000
return count .. "B"
end
elseif count >= 10000000 then
if dec then
count = math.floor((count*10^dec)/1000000)/(10^dec)
return count .. "M"
else
count = count // 1000000
return count .. "M"
end
elseif count >= 100000 then
if dec then
count = math.floor((count*10^dec)/1000)/(10^dec)
return count .. "K"
else
count = count // 1000
return count .. "K"
end
else
return GFunc.parseDedundantNumber(count)
end
end
function GFunc.killDOTween(id, complete)
if complete == nil then
return CS.BF.Utils.KillDOTween(id)
else
return CS.BF.Utils.KillDOTween(id, complete)
end
end
function GFunc.setDOTweenTimeScale(id, timeScale)
CS.BF.Utils.SetDOTweenTimeScale(id, timeScale)
end
function GFunc.nameToLayer(name)
return CS.BF.Utils.NameToLayer(name)
end
-- BKDRHash
function GFunc.hash(str)
local h = 0
for i = 1, #str do
h = h * HASH_SEED + byte(str, i)
end
return h%UINT_RANGE
end
function GFunc.getScreenSize()
return CS.UnityEngine.Screen.width, CS.UnityEngine.Screen.height
end
function GFunc.parseDedundantNumber(num)
if num % 1 == 0 then
return math.ceil(num)
else
return num
end
end
function GFunc.openUrl(web)
CS.UnityEngine.Application.OpenURL(web)
end
function GFunc.getShader(shaderName)
return CS.UnityEngine.Shader.Find(shaderName)
end
function GFunc.subStringGetByteCount(str, index)
local curByte = byte(str, index)
local byteCount = 1
if curByte == nil then
byteCount = 0
elseif curByte > 240 then
byteCount = 4
elseif curByte > 225 then
byteCount = 3
elseif curByte > 192 then
byteCount = 2
end
return byteCount
end
function GFunc.subStringByCharCount(str, needCount)
local index = 1
local lastIndex = 1
local num = 0
while num < needCount and lastIndex ~= 0 do
lastIndex = GFunc.subStringGetByteCount(str, index)
index = index + lastIndex
num = num + 1
end
return string.sub(str,1, index - 1)
end
function GFunc.setLayer(gameObject, layerName)
local trans = gameObject.transform:GetComponentsInChildren(typeof(CS.UnityEngine.Transform))
local layer = GFunc.nameToLayer(layerName)
if trans then
local len = trans.Length
for i = 0, len - 1 do
trans[i].gameObject.layer = layer
end
end
end
-- 根据当前屏幕分辨率 计算偏差值
function GFunc.calculateFitSizeY()
local width, height = GFunc.getScreenSize()
local dif = 0
if width / height < DESIGN_RESOLUTION_WIDTH / DESIGN_RESOLUTION_HEIGHT then
dif = height / (width / DESIGN_RESOLUTION_WIDTH) - DESIGN_RESOLUTION_HEIGHT
end
return dif
end
-- 获得Expand模式下UI分辨率
function GFunc.getUIExpandScreenSize()
local width, height = GFunc.getScreenSize()
if width / height <= DESIGN_RESOLUTION_WIDTH / DESIGN_RESOLUTION_HEIGHT then
height = height * (DESIGN_RESOLUTION_WIDTH / width)
width = DESIGN_RESOLUTION_WIDTH
else
width = width * (DESIGN_RESOLUTION_HEIGHT / height)
height = DESIGN_RESOLUTION_HEIGHT
end
return width, height
end
function GFunc.checkNameValid(str, min, max)
local result = nil
if str == nil or str == "" then
--输入不能为空
return false
else
result = string.match(str, "/u{0020}") or string.match(str, "/u{3000}") or string.match(str, "/u{00A0}")
end
if result then
--非法字符
return false
end
local k, length = GFunc.getTextLen(str)
if length < min then
return false
elseif length > max then
return false
end
return true
end
function GFunc.showMessageBox(params)
local MessageBox = require "app/ui/common/message_box"
MessageBox:showMessageBox(params)
end
function GFunc.showCheatingBox(params)
local CheatMessageBox = require "app/ui/common/cheat_message_box"
CheatMessageBox:showCheatMessageBox(params)
end
function GFunc.hideCheatingBox()
local CheatMessageBox = require "app/ui/common/cheat_message_box"
CheatMessageBox:hideCheatMessageBox()
end
function GFunc.showToast(tab)
ModuleManager.ToastManager:showToast(tab)
end
function GFunc.UiRectTransformScreenPointToLocalPointInRectangle(go, x, y)
local uiCamera = UIManager:getUICameraComponent()
local anchoredPosition = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(go:getTransform(),
x, y, uiCamera)
return anchoredPosition
end
function GFunc.UiRectangleContainsScreenPoint(go, x, y)
local uiCamera = UIManager:getUICameraComponent()
return CS.BF.Utils.RectangleContainsScreenPoint(go:getTransform(), x, y, uiCamera)
end
function GFunc.getPerByW(ratio)
if ratio < 0 then
return math.ceil(ratio*0.01)
else
return math.floor(ratio*0.01)
end
end
function GFunc.getPerByW2(ratio)
if ratio < 0 then
return math.ceil(ratio*0.0001)
else
return math.floor(ratio*0.0001)
end
end
function GFunc.getPerByW3(ratio)
return ratio*0.0001
end
-- function GFunc.getRoundingNumByW(num)
-- if num <= 0 then
-- return 0
-- end
-- if num < 10000 then
-- return GFunc.getRoundingNumByW(num*100) // 100
-- end
-- local remainder = num%10000
-- if remainder < 5000 then
-- return num - remainder
-- elseif remainder > 5000 then
-- return num - remainder + 10000
-- else
-- local integer = (num - remainder)*0.0001
-- if integer%2 == 0 then
-- return num - remainder
-- else
-- return num - remainder + 10000
-- end
-- end
-- end
function GFunc.getFinalAttr(key, value)
if key == GConst.ATTR_TYPE.crit or
key == GConst.ATTR_TYPE.crit_time or
-- key == GConst.ATTR_TYPE.atk_range or
key == GConst.ATTR_TYPE.atkp_1 or
key == GConst.ATTR_TYPE.atkp_2 or
key == GConst.ATTR_TYPE.atkp_3 or
key == GConst.ATTR_TYPE.atkp_4 or
key == GConst.ATTR_TYPE.atkp_5 or
key == GConst.ATTR_TYPE.atkp_6 or
key == GConst.ATTR_TYPE.hpp_1 or
key == GConst.ATTR_TYPE.hpp_2 or
key == GConst.ATTR_TYPE.hpp_3 or
key == GConst.ATTR_TYPE.hpp_4 or
key == GConst.ATTR_TYPE.hpp_5 or
key == GConst.ATTR_TYPE.hpp_6 or
key == GConst.ATTR_TYPE.hpp_7 or
key == GConst.ATTR_TYPE.atkp_7 or
key == GConst.ATTR_TYPE.atkp_8 or
key == GConst.ATTR_TYPE.atkp_9 or
-- key == GConst.ATTR_TYPE.spdp or
key == GConst.ATTR_TYPE.gold_gain or
key == GConst.ATTR_TYPE.dmg_addition_skill or
key == GConst.ATTR_TYPE.dmg_addition_normal or
key == GConst.ATTR_TYPE.pickaxe_recover_spd or
key == GConst.ATTR_TYPE.mineral_gain or
key == GConst.ATTR_TYPE.research_spd or
key == GConst.ATTR_TYPE.dmg_addition or
key == GConst.ATTR_TYPE.dmg_addition_poicon or
-- key == GConst.ATTR_TYPE.atkp_0 or
key == GConst.ATTR_TYPE.airborne_damage or
-- key == GConst.ATTR_TYPE.skill_all_damage or
-- key == GConst.ATTR_TYPE.skill_1_damage or
-- key == GConst.ATTR_TYPE.skill_2_damage or
-- key == GConst.ATTR_TYPE.skill_3_damage or
-- key == GConst.ATTR_TYPE.attack_damage or
key == GConst.ATTR_TYPE.miss or
key == GConst.ATTR_TYPE.dmg_dec_all or
key == GConst.ATTR_TYPE.idle_income
then
return BigNumOpt.bigNumDiv(value, {value = 100, unit = 0})
else
return BigNumOpt.bigNumDiv(value, {value = 10000, unit = 0})
end
end
function GFunc.getPerStr(key, str)
if key == GConst.ATTR_TYPE.crit or
key == GConst.ATTR_TYPE.crit_time or
-- key == GConst.ATTR_TYPE.atk_range or
key == GConst.ATTR_TYPE.atkp_1 or
key == GConst.ATTR_TYPE.atkp_2 or
key == GConst.ATTR_TYPE.atkp_3 or
key == GConst.ATTR_TYPE.atkp_4 or
key == GConst.ATTR_TYPE.atkp_5 or
key == GConst.ATTR_TYPE.atkp_6 or
key == GConst.ATTR_TYPE.atkp_7 or
key == GConst.ATTR_TYPE.atkp_8 or
key == GConst.ATTR_TYPE.atkp_9 or
key == GConst.ATTR_TYPE.hpp_1 or
key == GConst.ATTR_TYPE.hpp_2 or
key == GConst.ATTR_TYPE.hpp_3 or
key == GConst.ATTR_TYPE.hpp_4 or
key == GConst.ATTR_TYPE.hpp_5 or
key == GConst.ATTR_TYPE.hpp_6 or
key == GConst.ATTR_TYPE.hpp_7 or
-- key == GConst.ATTR_TYPE.spdp or
key == GConst.ATTR_TYPE.gold_gain or
key == GConst.ATTR_TYPE.dmg_addition_skill or
key == GConst.ATTR_TYPE.dmg_addition_normal or
key == GConst.ATTR_TYPE.pickaxe_recover_spd or
key == GConst.ATTR_TYPE.mineral_gain or
key == GConst.ATTR_TYPE.research_spd or
key == GConst.ATTR_TYPE.dmg_addition or
key == GConst.ATTR_TYPE.dmg_addition_poicon or
-- key == GConst.ATTR_TYPE.atkp_0 or
key == GConst.ATTR_TYPE.airborne_damage or
-- key == GConst.ATTR_TYPE.skill_all_damage or
-- key == GConst.ATTR_TYPE.skill_1_damage or
-- key == GConst.ATTR_TYPE.skill_2_damage or
-- key == GConst.ATTR_TYPE.skill_3_damage or
-- key == GConst.ATTR_TYPE.attack_damage or
key == GConst.ATTR_TYPE.miss or
key == GConst.ATTR_TYPE.dmg_dec_all or
key == GConst.ATTR_TYPE.idle_income
then
str = str .. "%"
end
return str
end
function GFunc.getFinalPerStr(typeId, bigNum)
return GFunc.getPerStr(typeId, BigNumOpt.bigNum2Str(GFunc.getFinalAttr(typeId, bigNum)))
end
function GFunc.getAttrName(key)
return I18N:getText("attr", key, "name")
end
function GFunc.getAttrNameAndValue(attrStruct, colorCode)
local finalStr = BigNumOpt.bigNumCfgAttr2FinalValueStr(attrStruct)
if colorCode then
finalStr = string.format("%s", colorCode, finalStr)
end
local str = GFunc.getAttrName(GConst.ATTR_TYPE[attrStruct.type]) .. "+" .. finalStr
return str
end
function GFunc.getAttrNameAndValue2(attrType, attrBigNum, colorCode)
local finalStr = BigNumOpt.bigNumCfgAttr2FinalValueStr2(GConst.ATTR_TYPE[attrType], attrBigNum)
if colorCode then
finalStr = string.format("%s", colorCode, finalStr)
end
local str = GFunc.getAttrName(GConst.ATTR_TYPE[attrType]) .. "+" .. finalStr
return str
end
function GFunc.getTimeStrWithMS(time)
local m = math.floor(time/60)
local s = time%60
return I18N:getGlobalText(I18N.GlobalConst.TIME_MS, string.format("%02d", m), string.format("%02d", s))
end
function GFunc.getTimeStrWithMS2(time)
local m = math.floor(time/60)
local s = time%60
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_MS, string.format("%02d", m), string.format("%02d", s))
end
function GFunc.getTimeStrWithHMS(time)
local h = math.floor(time/3600)
local m = math.floor((time%3600)/60)
local s = time%60
return I18N:getGlobalText(I18N.GlobalConst.TIME_HMS, string.format("%02d", h), string.format("%02d", m), string.format("%02d", s))
end
function GFunc.getTimeStrWithM2(time)
local m = time // 60
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_M, m)
end
function GFunc.getTimeStrWithHMS2(time)
local h = math.floor(time/3600)
local m = math.floor((time%3600)/60)
local s = time%60
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_HMS, h, m, s)
end
function GFunc.getTimeStrWithDH2(time)
local d = math.floor(time/86400)
local h = math.floor((time%86400)/3600)
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_DH, d, h)
end
function GFunc.getTimeStrWithD2(time)
local d = math.floor(time/86400)
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_D, d)
end
function GFunc.getTimeStrWithHM(time)
local h = math.floor(time/3600)
local m = math.floor((time%3600)/60)
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_HM, string.format("%02d", h), string.format("%02d", m))
end
function GFunc.getTimeStrWithHM2(time)
local h = math.floor(time/3600)
local m = math.floor((time%3600)/60)
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_HM, h, m)
end
function GFunc.getTimeStr(time)
if time > 86400 then
return GFunc.getTimeStrWithDH2(time)
else
return GFunc.getTimeStrWithHMS2(time)
end
end
function GFunc.getTimeStr2(time)
if time > 86400 then
return GFunc.getTimeStrWithD2(time)
else
return GFunc.getTimeStrWithHM2(time)
end
end
function GFunc.getTimeStr3(time)
if time >= 3600 then
return GFunc.getTimeStrWithHM(time)
else
return GFunc.getTimeStrWithMS2(time)
end
end
function GFunc.getAdaptScale(basePixel)
basePixel = basePixel or 0
local DESIGN_WIDTH = 720
local DESIGN_HEIGHT = 1280
local safeHeight = SafeAreaManager:getNotchScreenHeight()
local winSizeWidth, winSizeHeight = GFunc.getScreenSize()
local maxScale = math.max(DESIGN_WIDTH/winSizeWidth, DESIGN_HEIGHT/winSizeHeight)
local height = maxScale*winSizeHeight - basePixel - safeHeight
local scale = height/(DESIGN_HEIGHT - basePixel)
return scale
end
function GFunc.getConstIntValue(key)
local ConstCfg = ConfigManager:getConfig("const")
return math.floor(ConstCfg[key].value)
end
function GFunc.getConstValue(key)
local ConstCfg = ConfigManager:getConfig("const")
return ConstCfg[key] and ConstCfg[key].value or 0
end
function GFunc.getTargetAnchoredPosition(targetGo, parent)
local rectTransform = targetGo:getComponent(GConst.TYPEOF_UNITY_CLASS.RECTTRANSFORM)
local rect = rectTransform.rect
local localToWorldMatrix = rectTransform.localToWorldMatrix
local tarCornerMid = localToWorldMatrix:MultiplyPoint3x4(BF.Vector3((rect.xMax + rect.x) / 2, (rect.yMax + rect.y) / 2, 0))
local screenPos = UIManager:getUICameraComponent():WorldToScreenPoint(tarCornerMid)
local anchoredPosition = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(parent:getTransform(), screenPos.x, screenPos.y, UIManager:getUICameraComponent())
return anchoredPosition
end
function GFunc.getFormatPrice(rechargeId)
local cfg = ConfigManager:getConfig("recharge")[rechargeId]
if cfg == nil then
return GConst.EMPTY_STRING
end
-- 优先读取通过sdk获取的商品价格
local price = SDKManager:getProductPrice(cfg.payId)
if price and price ~= "" then
return price
end
-- sdk里查不到就读表
return cfg.price_str
end
function GFunc.setGrey(component, isGrey)
if isGrey then
component.color = GConst.COMPONENT_GREY_COLOR
else
component.color = GConst.COLOR.WHITE
end
end
function GFunc.checkBit(value, nbit)
if not value then
return false
end
local ret = value >> (nbit - 1)
if ret %2 == 1 then
return true
else
return false
end
end
function GFunc.showItemNotEnough(itemId)
local gemTextInfo = I18N:getConfig("item")[itemId]
if gemTextInfo then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ITEM_NOT_ENOUGH, gemTextInfo.name))
end
end
function GFunc.showJewelryNotEnough(itemId)
local gemTextInfo = I18N:getConfig("jewelry")[itemId]
if gemTextInfo then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ITEM_NOT_ENOUGH, gemTextInfo.name))
end
end
function GFunc.checkCost(id, num, showToast, giftType)
if num.value <= 0 then
BIReport:postDataException(id, num.value, giftType)
return false
end
local bigNum = DataManager.BagData.ItemData:getItemBigNumById(id)
if BigNumOpt.bigNumCompare(bigNum, num) < 0 then
if showToast then
GFunc.showItemNotEnough(id)
end
return false
else
return true
end
end
function GFunc.checkCostNum(id, num, giftType)
if num <= 0 then
BIReport:postDataException(id, num, giftType)
return false
end
return true
end
---- 获得奖励的统一接口
function GFunc.addRewards(rewards, itemGetType)
if rewards == nil then
return
end
if EDITOR_MODE then
if not itemGetType then
local params = {
content = "GFunc addRewards has no itemGetType",
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
Logger.log("GFunc addRewards has no itemGetType")
end
end
-- 用元表来判断此奖励是否领过了,避免重复领取
if getmetatable(rewards) then
return
end
setmetatable(rewards, EMPTY_TABLE)
-- 合并奖励
local newRewards = {}
GFunc.mergeRewards2(rewards, newRewards)
local runeList = {}
-- 根据类型type来添加奖励
for k, v in ipairs(newRewards) do
if v.type == GConst.REWARD_TYPE.ITEM then
DataManager.BagData.ItemData:addItem(v.item, itemGetType)
elseif v.type == GConst.REWARD_TYPE.EQUIP then
DataManager.BagData.EquipData:addEquipCountById(v.equip.id, v.equip.count, itemGetType)
end
end
ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_RUNE_GOT, {runeList = runeList})
end
function GFunc.addCosts(costs, itemGetType)
if costs == nil then
return
end
-- 用元表来判断此消耗是否领过了,避免重复扣除
if getmetatable(costs) then
return
end
setmetatable(costs, EMPTY_TABLE)
for _, unitCost in ipairs(costs) do
if unitCost.type == GConst.REWARD_TYPE.ITEM then
DataManager.BagData.ItemData:addItemCost(unitCost.item, itemGetType)
end
end
end
-- 奖励排序 结构为后端结构
-- function GFunc.sortRewards(rewards)
-- rewards = rewards or {}
-- local maxType = 10
-- for i,v in ipairs(rewards) do
-- if v.type == GConst.REWARD_TYPE.ITEM then
-- rewards[i].sort = (maxType - v.type) * 1000000000 + (1000000000 - v.item.cfg_id)
-- elseif v.type == GConst.REWARD_TYPE.EQUIP then
-- local cfg = ConfigManager:getConfig("equip")[v.equip.id]
-- rewards[i].sort = (maxType - v.type) * 1000000000 + cfg.qlt*100000000 + v.equip.id
-- elseif v.type == GConst.REWARD_TYPE.JEWELRY then
-- rewards[i].sort = (maxType - v.type) * 1000000000 + (1000000000 - v.jewelry.cfg_id)
-- end
-- end
-- table.sort(rewards, function (a, b)
-- return a.sort > b.sort
-- end)
-- end
---- 奖励展示接口
function GFunc.showRewardBox(rewards, extParams, callback)
rewards = rewards or {}
local params = extParams or {}
local newRewards = {}
if not params.noMerge then
GFunc.mergeRewards2(rewards, newRewards)
else
newRewards = rewards
end
params.rewards = newRewards
params.callback = callback
ModuleManager.TipsManager:showRewardsBox(params)
end
function GFunc.mergeRewards2(rewards, newRewards)
local items = {}
for i,v in ipairs(rewards) do
if v.type == GConst.REWARD_TYPE.ITEM then
if not items[v.item.id] then
items[v.item.id] = BigNumOpt.num2BigNum(0)
end
items[v.item.id] = BigNumOpt.bigNumAdd(items[v.item.id], v.item.count)
elseif v.type == GConst.REWARD_TYPE.EQUIP then
table.insert(newRewards, v)
elseif v.type == GConst.REWARD_TYPE.LEGACY then
table.insert(newRewards, v)
elseif v.type == GConst.REWARD_TYPE.RUNES then
table.insert(newRewards, v)
end
end
for k,v in pairs(items) do
table.insert(newRewards, {type = GConst.REWARD_TYPE.ITEM, item = {id = k, count = v}})
end
end
-- reward 结构为 type id num 配置中结构
function GFunc.mergeRewards(rewards)
local items = {}
local newRewards = {}
for i,v in ipairs(rewards) do
if v.type == GConst.REWARD_TYPE.ITEM then
items[v.id] = (items[v.id] or 0) + v.num
elseif v.type == GConst.REWARD_TYPE.EQUIP then
table.insert(newRewards, v)
elseif v.type == GConst.REWARD_TYPE.LEGACY then
table.insert(newRewards, v)
end
end
for k,v in pairs(items) do
table.insert(newRewards, {type = GConst.REWARD_TYPE.ITEM, id = k, num = v})
end
return newRewards
end
function GFunc.getRandomIndex(weightArr)
if #weightArr <= 0 then
return
end
local maxWeight = 0
for i, v in ipairs(weightArr) do
maxWeight = maxWeight + v
end
local randomWeight = math.random(1, maxWeight)
local idx
for i, v in ipairs(weightArr) do
if randomWeight <= v then
idx = i
break
else
randomWeight = randomWeight - v
end
end
return idx
end
-- function GFunc.getRewardsStr(rewards)
-- if rewards == nil then
-- return
-- end
-- local itemStr = ""
-- for k, v in ipairs(rewards) do
-- if v.type == GConst.REWARD_TYPE.ITEM then
-- itemStr = itemStr .. v.type .. "." .. v.item.cfg_id .. "." .. v.item.count
-- elseif v.type == GConst.REWARD_TYPE.EQUIP then
-- itemStr = itemStr .. v.type .. "." .. v.equip.id .. "." .. v.equip.eid
-- elseif v.type == GConst.REWARD_TYPE.JEWELRY then
-- itemStr = itemStr .. v.type .. "." .. v.jewelry.cfg_id .. "." .. v.jewelry.count
-- end
-- if k ~= #rewards then
-- itemStr = itemStr.. "|"
-- end
-- end
-- return itemStr
-- end
function GFunc.copyStr(str)
CS.UnityEngine.GUIUtility.systemCopyBuffer = str
end
function GFunc.getShakeSeq(obj, onlyKill, originScale, notForcerefresh)
originScale = originScale or 1
if obj.shakeSeq then
if notForcerefresh then
return obj.shakeSeq
end
obj.shakeSeq:Kill()
obj.shakeSeq = nil
end
obj:setLocalScale(originScale, originScale, originScale)
if onlyKill then
return
end
obj.shakeSeq = obj:createBindTweenSequence()
-- obj.shakeSeq:AppendCallback(obj:setLocalEulerAngles(0, 0, 15))
-- obj.shakeSeq:Append(obj:getTransform():DOLocalRotate(BF.Vector3(0, 0, -15), 0.2))
-- obj.shakeSeq:Append(obj:getTransform():DOLocalRotate(BF.Vector3(0, 0, 15), 0.2))
obj.shakeSeq:AppendInterval(2)
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1.12, 0.1))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 0.9, 0.11))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1.1, 0.15))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 0.9, 0.2))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1.05, 0.25))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 0.9, 0.3))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1, 0.3))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale, 0.3))
obj.shakeSeq:SetLoops(-1)
return obj.shakeSeq
end
function GFunc.getShakeSeq2(obj, onlyKill, originScale, notForcerefresh)
originScale = originScale or 1
if obj.shakeSeq then
if not notForcerefresh then
return obj.shakeSeq
end
obj.shakeSeq:Kill()
obj.shakeSeq = nil
end
obj:setLocalScale(originScale, originScale, originScale)
if onlyKill then
return
end
obj.shakeSeq = obj:createBindTweenSequence()
-- obj.shakeSeq:AppendCallback(obj:setLocalEulerAngles(0, 0, 15))
-- obj.shakeSeq:Append(obj:getTransform():DOLocalRotate(BF.Vector3(0, 0, -15), 0.2))
-- obj.shakeSeq:Append(obj:getTransform():DOLocalRotate(BF.Vector3(0, 0, 15), 0.2))
obj.shakeSeq:AppendInterval(1)
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1.12, 0.1))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 0.9, 0.11))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1.1, 0.15))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 0.9, 0.2))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1.05, 0.25))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 0.9, 0.3))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale * 1, 0.3))
obj.shakeSeq:Append(obj:getTransform():DOScale(originScale, 0.3))
obj.shakeSeq:SetLoops(-1)
return obj.shakeSeq
end
---@param obj UIPrefabObject
function GFunc.getShakeSeqRotate(obj, onlyKill, notForcerefresh)
if obj.shakeSeq then
if notForcerefresh then
return obj.shakeSeq
end
obj.shakeSeq:Kill()
obj.shakeSeq = nil
obj:setLocalEulerAngles(0,0,0)
end
if onlyKill then
return
end
---@type UnityEngine.Transform
local objTrans = obj:getTransform()
obj.shakeSeq = obj:createBindTweenSequence()
obj.shakeSeq:AppendInterval(2)
local angle = 12
obj.shakeSeq:Append(objTrans:DORotate({x=0,y=0,z=angle},0.2))
obj.shakeSeq:Append(objTrans:DORotate({x=0,y=0,z=-angle},0.1))
obj.shakeSeq:Append(objTrans:DORotate({x=0,y=0,z=angle},0.1))
obj.shakeSeq:Append(objTrans:DORotate({x=0,y=0,z=-angle},0.07))
obj.shakeSeq:Append(objTrans:DORotate({x=0,y=0,z=angle},0.07))
obj.shakeSeq:Append(objTrans:DORotate({x=0,y=0,z=-angle},0.05))
obj.shakeSeq:SetLoops(-1)
return obj.shakeSeq
end
function GFunc.getScaleQueueAni(root, rewardList, listCell, callBack)
if root.aniSeq then
root.aniSeq:Kill()
root.aniSeq = nil
end
root.aniSeq = root:createBindTweenSequence()
---@type DG.Tweening.Sequence
local seq = root.aniSeq
local groupCell = {}
local index = 1
table.foreach(listCell, function(k, cell)
if groupCell[index] and #groupCell[index] >= 5 then
index = index + 1
end
if not groupCell[index] then
groupCell[index] = {}
end
table.insert(groupCell[index], cell)
end)
---@type UnityEngine.Transform
local rewardListTrans = rewardList:getTransform()
-- ani
table.foreach(groupCell, function(row, cells)
table.foreach(cells, function(k, cell)
---@type SummonRewardCell
local summonRewardCell = cell
local rewardType, id = summonRewardCell:getReward()
summonRewardCell:showMask()
local isNew = summonRewardCell:getIsFirstGet()
local rewardQlt = GFunc.getQuality(rewardType, id)
if rewardQlt and rewardQlt >= 4 and isNew then -- 紫色以上
seq:AppendInterval(0.4)
seq:AppendCallback(function() summonRewardCell:showReward() end)
--seq:Append(rewardListTrans:DOShakePosition(0.4, 14, 18, 90,true)) -- 轻幅度震动
seq:Append(rewardListTrans:DOShakePosition(1, 20, 18, 90,true)) -- 大力震动
else
seq:AppendCallback(function()
summonRewardCell:showReward()
end)
end
end)
seq:AppendInterval(0.1)
end)
seq:AppendCallback(function()
if callBack then
callBack()
end
end)
return seq
end
---@param obj UIPrefabObject
function GFunc.miningTipsMovePosY(obj, delay,callBack)
if obj.seq then
obj.seq:Kill()
obj.seq = nil
end
obj.seq = obj:createBindTweenSequence()
---@type UnityEngine.Transform
local trans = obj:getTransform()
local localPosY = trans.localPosition.y
---@type DG.Tweening.Sequence
local seq = obj.seq
seq:AppendInterval(delay)
seq:Append(trans:DOLocalMoveY(localPosY + 200, 1.2))
seq:AppendCallback(function()
obj:setActive(false)
if callBack then
callBack()
end
end)
end
function GFunc.dataEncrypt(data)
if not VersionCompatible:supportDataEncryptVersion() then
return data
end
local numStr = CS.Security.XXTEA.Encrypt(tostring(data), GConst.SECRET_KEY)
return numStr
end
function GFunc.dataDecrypt(data)
if not VersionCompatible:supportDataEncryptVersion() then
return data
end
local numStr = CS.Security.XXTEA.Decrypt(data, GConst.SECRET_KEY)
return tonumber(numStr)
end
function GFunc.getTickCount()
if not VersionCompatible:supportDataEncryptVersion() then
return 0
end
return math.floor(UnityTime.realtimeSinceStartup)
end
function GFunc.IsGotServerTime()
if not VersionCompatible:supportDataEncryptVersion() then
return true
end
if not CS.BF.BFMain.IsGotServerTime then
return false
end
return true
end
---得到展示奖励的图集名称,图片资源id
function GFunc.getFrameRes(type, id)
if type == GConst.REWARD_TYPE.REWARD_NONE then
return
end
local qlt = 1
local atlasPath = ""
if type == GConst.REWARD_TYPE.ITEM then
local ItemCfg = ConfigManager:getConfig("item")
local config = ItemCfg[id]
if not config then
return
end
qlt = config.qlt
atlasPath = GConst.ATLAS_PATH.ICON_EQUIP
end
if type == GConst.REWARD_TYPE.EQUIP then
local equipCfg = ConfigManager:getConfig("equip")
local config = equipCfg[id]
if not config then
return
end
qlt = config.qlt
atlasPath = GConst.ATLAS_PATH.ICON_EQUIP
end
if type == GConst.REWARD_TYPE.RUNES then
local runeCfg = ConfigManager:getConfig("runes")
local config = runeCfg[id]
if not config then
return
end
qlt = config.qlt
atlasPath = GConst.ATLAS_PATH.ICON_RUNE
end
return atlasPath, GConst.HERO_FRAME[ GConst.QUALITY[qlt] ] or "frame_1", qlt
end
---得到展示奖励的图集名称,图片资源id
function GFunc.getQuality(type, id)
if type == GConst.REWARD_TYPE.REWARD_NONE then
return
end
local qlt = 1
if type == GConst.REWARD_TYPE.ITEM then
local ItemCfg = ConfigManager:getConfig("item")
local config = ItemCfg[id]
if not config then
return
end
qlt = config.qlt
end
if type == GConst.REWARD_TYPE.EQUIP then
local equipCfg = ConfigManager:getConfig("equip")
local config = equipCfg[id]
if not config then
return
end
qlt = config.qlt
end
if type == GConst.REWARD_TYPE.LEGACY then
local equipCfg = ConfigManager:getConfig("legacy")
local config = equipCfg[id]
if not config then
return
end
qlt = config.qlt
end
if type == GConst.REWARD_TYPE.RUNES then
local runeCfg = ConfigManager:getConfig("runes")
local config = runeCfg[id]
if not config then
return
end
qlt = config.qlt
end
return qlt
end
---得到展示奖励的图集名称,图片资源id
function GFunc.getRewardIconRes(type, id)
if type == GConst.REWARD_TYPE.REWARD_NONE then
return
end
if type == GConst.REWARD_TYPE.ITEM then
return GFunc.getIconRes(id)
end
if type == GConst.REWARD_TYPE.EQUIP then
return GFunc.getEquipIconRes(id)
end
if type == GConst.REWARD_TYPE.RUNES then
return GFunc.getRuneIconRes(id)
end
if type == GConst.REWARD_TYPE.LEGACY then
return GFunc.getLegacyIconRes(id)
end
end
function GFunc.getIconRes(itemId)
local ItemCfg = ConfigManager:getConfig("item")
local config = ItemCfg[itemId]
if not config then
return
end
return GConst.ATLAS_PATH.ICON_ITEM, tostring(config.icon)
end
function GFunc.getEquipIconRes(equipId)
local EquipCfg = ConfigManager:getConfig("equip")
local config = EquipCfg[equipId]
if not config then
return
end
return GConst.ATLAS_PATH.ICON_EQUIP, tostring(config.icon)
end
function GFunc.getRuneIconRes(runeId)
local runeCfg = ConfigManager:getConfig("runes")
local config = runeCfg[runeId]
if not config then
return
end
return GConst.ATLAS_PATH.ICON_RUNE, tostring(config.icon)
end
function GFunc.getLegacyIconRes(legacyId)
local legacyCfg = ConfigManager:getConfig("legacy")
local config = legacyCfg[legacyId]
if not config then
return
end
return GConst.ATLAS_PATH.ICON_LEGACY, tostring(config.icon)
end
---得到展示奖励的图集名称,图片资源id
function GFunc.getRewardName(type, id)
if type == GConst.REWARD_TYPE.REWARD_NONE then
return
end
if type == GConst.REWARD_TYPE.ITEM then
return I18N:getText("item", id, "name")
end
if type == GConst.REWARD_TYPE.EQUIP then
return I18N:getText("equip", id, "desc")
end
if type == GConst.REWARD_TYPE.RUNES then
return I18N:getText("rune", id, "desc")
end
end
function GFunc.performDurationDelay(obj, delay, callback)
if obj.sequence then
obj.sequence:Kill()
obj.sequence = nil
end
local sequence = obj:createBindTweenSequence()
delay = delay or 0
delay = math.max(0, delay)
obj.sequence = sequence
sequence:AppendInterval(delay or 0)
sequence:OnComplete(callback)
return sequence
end
function GFunc.compareVersionThan(version1, version2, include)
if not version1 or not version2 then
return false
end
local versionStrs = string.split(version1, ".")
local versionNum1 = tonumber(versionStrs[1])
local versionNum2 = tonumber(versionStrs[2])
local versionNum3 = tonumber(versionStrs[3])
local versionStrs2 = string.split(version2, ".")
local versionNum21 = tonumber(versionStrs2[1])
local versionNum22 = tonumber(versionStrs2[2])
local versionNum23 = tonumber(versionStrs2[3])
if not versionNum1 or not versionNum2 or not versionNum3 or not versionNum21 or not versionNum22 or not versionNum23 then
return false
end
if versionNum1 > versionNum21 then
return true, true
elseif versionNum1 < versionNum21 then
return false
end
if versionNum2 > versionNum22 then
return true, true
elseif versionNum2 < versionNum22 then
return false
end
if versionNum3 > versionNum23 then
return true
elseif versionNum3 < versionNum23 then
return false
end
if include then
return true
end
return false
end
function GFunc.getFormatCfgRewards(rewards, onlyOne)
local cfgRewards = GFunc.getArray()
for _, reward in ipairs(rewards) do
local cfgReward = {
type = reward.type,
id = reward.id,
count = {
value = reward.count.value,
unit = reward.count.unit,
},
}
if onlyOne then
return cfgReward
else
table.insert(cfgRewards, reward)
end
end
return cfgRewards
end
function GFunc.getUpdateDataMap(fnName, dataName, dataMap, costs, rewards, fnArgs)
local params = {
fnName = fnName,
dataType = dataName,
data = dataMap,
costs = costs or GFunc.getArray(),
rewards = rewards or GFunc.getArray(),
fnArgs = fnArgs
}
return params
end
function GFunc.isShenhe()
return CS.BF.BFMain.IsShenhe
end
function GFunc.getArray()
local array = {}
setmetatable(array, {__jsontype = "array"})
return array
end
function GFunc.showProbability()
local language = I18N:getCurLanguage()
if language == "ko" or language == "ja" then
return true
end
return false
end
function GFunc.getTable(struct)
local t = {}
if struct then
for k, v in pairs(struct) do
if type(v) == "table" then
t[k] = GFunc.getTable(v)
else
t[k] = v
end
end
end
return t
end
function GFunc.formatTimeStep(timestep)
if timestep and timestep > 10000000000 then
timestep = timestep // 1000
end
return timestep
end
function GFunc.randomPos(idx, pos)
local posX, posY
if idx == 1 then
posX = math.random(-50, 0)
posY = math.random(0, 50)
elseif idx == 2 then
posX = math.random(0, 50)
posY = math.random(0, 50)
elseif idx == 3 then
posX = math.random(-50, 0)
posY = math.random(-50, 0)
elseif idx == 4 then
posX = math.random(0, 50)
posY = math.random(-50, 0)
else
posX = math.random(-50, 50)
posY = math.random(-50, 50)
end
return posX + pos.x, posY + pos.y
end
function GFunc.imgFly(flyImg, beginPos, endPos, callback)
if flyImg.aniSeq then
flyImg.aniSeq:Kill()
end
local scale = 0.5
flyImg:setAnchoredPosition(beginPos.x, beginPos.y)
flyImg:setVisible(true, 0.1)
local maxDis = 2000
local dis = BF.Vector2Distance(beginPos, endPos)
local time = dis/maxDis
local aniSeq = flyImg:createBindTweenSequence()
-- aniSeq:Append(flyImg:getTransform():DOScale(BF.Vector3(scale + 0.2, scale + 0.2, scale + 0.2), 0.1):SetEase(CS.DG.Tweening.Ease.InCubic))
aniSeq:Append(flyImg:getTransform():DOScale(BF.Vector3(scale, scale, scale), 0.04):SetEase(CS.DG.Tweening.Ease.InCubic))
-- aniSeq:AppendInterval(0.3)
aniSeq:Append(flyImg:getTransform():DOAnchorPos(endPos, time):SetEase(CS.DG.Tweening.Ease.InCubic))
aniSeq:Join(flyImg:getTransform():DOScale(BF.Vector3(0.1, 0.1, 0.1), time):SetEase(CS.DG.Tweening.Ease.InCubic))
aniSeq:AppendCallback(function()
flyImg:setVisible(false)
if callback then
callback()
end
end)
flyImg.aniSeq = aniSeq
end
function GFunc.doScaleFlyImg(img, callback)
if img.aniSeq then
img.aniSeq:Kill()
img:setLocalScale(1, 1, 1)
end
local transform = img:getTransform()
local localScale = transform.localScale
local scale = localScale.x
local aniSeq = img:createBindTweenSequence()
aniSeq:Append(img:getTransform():DOScale(BF.Vector3(scale + 0.1, scale + 0.1, scale + 0.1), 0.08):SetEase(CS.DG.Tweening.Ease.InCubic))
aniSeq:Append(img:getTransform():DOScale(BF.Vector3(scale - 0.08, scale - 0.08, scale - 0.08), 0.08):SetEase(CS.DG.Tweening.Ease.InCubic))
aniSeq:Append(img:getTransform():DOScale(BF.Vector3(scale, scale, scale), 0.08):SetEase(CS.DG.Tweening.Ease.InCubic))
aniSeq:AppendCallback(function()
if callback then
callback()
end
end)
img.aniSeq = aniSeq
end
function GFunc.doScaleQuickZoom(img,callback)
if img.aniSeq then
img.aniSeq:Kill()
end
---@type UnityEngine.Transform
local transform = img:getTransform()
local localScale = transform.localScale
local scale = 1
---@type DG.Tweening.Sequence
local aniSeq = img:createBindTweenSequence()
aniSeq:Append(transform:DOScale(1.4, 0.1))
aniSeq:Append(transform:DOScale(1, 0.06))
aniSeq:AppendCallback(function()
if callback then
callback()
end
end)
img.aniSeq = aniSeq
end
-- colorType 1 白色, 2 黑色
function GFunc.setAdsSprite(img, isGrey, colorType)
if not img then
return
end
colorType = colorType or 1
local skip = DataManager.MallActData:skipAd()
local icon = ""
if colorType == 1 then
icon = skip and "common_ad_4" or "common_ad_3"
end
if colorType == 2 then
icon = skip and "common_ad_2" or "common_ad_1"
end
if isGrey then
icon = skip and "common_ad_6" or "common_ad_5"
end
img:setSprite(GConst.ATLAS_PATH.COMMON, icon)
--img:setSprite(GConst.ATLAS_PATH.COMMON, icon, function ()
-- img:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_IMAGE):SetNativeSize()
--end)
end
function GFunc.getAdSprite()
local skip = DataManager.MallActData:skipAd()
return skip and "common_ad_4" or "common_ad_3"
end
function GFunc.centerImgAndTx(imgObj, txObj, spacing, offset)
spacing = spacing or 0
offset = offset or 0
local imgW = imgObj:getSizeDelta().x
local txW = txObj:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO).preferredWidth
txObj:setSizeDeltaX(txW)
local w = (imgW + txW + spacing) / 2
imgObj:setAnchoredPositionX(imgW / 2 - w + offset)
txObj:setAnchoredPositionX(w - txW / 2 + offset)
end
function GFunc.centerTxAndTx(txObj1, txObj2, spacing)
spacing = spacing or 0
local txW = txObj1:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO).preferredWidth
txObj1:setSizeDeltaX(txW)
local txW2 = txObj2:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO).preferredWidth
txObj2:setSizeDeltaX(txW2)
local w = (txW2 + txW + spacing) / 2
txObj1:setAnchoredPositionX(txW / 2 - w)
txObj2:setAnchoredPositionX(w - txW2 / 2)
end
function GFunc.expandImgToFitTx(imgObj, txObj, spacing)
spacing = spacing or 0
local txW = txObj:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO).preferredWidth
txObj:setSizeDeltaX(txW)
imgObj:setSizeDeltaX(txW + spacing * 2)
end
function GFunc.formatAdImg(adImg)
if DataManager.MonthlyData:skipAd() then
adImg:setSprite(GConst.ATLAS_PATH.COMMON, "common_ad_1")
else
adImg:setSprite(GConst.ATLAS_PATH.COMMON, "common_ad")
end
end
function GFunc.organizeCfg(cfgId, cfg)
local result = {}
result.cfgId = cfgId
result.cfg = cfg
return result
end
function GFunc.gemEnough(needNum,showToast) -- 钻石是否足够
return GFunc.checkCost(GConst.ItemConst.ITEM_ID_GEM, needNum, showToast) --判断不提示,点击才提示
end
function GFunc.getCostContentWithColor(key)
local cost = GFunc.getConstIntValue(key)
local content = ""..cost..""
local bigNum = {
unit = 0,
value = cost
}
if GFunc.gemEnough(bigNum, false) then
content = tostring(cost)
end
return content
end
---@param txtObj UIPrefabObject 文本对象
---@param icon UIPrefabObject 图片对象
---@param bgImg UIPrefabObject 背景图片
---设置图片和文本居中, 文本需要左右居中对齐
function GFunc.setMiddlePosX(txtObj, icon, bgImg)
local txtRectWidth = txtObj:getTransform().rect.width
local iconRectWidth = icon:getTransform().rect.width
local bgImgRectWidth = bgImg:getTransform().rect.width
local halfBgWidth = bgImgRectWidth * 0.5
-- 文本的宽度
local meshPro = txtObj:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO)
local width = meshPro.preferredWidth
local txtMinWidth = math.max(width, txtRectWidth)
-- 以bg中心点为锚点时
-- 文本距离边界的距离
local txtPadding = halfBgWidth - txtMinWidth
txtPadding = txtPadding > 0 and txtPadding or 0
-- 图片距离边界距离
local iconPadding = halfBgWidth - iconRectWidth
iconPadding = iconPadding > 0 and iconPadding or 0
local maxPadding = math.max(txtPadding, iconPadding)
local minPadding = math.min(txtPadding, iconPadding)
local offset = (maxPadding - minPadding) * 0.5
if txtPadding > iconPadding then
txtObj:setAnchoredPositionX(txtMinWidth * 0.5 + offset)
icon:setAnchoredPositionX(-iconRectWidth * 0.5 + offset)
else
txtObj:setAnchoredPositionX(txtMinWidth * 0.5 - offset)
icon:setAnchoredPositionX(-iconRectWidth * 0.5 - offset)
end
end
---计算最小值
function GFunc.getCalcMinVal(arr)
local min = arr[1]
for i, v in ipairs(arr) do
if min > v then
min = v
end
end
return min
end
---计算最大值
function GFunc.getCalcMaxVal(arr)
local max = arr[1] or 0
for i, v in ipairs(arr) do
if max < v then
max = v
end
end
return max
end
function GFunc.getRewardTableByRewardList(rewardList)
local newRewards = {}
for _, reward in ipairs(rewardList) do
table.insert(newRewards, reward)
end
return newRewards
end
function GFunc.getRewardTableByReward(reward)
return GFunc.getRewardTable(reward.type, reward.id, reward.count)
end
function GFunc.getRewardTable(type, id, count)
if type == GConst.REWARD_TYPE.EQUIP then
return GFunc.getServerEquipRewardTable(id, count)
end
return {
type = type,
id = id,
count = {
unit = count.unit,
value = count.value,
}
}
end
function GFunc.formatRewardsToServerStruct(rewardList)
local rewards = {}
for _, reward in ipairs(rewardList) do
local serverReward = GFunc.getServerRewardTable(reward.type, reward.id, reward.count)
table.insert(rewards, serverReward)
end
return rewards
end
function GFunc.getServerRewardTable(type, id, count)
if type == GConst.REWARD_TYPE.ITEM then
return GFunc.getServerItemRewardTable(id, count)
elseif type == GConst.REWARD_TYPE.RUNES then
return GFunc.getServerRuneRewardTable(id, BigNumOpt.bigNum2Num(count))
elseif type == GConst.REWARD_TYPE.EQUIP then
return GFunc.getServerEquipRewardTable(id, count)
end
end
function GFunc.getServerItemRewardTable(id, count)
local reward = {
type = GConst.REWARD_TYPE.ITEM,
item = {
id = id,
count = {
unit = count.unit,
value = count.value,
}
},
}
BigNumOpt.adjustRealBigNum(reward.item.count)
return reward
end
function GFunc.getServerRuneRewardTable(id, level)
return {
type = GConst.REWARD_TYPE.RUNES,
rune = {
id = id,
level = level,
},
}
end
function GFunc.getServerEquipRewardTable(id, level, count)
local reward = {
type = GConst.REWARD_TYPE.EQUIP,
equip = {
id = id,
level = level,
count = count
},
}
return reward
end
function GFunc.checkTableValueSame(standardTable, compareTable, debug)
if type(standardTable) ~= "table" or type(compareTable) ~= "table" then
if debug and standardTable ~= compareTable then
Logger.logHighlight(standardTable)
end
return standardTable == compareTable
end
for k, v in pairs(standardTable) do
local v2 = compareTable[k]
if v2 == nil then
if debug then
Logger.logHighlight(k)
end
return false
end
if not GFunc.checkTableValueSame(v, v2, debug) then
return false
end
end
return true
end
function GFunc.getRealItemAddChange(itemId, bigNum)
local hadBigNum = DataManager.BagData.ItemData:getItemBigNumById(itemId)
local addBigNum = BigNumOpt.bigNumAdd(hadBigNum, bigNum)
return BigNumOpt.bigNumSub(addBigNum, hadBigNum)
end
function GFunc.getRealItemSubChange(itemId, bigNum)
local hadBigNum = DataManager.BagData.ItemData:getItemBigNumById(itemId)
local subBigNum = BigNumOpt.bigNumSub(hadBigNum, bigNum)
return BigNumOpt.bigNumSub(hadBigNum, subBigNum)
end
-- 获取挖矿研究得到的属性加成
function GFunc.getMainHeroAttributeVal(key)
local mainEntity = DataManager.HeroData:getMainHeroEntity()
local allAttr = mainEntity:getAllAttr()
local result = allAttr[key]
return result
end
function GFunc.checkAttrWhitServerAttr()
if not DataManager.serverAttr or (not DataManager.serverAttr.attr_set) then
return
end
table.foreach(DataManager.serverAttr.attr_set, function(id, val)
local playerAttr = GFunc.getMainHeroAttributeVal(id)
if not playerAttr then
Logger.logHighlight("玩家没有属性:"..id)
return
end
--playerAttr = BigNumOpt.bigNumDivNum(playerAttr, 10000)
if BigNumOpt.bigNumCompare(playerAttr, val) ~= 0 then
Logger.logError("属性不一致!ID:"..id.." PlayerVal:"..BigNumOpt.bigNum2Str(playerAttr).." ServerVal:"..BigNumOpt.bigNum2Str(val))
else
Logger.logHighlight("属性一致:ID"..id.." val: "..BigNumOpt.bigNum2Str(val))
end
end)
end
function GFunc.showCurrencyFlyAction(rewards, pos)
local flyPos = {}
if not pos then
pos = {x = 0, y = 0}
else
local sPoint = UIManager:getUICameraComponent():WorldToScreenPoint(pos)
pos = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(UIManager:getMainCanvasTransform(), sPoint.x, sPoint.y, UIManager:getUICameraComponent())
end
for i, reward in ipairs(rewards) do
if reward.type == GConst.REWARD_TYPE.ITEM then
local allPos = {}
for i = 1, 4 do
local posX, posY = GFunc.randomPos(i, pos)
allPos[i] = {x = posX, y = posY}
end
flyPos[reward.item.id] = allPos
end
end
UIManager:showCurrencyAction(flyPos)
end
function GFunc.getItemRewardNum(reward)
local type = ConfigManager:getConfig("item")[reward.id].type
if type == 6 then
return BigNumOpt.bigNum2Num(reward.count)
end
return BigNumOpt.bigNum2Str(reward.count)
end
function GFunc.getSkillEffectStr(id, lv)
local str = I18N:getText("skill", id, "desc")
local cfg = ConfigManager:getConfig("skill")[id]
local baseNum = cfg.string_num_base
local growNum = cfg.string_num_grow
local tab = {}
for i,v in ipairs(baseNum) do
table.insert(tab, baseNum[i] + (lv - 1)*growNum[i])
end
local idx = 0
str = string.gsub(str, '{%d+}', function (s)
idx = idx + 1
return tostring(tab[idx])
end)
return str
end
--[[
设置tabLe只速 出现改写会抛出Lua error
用法locaL readOnlyCfg = GFunc.readOnlyTab(cfg) return readOnlyCfg
增加了防重置设置read_onLy的机制
Lua5.3支持 1) table库支持调用元方法,所以table.remove table.insert也会抛出错误,
2)不用定义_ipairs 5.3 ipairs迭代器支持访问元方法__index,pairs迭代器next不支持故需要元方法_pairs
低版本Lua此网数不能完全按照预期工作
]]
function GFunc.readOnlyTab(inputTable)
local travelled_tables = {}
local function _read_only(tbl)
if not travelled_tables[tbl] then
local tbl_mt = getmetatable(tbl)
if not tbl_mt then
tbl_mt = {}
setmetatable(tbl, tbl_mt)
end
local proxy = tbl_mt._read_only__proxy
if not proxy then
proxy = {}
tbl_mt.__read_only_proxy = proxy
local proxy_mt = {
__index = tbl,
__newindex = function (t, k, v) error( "error write to a read-only table with key = " .. tostring(k)) end,
__pairs = function (t) return pairs(tbl) end,
-- __ipairs = function (t) return ipairs(tbl) end, 5.3版本不需要此方法
_len = function (t) return #tbl end,
__read_only_proxy = proxy
}
setmetatable(proxy, proxy_mt)
end
travelled_tables[tbl] = proxy
for k, v in pairs(tbl) do
if type(v) == "table" then
tbl[k] = _read_only(v)
end
end
end
return travelled_tables[tbl]
end
return _read_only(inputTable)
end
function GFunc.getItemNumStr(itemID)
local bigNum = DataManager.BagData.ItemData:getItemBigNumById(itemID)
local itemCfg = ConfigManager:getConfig("item")[itemID]
if itemCfg.type == 6 then
return BigNumOpt.bigNum2Num(bigNum)
end
return BigNumOpt.bigNum2Str(bigNum)
end
return GFunc