c1_lua/lua/app/global/global_func.lua
2023-08-03 14:53:51 +08:00

1820 lines
47 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local GFunc = {}
local EMPTY_TABLE = {}
local TEMP_LIST = {}
local TEMP_MAP = {}
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.showToast(params)
ModuleManager.ToastManager:showToast(params)
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.getPerStr(key, str)
if key == GConst.BattleConst.BUFF_NAME.ATKP_ADD or
key == GConst.BattleConst.BUFF_NAME.ATKP_COLOR_ADD or
key == GConst.BattleConst.BUFF_NAME.ATKP_RED_ADD or
key == GConst.BattleConst.BUFF_NAME.ATKP_YELLOW_ADD or
key == GConst.BattleConst.BUFF_NAME.ATKP_GREEN_ADD or
key == GConst.BattleConst.BUFF_NAME.ATKP_BLUE_ADD or
key == GConst.BattleConst.BUFF_NAME.ATKP_PURPLE_ADD or
key == GConst.BattleConst.BUFF_NAME.DEC_DMG_RED_ADD or
key == GConst.BattleConst.BUFF_NAME.DEC_DMG_YELLOW_ADD or
key == GConst.BattleConst.BUFF_NAME.DEC_DMG_GREEN_ADD or
key == GConst.BattleConst.BUFF_NAME.DEC_DMG_BLUE_ADD or
key == GConst.BattleConst.BUFF_NAME.DEC_DMG_PURPLE_ADD or
key == GConst.BattleConst.BUFF_NAME.DEC_DMG_ALL_ADD or
key == GConst.BattleConst.BUFF_NAME.WEAKNESS_RED_ADD or
key == GConst.BattleConst.BUFF_NAME.WEAKNESS_YELLOW_ADD or
key == GConst.BattleConst.BUFF_NAME.WEAKNESS_GREEN_ADD or
key == GConst.BattleConst.BUFF_NAME.WEAKNESS_BLUE_ADD or
key == GConst.BattleConst.BUFF_NAME.WEAKNESS_PURPLE_ADD or
key == GConst.BattleConst.BUFF_NAME.WEAKNESS_ALL_ADD or
key == GConst.BattleConst.BUFF_NAME.DMG_ADDITION_RED_ADD or
key == GConst.BattleConst.BUFF_NAME.DMG_ADDITION_YELLOW_ADD or
key == GConst.BattleConst.BUFF_NAME.DMG_ADDITION_GREEN_ADD or
key == GConst.BattleConst.BUFF_NAME.DMG_ADDITION_BLUE_ADD or
key == GConst.BattleConst.BUFF_NAME.DMG_ADDITION_PURPLE_ADD or
key == GConst.BattleConst.BUFF_NAME.DMG_ADDITION_ALL_ADD or
key == GConst.BattleConst.BUFF_NAME.HPP_ADD or
key == GConst.BattleConst.BUFF_NAME.CRIT_TIME_ADD or
key == GConst.BattleConst.BUFF_NAME.EXP_TIME_ADD or
key == GConst.BattleConst.BUFF_NAME.CURED_ADD or
key == GConst.BattleConst.BUFF_NAME.POISON or
key == GConst.BattleConst.BUFF_NAME.SHIELD or
key == GConst.BattleConst.BUFF_NAME.SHIELD_REBOUND_200 or
key == GConst.BattleConst.BUFF_NAME.VULNERABLE or
key == GConst.BattleConst.BUFF_NAME.CORRUPT or
key == GConst.BattleConst.BUFF_NAME.BLEED or
key == GConst.BattleConst.BUFF_NAME.WEAKEN or
key == GConst.BattleConst.BUFF_NAME.COUNTER_ATTACK or
key == GConst.BattleConst.BUFF_NAME.THORNS or
key == GConst.BattleConst.BUFF_NAME.SHIELD_REBOUND_400 or
key == GConst.BattleConst.BUFF_NAME.SHIELD_ICE_REBOUND_400 or
key == GConst.BattleConst.BUFF_NAME.BURN or
key == GConst.BattleConst.BUFF_NAME.SHIELD_ICE or
key == GConst.BattleConst.BUFF_NAME.SHIELD_ICE_02 or
key == GConst.BattleConst.BUFF_NAME.BLOCK or
key == GConst.BattleConst.BUFF_NAME.CRIT_ADD
then
str = str // 100 .. "%"
end
return str
end
function GFunc.getBuffDesc(buffName, effectNum)
effectNum = GFunc.getPerStr(buffName, effectNum)
return I18N:getTextWithOtherKey("buff", "name", buffName, "desc", effectNum)
end
function GFunc.getAttrDesc(attrName, attrNum)
attrNum = attrNum // 100
return I18N:getTextWithOtherKey("attr", "name", attrName, "desc", attrNum)
end
function GFunc.getAttrName(key)
return I18N:getText("attr", key, "name")
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.getTimeWithHMS(time)
local h = math.floor(time/3600)
local m = math.floor((time%3600)/60)
local s = time%60
return 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.getTimeStrWithDHM(time)
local d = math.floor(time/86400)
local h = math.floor((time%86400)/3600)
local m = math.floor((time%3600)/60)
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_DHM, d, h, m)
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.getConstReward(key)
local ConstCfg = ConfigManager:getConfig("const")
return ConstCfg[key] and ConstCfg[key].reward
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
if itemId == GConst.ItemConst.ITEM_ID_GOLD then
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.GOTO_COIN_STORE_DESC),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
okFunc = function()
UIManager:closeAllUIExceptMainUI()
EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.GO_SHOP, {page = GConst.ShopConst.PAGE_TYPE.MAIN, subType = GConst.ShopConst.MAIN_PAGE_TYPE.GOLD})
end
}
GFunc.showMessageBox(params)
end
end
function GFunc.checkCost(id, num, showToast)
if num <= 0 then
return true
end
local count = DataManager.BagData.ItemData:getItemNumById(id)
if count < num then
if showToast then
GFunc.showItemNotEnough(id)
end
return false
else
return true
end
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)
-- 根据类型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
EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.GETED_REWARD_SUCCESS, newRewards)
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 + v.item.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
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, true)
else
newRewards = rewards
end
params.rewards = newRewards
params.callback = callback
ModuleManager.TipsManager:showRewardsBox(params)
AudioManager:playEffect(AudioManager.EFFECT_ID.REWARD)
end
function GFunc.mergeRewards2(rewards, newRewards, needSort)
local items = {}
for i,v in ipairs(rewards) do
if v.type == GConst.REWARD_TYPE.ITEM then
items[v.item.id] = (items[v.item.id] or 0) + v.item.count
elseif v.type == GConst.REWARD_TYPE.EQUIP 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
if needSort then
GFunc.sortRewards(newRewards)
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.id .. "." .. v.item.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: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: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
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
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()
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)
local rewardListTrans = rewardList:getTransform()
-- ani
table.foreach(groupCell, function(row, cells)
table.foreach(cells, function(k, cell)
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
function GFunc.miningTipsMovePosY(obj, delay,callBack)
if obj.seq then
obj.seq:Kill()
obj.seq = nil
end
obj.seq = obj:createBindTweenSequence()
local trans = obj:getTransform()
local localPosY = trans.localPosition.y
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)
local numStr = CS.Security.XXTEA.Encrypt(tostring(data), GConst.SECRET_KEY)
return numStr
end
function GFunc.dataDecrypt(data)
local numStr = CS.Security.XXTEA.Decrypt(data, GConst.SECRET_KEY)
return tonumber(numStr)
end
function GFunc.getTickCount()
return math.floor(UnityTime.realtimeSinceStartup)
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.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.isInWhitelist()
return CS.BF.BFMain.IsWhite
end
function GFunc.getArray()
local array = {}
setmetatable(array, {__jsontype = "array"})
return array
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
local transform = img:getTransform()
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)
if not img then
return
end
local skip = false -- DataManager.MallActData:skipAd()
local icon = nil
if isGrey then
icon = skip and "common_ad_6" or "common_ad_5"
else
icon = skip and "common_ad_4" or "common_ad_3"
end
img:setSprite(GConst.ATLAS_PATH.COMMON, icon)
end
function GFunc.getAdSprite()
local skip = false --DataManager.MallActData:skipAd()
return skip and "common_ad_4" or "common_ad_3"
end
function GFunc.centerImgAndTx(imgObj, txObj, spacing, offset, txMaxWidth)
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
-- 文字最大宽度处理
if txMaxWidth and txW > txMaxWidth then
txW = txMaxWidth
end
txObj:setSizeDeltaX(txW)
local w = (imgW + txW + spacing) / 2
imgObj:setAnchoredPositionX(imgW / 2 - w + offset)
txObj:setAnchoredPositionX(w - txW / 2 + offset)
end
-- centerImgAndTx的位置反向版本
function GFunc.centerTxAndImg(txObj, imgObj, 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
txObj:setAnchoredPositionX(txW / 2 - w + offset)
imgObj:setAnchoredPositionX(w - imgW / 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.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 = count
}
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)
end
end
function GFunc.getServerItemRewardTable(id, count)
local reward = {
type = GConst.REWARD_TYPE.ITEM,
item = {
id = id,
count = 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.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.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
function GFunc.goTargetElasticityY(obj, onlyKill, offset, punchY, callBack)
if obj.shakeSeq then
obj.shakeSeq:Kill()
obj.shakeSeq = nil
end
if onlyKill then
return
end
local curPosY = obj:getAnchoredPositionY()
local objTrans = obj:getTransform()
obj.shakeSeq = obj:createBindTweenSequence()
obj.shakeSeq:Append(objTrans:DOLocalMoveY(curPosY - offset / 2,0.1))
obj.shakeSeq:Append(objTrans:DOLocalMoveY(curPosY + offset * 2 ,0.1))
obj.shakeSeq:Join(objTrans:DOPunchScale({x=0,y=punchY,z = 0},0.2, 6))
obj.shakeSeq:AppendCallback(function()
if callBack then
callBack()
end
end)
return obj.shakeSeq
end
function GFunc.goTargetPosXShake(obj, onlyKill, targetX, offset, callBack)
if obj.shakeSeq then
obj.shakeSeq:Kill()
obj.shakeSeq = nil
end
if onlyKill then
return
end
obj.shakeSeq = obj:createBindTweenSequence()
local objTrans = obj:getTransform()
local seq = obj.shakeSeq
seq:Append(objTrans:DOLocalMoveX(targetX,0.12))
seq:Append(objTrans:DOLocalMoveX(targetX + offset,0.1))
seq:Append(objTrans:DOLocalMoveX(targetX - offset / 3,0.05))
seq:Append(objTrans:DOLocalMoveX(targetX, 0.1))
seq:AppendCallback(function()
if callBack then
callBack()
end
end)
return obj.shakeSeq
end
function GFunc.getRewardId(reward)
if reward.id_for_nothing then
return CS.BF.Utils.GetRewardNumber(reward.id_for_nothing)
else
return reward.id
end
end
function GFunc.getRewardNum(reward)
if reward.num_for_nothing then
return CS.BF.Utils.GetRewardNumber(reward.num_for_nothing)
else
return reward.num or reward.count
end
end
function GFunc.getRewardType(reward)
if reward.type_for_nothing then
return CS.BF.Utils.GetRewardNumber(reward.type_for_nothing)
else
return reward.type
end
end
function GFunc.DOBFSliderValue(slider, endValue, duration, snapping)
return CS.BF.Utils.DOBFSliderValue(slider, endValue, duration, snapping)
end
function GFunc.intToString(int)
return GConst.INT_TO_STRING[int] or tostring(int)
end
function GFunc.getTempList()
for i = 1, #TEMP_LIST do
table.remove(TEMP_LIST)
end
return TEMP_LIST
end
function GFunc.recycleTempList()
for i = 1, #TEMP_LIST do
table.remove(TEMP_LIST)
end
end
function GFunc.getTempMap()
for k, v in pairs(TEMP_MAP) do
TEMP_MAP[k] = nil
end
return TEMP_MAP
end
function GFunc.recycleTempMap()
for k, v in pairs(TEMP_MAP) do
TEMP_MAP[k] = nil
end
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迭代器支持访问元方法__indexpairs迭代器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.encryptNumber(value)
return value + GConst.NUMBER_ENCRYPTION_CONSTANT
end
function GFunc.decryptNumber(value)
return value - GConst.NUMBER_ENCRYPTION_CONSTANT
end
function GFunc.formatPlayerName(name)
if name == nil or #name == 0 then
name = I18N:getGlobalText(I18N.GlobalConst.NEW_PLAYER)
end
return name
end
-- info = {array_heroes, heroes_equips} -- 服务器返回的数据
function GFunc.formatPlayerFormationInfo(info)
local formation = {}
if not info.array_heroes then
return formation
end
for index, info in ipairs(info.array_heroes) do
if DataManager.HeroData:isExistHeroById(info.id) then
local heroEntity = DataManager.HeroData:getEntity(info)
formation[heroEntity:getMatchType()] = heroEntity
end
end
-- 处理装备
if not info.heroes_equips then
info.heroes_equips = {}
end
for matchType, heroEntity in pairs(formation) do
local heroId = heroEntity:getCfgId()
local equipInfo = info.heroes_equips[heroId]
local equips = {}
if not equipInfo then
equipInfo = {equips = {}}
end
for partName, partType in pairs(GConst.EquipConst.PART_TYPE) do
local level = equipInfo.equips[partType] or 0
local equipEntity = DataManager.EquipData:createEntity(heroId, partType, level)
equips[partType] = equipEntity
equipEntity:setHeroEntity(heroEntity)
end
heroEntity:setEquips(equips)
end
return formation
end
return GFunc