源战役客户端
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

4023 行
113 KiB

local LuaEventListener = LuaEventListener
local LuaClickListener = LuaClickListener
local LuaDragListener = LuaDragListener
local LuaDragExtendListener = LuaDragExtendListener
local Application = Application
local GameObject = GameObject
local Util = Util
local table_insert = table.insert
local unpack = unpack
local is_50_version = EnglineVersion and AppConst_EnglineVer >= 50
local is_52_version = EnglineVersion and AppConst_EnglineVer >= 52
local is_61_version = EnglineVersion and AppConst_EnglineVer >= 61
--判断游戏对象是否已经被销毁为 null
function IsNull(obj)
if obj == nil or obj == false then return true end
return Util.Equals(obj, nil)
end
function GetChildTransforms(transform, names)
if transform then
local childs = {}
if is_52_version then
local objs = Util.GetChildTransforms(transform, names)
for i = 0,objs.Length - 1 do
table_insert(childs, objs[i])
end
else
for i = 1, #names do
table_insert(childs, transform:FindChild(names[i]))
end
end
return unpack(childs)
end
end
function GetChildGameObjects(transform, names)
if transform then
local childs = {}
if is_52_version then
local objs = Util.GetChildGameObjects(transform, names)
for i = 0,objs.Length - 1 do
table_insert(childs, objs[i])
end
else
for i = 1, #names do
table_insert(childs, transform:FindChild(names[i]).gameObject)
end
end
return unpack(childs)
end
end
function GetChildImages(transform, names)
if transform then
local childs = {}
if is_52_version then
local objs = Util.GetChildImages(transform, names)
for i = 0,objs.Length - 1 do
table_insert(childs, objs[i])
end
else
for i = 1, #names do
table_insert(childs, transform:FindChild(names[i]):GetComponent("Image"))
end
end
return unpack(childs)
end
end
function GetChildTexts(transform, names)
if transform then
local childs = {}
if is_52_version then
local objs = Util.GetChildTexts(transform, names)
for i = 0,objs.Length - 1 do
table_insert(childs, objs[i])
end
else
for i = 1, #names do
table_insert(childs, transform:FindChild(names[i]):GetComponent("Text"))
end
end
return unpack(childs)
end
end
--打印方法的调用位置
function PrintFunctionCallPos(function_name, stack_layer)
if RuntimePlatform and (SystemRuntimePlatform.IsAndroid() or SystemRuntimePlatform.IsIphone()) then
return
end
local create_info = debug.getinfo(stack_layer or 3, "Sl")
local print_msg = ""
if create_info then
function_name = function_name or ""
print_msg = string.format("%s calledPos = %s[%d]",function_name, create_info.source,create_info.currentline)
print(print_msg)
end
return print_msg
end
function NewTable()
PrintFunctionCallPos("NewTable")
return {}
end
--输出报错栈
function TraceBack(str)
if RuntimePlatform and (SystemRuntimePlatform.IsAndroid() or SystemRuntimePlatform.IsIphone()) then
return
end
if str then
LogError("error_reason is: ".. str .. debug.traceback("", 2))
else
LogError(debug.traceback("", 2))
end
end
function tracebackex()
local ret = ""
local level = 3
ret = ret .. "stack traceback:\n"
-- while true do
--get stack info
local info = debug.getinfo(level, "Sln")
if not info then return end
if info.what == "C" then -- C function
ret = ret .. tostring(level) .. "\tC function\n"
else -- Lua function
ret = ret .. string.format("\t[%s]:%d in function `%s`\n", info.short_src, info.currentline, info.name or "")
end
--get local vars
local i = 1
while true do
local name, value = debug.getlocal(level, i)
if not name then break end
ret = ret .. "\t\t" .. name .. " =\t" .. tostringex(value, 3) .. "\n"
i = i + 1
end
level = level + 1
-- end
return ret
end
function tostringex(v, len)
if len == nil then len = 0 end
local pre = string.rep('\t', len)
local ret = ""
if type(v) == "table" then
if len > 5 then return "\t{ ... }" end
local t = ""
for k, v1 in pairs(v) do
t = t .. "\n\t" .. pre .. tostring(k) .. ":"
t = t .. tostringex(v1, len + 1)
end
if t == "" then
ret = ret .. pre .. "{ }\t(" .. tostring(v) .. ")"
else
if len > 0 then
ret = ret .. "\t(" .. tostring(v) .. ")\n"
end
ret = ret .. pre .. "{" .. t .. "\n" .. pre .. "}"
end
else
ret = ret .. pre .. tostring(v) .. "\t(" .. type(v) .. ")"
end
return ret
end
--捕获报错 is_safe = false 表示有异常 可以在else里用替换方法
function TryCatch(func, ...)
local args = { ... }
local paramCount = select('#', ...)
args = {xpcall(func, TraceBack, unpack(args, 1, paramCount))}
local is_safe = table.remove(args, 1)
return is_safe, args
end
function ShowBlackGround(alpha, show_type, sky_res, parent)
if not lua_viewM.main_cancas_last_visible or lua_viewM.is_lock_screen then
return
end
if show_type and show_type == 2 then
MainCamera:getInstance():ShowBlackSky(sky_res)
else
if global_black_ground_go == nil then
global_black_ground_go = UiFactory.createChild(parent or MainCamera.Instance.camera_gameObject.transform, UIType.SpriteRenderer, "global_black_ground_go")
lua_resM:loadSprite(UiFactory, "uiComponent_asset", "com_black", function(objs)
if objs[0] then
global_black_ground_go:GetComponent("SpriteRenderer").sprite = objs[0]
global_black_ground_go.transform.localPosition = Vector3(0, 0, 1)
global_black_ground_go.transform.localScale = Vector3.one * 10
SetLocalRotation(global_black_ground_go.transform, 0)
global_black_ground_go:GetComponent("SpriteRenderer").color = Color(1 ,1 ,1 ,alpha or 0.8)
end
end)
else
if parent then
global_black_ground_go.transform:SetParent(parent)
end
end
global_black_ground_go:SetActive(true)
local main_role = Scene.Instance:GetMainRole()
if main_role then
main_role:AddSceneObject()
end
end
end
function HideBlackGround(show_type, sky_res)
if show_type and show_type == 2 then
MainCamera:getInstance():HideBlackSky(sky_res)
else
if global_black_ground_go then
global_black_ground_go:SetActive(false)
local main_role = Scene.Instance:GetMainRole()
if main_role then
main_role:RemoveScreenObj()
end
end
end
end
function SetAlphaBlackGround()
if global_black_ground_go then
local compoent = global_black_ground_go:GetComponent("Image")
if compoent then
compoent.alpha = 0
end
local main_role = Scene.Instance:GetMainRole()
if main_role then
main_role:RemoveScreenObj()
end
end
end
function FindBone(transform, bone_name)
if transform then
--先从一级子节点找起
local obj = transform.Find(transform, bone_name)
if obj then
return obj
end
--[[
-- gameObject.name对比有GCAlloc
local objs = transform:GetComponentsInChildren(typeof(UnityEngine.Transform))
for i=1,objs.Length do
if objs[i-1].name == bone_name then
return objs[i-1]
end
end
]]
local count = transform.childCount
for i=1,count do
local child_trans = transform:GetChild(i-1)
local child_obj = FindBone(child_trans, bone_name)
if child_obj then
return child_obj
end
end
end
return nil
end
function SetChildRenderQueue(game_object,ignore_bone,render_queue, ignore_mat)
if game_object then
local objs = game_object:GetComponentsInChildren(typeof(UnityEngine.Renderer))
for i=1,objs.Length do
if objs[i-1].name ~= ignore_bone then
local mats = objs[i-1].sharedMaterials
for i=0, mats.Length - 1 do
if ignore_mat and mats[i].name ~= ignore_mat then
mats[i].renderQueue = render_queue
end
end
end
end
end
end
--输出日志--
function log( ... )
lua_logM:Log( ... )
end
--错误日志--
function LogError( ... )
lua_logM:LogError( ... )
end
--警告日志--
function logWarn( ... )
lua_logM:LogWarn( ... )
end
--查找对象--
function find(str)
return GameObject.Find(str);
end
function destroy(obj,immediate)
if not obj then
return
end
if immediate then
GameObject.DestroyImmediate(obj)
else
GameObject.Destroy(obj);
end
end
function newObject(prefab)
--print("-----newObject------",prefab)
return Util.newObject(prefab)
end
function Trim(str)
--去除字符串str两端空格
-- @param str 需要去除空格的字符串
--[[
local p1, p2, s = string.find(str, "^%s*(.-)%s*$")
if p1 then
return s
else
return str
end]]
if str == nil or type(str) == "table" then return "" end
str = string.gsub(str, "^[ \t\n\r]+", "")
return string.gsub(str, "[ \t\n\r]+$", "")
-- return (string.gsub(str, "^%s*(.-)%s*$", "%1"))
end
function Join(join_table, joiner)
-- 以某个连接符为标准,返回一个table所有字段连接结果
-- @param join_table 连接table
-- @param joiner 连接符
-- @param return 用连接符连接后的字符串
if #join_table == 0 then
return ""
end
local fmt = "%s"
for i = 2, #join_table do
fmt = fmt .. joiner .. "%s"
end
return string.format(fmt, unpack(join_table))
end
function Printf(fmt, ...)
-- 格式化输出字符串,类似c函数printf风格
print(string.format(fmt, ...))
end
function DeepCopy(object)
-- @param object 需要深拷贝的对象
-- @return 深拷贝完成的对象
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end
function RemoveRepeat(list, equal_func)
local new_list = {}
local have = false
for k,v in pairs(list or {}) do
have = false
for kk,vv in pairs(new_list) do
if equal_func(v, vv) then
have = true
break
end
end
if not have then
table.insert( new_list, v )
end
end
return new_list
end
function ToBoolean(s)
-- 将字符串转换为boolean值
local transform_map = {
["true"] = true,
["false"] = false,
}
return transform_map[s]
end
--[[
性别转换
]]
function GetSexByCareer(career_id)
for index,data in pairs(Config.Career) do
if data.career_id == career_id then
return data.sex
end
end
return 1
end
--将 szFullString 对象拆分为一个子字符串表
function Split(szFullString, szSeparator, start_pos)
if not szFullString or not szSeparator then
return {}
end
local nFindStartIndex = start_pos or 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
break
end
table.insert(nSplitArray, string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1))
nFindStartIndex = nFindLastIndex + string.len(szSeparator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
-- 通过一个指定的字符串切割另一个字符串
function SplitByStr(str, delimeter)
local res = {}
if not str or not delimeter then return res end
local find, sub, insert = string.find, string.sub, table.insert
local start, start_pos, end_pos = 1, 1, 1
while true do
start_pos, end_pos = find(str, delimeter, start, true)
if not start_pos then
break
end
insert(res, sub(str, start, start_pos - 1))
start = end_pos + 1
end
insert(res, sub(str, start))
return res
end
-- 根据国家获得不同的html文本
function GetHtmlColorStringByCountry(realm,label)
return "<font color = '"..ColorUtil:getRealmColorNew(realm).."'>"..label.."</font>"
-- return "<font color = '"..ColorUtil:dencodeRealmType(realm).."'>"..label.."</font>" --旧的
end
--访问common目录的资源
function toURL(url)
return "common/"..url
-- return url
end
--[[
* 得到进阶前缀
* @param id
* @return
*
--]]
function getJinjiePreFix(id, type)
local arr={"", "[1阶]", "[2阶]", "[3阶]", "[4阶]", "[5阶]", "[6阶]", "[7阶]", "[8阶]", "[9阶]", "[10阶]", "[11阶]", "[12阶]", "[13阶]", "[14阶]", "[15阶]", "[16阶]", "[17阶]", "[18阶]"}
local str = arr[id + 1]
if str == nil then
return ""
end
if type ~= nil then
str = string.gsub(str, "%[", "")
str = string.gsub(str, "%]", "")
end
return str
end
--连接两个tab
function TableConcat(tab1,tab2)
local tab = {}
for i=1,#tab1 do
table.insert(tab,tab1[i])
end
for j=1,#tab2 do
table.insert(tab,tab2[j])
end
return tab
end
function TableContains(tb,item)
if table == nil or item == nil then
return false
end
for key, value in pairs(tb) do
if item == value then
return true
end
end
return false
end
function TableRemove(tb,item)
if tb == nil or item == nil then
return
end
for key, value in pairs(tb) do
if item == value then
table.remove(tb,key)
return
end
end
end
function GetMaxLenString(str,max)
local data = {}
local charlen = 0
local len = 0
local string = ""
--[[
UTF8的编码规则:
1. 字符的第一个字节范围: 0x00—0x7F(0-127),或者 0xC2—0xF4(194-244); UTF8 是兼容 ascii 的,所以 0~127 就和 ascii 完全一致
2. 0xC0, 0xC1,0xF5—0xFF(192, 193 和 245-255)不会出现在UTF8编码中
3. 0x80—0xBF(128-191)只会出现在第二个及随后的编码中(针对多字节编码,如汉字)
]]
for v in string.gmatch(str,"[%z\1-\127\194-\244][\128-\191]*") do
table.insert(data,v)
end
for i,v in ipairs(data) do
if string.len(v) > 1 then
charlen = 1 -- 汉字的长度重置为1
else
charlen = 1
end
len = len + charlen
string = string .. v
if len >= max then
break
end
end
return string,len
end
--[[
@四舍五入
--]]
function round(number)
return math.floor(number + 0.5)
end
--[[
@延迟执行
@func 延迟回调函数
@time 延迟时间(秒)
@arg 延迟回调参数
--]]
function setTimeout(func,time,...)
local arg = {...}
if func == nil or type(func) == "number" then return end
local timeOutId = nil
local timeFunc = function()
func(unpack(arg))
GlobalTimerQuest:CancelQuest(timeOutId)
func = nil
end
timeOutId = GlobalTimerQuest:AddDelayQuest(timeFunc,time)
return timeOutId
end
function ChineseNumber(num)
if num == nil then return end
local chinese_num = {"","", "", "", "", "", "", "", "", ""}
local tem_name_list = {"","","","","",""}
local num_str = tostring(num)
local num_len = string.len(num_str)
local final_content = {}
local cell_content = ""
for i = 1, num_len do
if string.sub(num_str,i,i) == "0" then
if num_len > 1 and (i == num_len or tonumber(string.sub(num_str,i+1,num_len)) == 0) then --尾数的零不显示
cell_content = ""
else
cell_content = chinese_num[1]
end
else
if (string.sub(num_str,i,i) + 1) == 2 and (num_len - i + 1) == num_len and num_len > 1 then --防止两位数以上第一个数字出现 一 比如 一十
cell_content = tem_name_list[num_len - i + 1]
else
cell_content = chinese_num[string.sub(num_str,i,i) + 1] .. tem_name_list[num_len - i + 1]
end
end
if i == 1 or cell_content ~= chinese_num[1] or final_content[i-1] ~= chinese_num[1] then --避免中间出现重复的零
table.insert(final_content,cell_content)
end
end
return table.concat(final_content)
end
--罗马数字转换Ⅰ、Ⅱ、Ⅲ、Ⅳ、Ⅴ、Ⅵ、Ⅶ、Ⅷ、Ⅸ
function RomeNumber(num)
if num == nil then return end
local chinese_num = {"N","", "", "", "", "", "", "", "", ""}
local tem_name_list = {"","X","C","M"}
local num_str = tostring(num)
local num_len = string.len(num_str)
local final_content = {}
local cell_content = ""
for i = 1, num_len do
if string.sub(num_str,i,i) == "0" then
if num_len > 1 and (i == num_len or tonumber(string.sub(num_str,i+1,num_len)) == 0) then --尾数的零不显示
cell_content = ""
else
cell_content = chinese_num[1]
end
else
if (string.sub(num_str,i,i) + 1) == 2 and (num_len - i + 1) == num_len and num_len > 1 then --防止两位数以上第一个数字出现 一 比如 一十
cell_content = tem_name_list[num_len - i + 1]
else
cell_content = chinese_num[string.sub(num_str,i,i) + 1] .. tem_name_list[num_len - i + 1]
end
end
if i == 1 or cell_content ~= chinese_num[1] or final_content[i-1] ~= chinese_num[1] then --避免中间出现重复的零
table.insert(final_content,cell_content)
end
end
return table.concat(final_content)
end
-- function GetMoneyTypeRes( money_type )--1绑钱,2绑金,3金币
-- local res = ""
-- if money_type == 1 then
-- res = "comp:xx_btongIcon"
-- elseif money_type == 2 then
-- res = "comp:xx_bgoldIcon"
-- elseif money_type == 3 then
-- res = "comp:xx_goldIcon"
-- end
-- print("xxxxxxxxxxxxxxxxxxxxxx",money_type,res)
-- return res
-- end
--0:物品, 1:彩钻, 2:红钻, 3:金币, 5:经验
--解析类似 [[ [{0,100100,100},{3,0,1000}] ]]},
function GetServerConfigReward( config_str)
local good_list={}
local lua=ErlangParser:GetInstance():Parse(config_str)
for i,v in ipairs(lua) do
local vo={}
if v[1] == "0" then
vo.typeId=tonumber(v[2])
elseif v[1] == "1" then
vo.typeId=36010001
elseif v[1] == "2" then
vo.typeId=36020001
elseif v[1] == "3" then
vo.typeId=36030001
elseif v[1] == "4" then
vo.typeId=36050001
elseif v[1] == "5" then
vo.typeId=36060001
end
vo.itemType = tonumber(v[1])
vo.count = tonumber(v[3])
table.insert(good_list,vo)
end
return good_list
end
--0:物品, 1:彩钻, 2:红钻, 3:金币, 5:经验 8社团资金 17社团成长值
--解析服务端发来的奖励列表
function GetServerRewardList( list, key1, key2, key3)
local good_list={}
for i,v in ipairs(list) do
local vo={}
if v[key1] == 0 then
vo.typeId=v[key2]
elseif v[key1] == 1 then
vo.typeId=36010001
elseif v[key1] == 2 then
vo.typeId=36020001
elseif v[key1] == 3 then
vo.typeId=36030001
elseif v[key1] == 4 then
vo.typeId=36050001
elseif v[key1] == 5 then
vo.typeId=36060001
elseif v[key1] == 8 then
vo.typeId=36050002
elseif v[key1] == 17 then
vo.typeId=36050003
else
vo.typeId=v[key2]
end
vo.itemType = v[key1]
vo.count = v[key3]
table.insert(good_list,vo)
end
return good_list
end
--解析类似 {aircraft_stage, Stage}
function ConvertServerConfigTable(tbl)
local ret = {}
for k,v in ipairs(tbl) do
if v[1] then
ret[v[1]] = {}
for i,vv in ipairs(v) do
if tonumber(i) > 1 then
table.insert(ret[v[1]],tonumber(vv))
end
end
end
end
return ret
end
--[[
@describtion:目前设备的分辨率和ipad的分辨率对比
@return:bool, ture 代表比大于等于ipad的分辨率 ,false代表小于ipad的分辨率
]]
function NowScreenCompareIpadScreen()
local view_size = Game.UI:GetScreenView()
local is_ipad_screen = false
local view_ratio = view_size.y / view_size.x
local ipad_ratio = 768 / 1024
if view_ratio < ipad_ratio then
is_ipad_screen = false
elseif view_ratio >= ipad_ratio then
is_ipad_screen = true
end
return is_ipad_screen
end
-- 检查table是否为空
function IsTableEmpty(tbl)
return not tbl or _G.next( tbl ) == nil
end
-- 获取table长度,当数据不连续时不能用#
function TableSize(tbl)
if IsTableEmpty(tbl) then
return 0
end
local len = 0
for _ in pairs(tbl) do
len = len + 1
end
return len
end
--无符号的32位转换成有符号的32位
function UnsignToSigned(number)
if number >= 4000000000 then --无符号的数大于这个数默认为负数了
return -1 * bit.bnot(number - 1)
else
return number
end
end
function insertElement(arr, obj)
local flag = true;
for i=1,#arr do
if arr[i] == obj then
flag = false;
break ;
end
end
if flag then
table.insert(arr, obj);
end
end
function deleteElement(arr, obj)
for i=#arr,1,-1 do
if arr[i] and arr[i] == obj then
table.remove(arr, i);
end
end
end
function utf8_to_unicode(str)
if not str or str == "" then
return nil
end
local res, seq, val = {}, 0, nil
for i = 1, #str do
local c = string.byte(str, i)
if seq == 0 then
if val then
res[#res + 1] = string.format("%04x", val)
end
seq = c < 0x80 and 1 or c < 0xE0 and 2 or c < 0xF0 and 3 or
c < 0xF8 and 4 or --c < 0xFC and 5 or c < 0xFE and 6 or
0
if seq == 0 then
return str
end
val = bit.band(c, 2 ^ (8 - seq) - 1)
else
val = bit.bor(bit.lshift(val, 6), bit.band(c, 0x3F))
end
seq = seq - 1
end
if val then
res[#res + 1] = string.format("%04x", val)
end
if #res == 0 then
return str
end
return "\\u" .. table.concat(res, " \\u")
end
function HasLimitChar(str)
--[[local function hex2bin( hexstr )
local s = string.gsub(hexstr, "(.)(.)%s", function ( h, l )
return string.char(h2b[h]*16+h2b[l])
end)
return s
end]]
local unicode_str = utf8_to_unicode(str)
if not unicode_str or type(unicode_str) ~= "string" or unicode_str == "" then
return false
end
local str = string.gsub(unicode_str,"\\u","0x")
str = Split(str," ")
for k,v in pairs(str) do
local value = tonumber(v)
--放过一批创角名字的特殊字符
--のミ★、灬о+メ丶◎ζξ
if value == 0x306E or value == 0x30DF or value == 0x2605 or value == 0x3001 or value == 0x706C or value == 0x043E
or value == 0xFF0B or value == 0x30E1 or value == 0x4E36 or value == 0x25CE or value == 0x03B6 or value == 0x03BE then
return false
end
--中文
if not ((value >= 0x4E00 and value <= 0x9FA5) or (value >= 0x0021 and value <= 0x007F)) and
--韩文
not ((value >= 0xAC00 and value <= 0xD7AF) or (value >= 0x0021 and value <= 0x007F)) and
--日文
not ((value >= 0x3040 and value <= 0x31FF) or (value >= 0x0021 and value <= 0x007F)) then
return true
end
end
return false
end
--[[@
功能: 生成角色唯一ID
参数:
plat_name 平台名 string
server_id 服ID int16
role_id 角色ID int32
返回值:
唯一角色ID int32
其它: 无
作者: deadline
]]
function GenerateRoleId( plat_name, server_id, role_id)
plat_name = plat_name or ""
server_id = server_id or 0
role_id = role_id or 0
local tmp_val = server_id
if string.len(plat_name) <= 0 then
plat_name = "0"
end
tmp_val = tmp_val + tonumber(string.byte(plat_name , 1))
tmp_val = math.modf(tmp_val, 19)
tmp_val = tmp_val + 1
tmp_val = bit.lshift(tmp_val, 24)
--tmp_val = bit.toint(bit.bor(tmp_val, role_id))
tmp_val = bit.bor(tmp_val, role_id)
tmp_val = bit.band(tmp_val, 0x0fffffff)
return tmp_val
end
function GenerateSuperMemberData()
local config = Config.SuperMemberQQSpecial[ClientConfig.plat_name]
local use_remote = false
if ClientConfig.super_member_qq_special then
config = Game.System:ReadJsonStr( ClientConfig.super_member_qq_special )
if config and config.first == 1 then
use_remote = true
end
end
if not use_remote and MallModel.Instance.kaifuTime > Config.CloseBetaActivity.SuperMemberForNewServerTime then
local server_info = LoginController.Instance:GetPlatUserInfo()
-- 混服和应用宝专服
if ClientConfig.plat_belong ~= "1" or ( tonumber(server_info.belongid) == 7 and string.find(ClientConfig.plat_name, "yyb")) then
config = Config.CloseBetaActivity.SuperMemberForNewServerConfig
end
end
return config
end
function PrintTable( tbl , level)
if RuntimePlatform and (SystemRuntimePlatform.IsAndroid() or SystemRuntimePlatform.IsIphone()) then
return
end
if tbl == nil or type(tbl) ~= "table" then
return
end
level = level or 1
local indent_str = ""
for i = 1, level do
indent_str = indent_str.." "
end
print(indent_str .. "{")
for k,v in pairs(tbl) do
local item_str = string.format("%s%s = %s", indent_str .. " ",tostring(k), tostring(v))
print(item_str)
if type(v) == "table" then
PrintTable(v, level + 1)
end
end
print(indent_str .. "}")
end
--把整个table的内容拼接成一个字符串
function GetTableContentStr( tbl, level, return_counter )
if tbl == nil or type(tbl) ~= "table" then
return ""
end
return_counter = return_counter or 3 --剩下多少层就返回,防止无限打印
if return_counter <= 0 then
return ""
end
return_counter = return_counter - 1
level = level or 1
local indent_str = ""
for i = 1, level do
indent_str = indent_str.." "
end
indent_str = indent_str .. "{\n"
-- print(indent_str .. "{")
for k,v in pairs(tbl) do
local item_str = string.format("%s%s = %s", indent_str .. " ",tostring(k), tostring(v))
indent_str = item_str.."\n"
-- print(item_str)
if type(v) == "table" then
indent_str = indent_str .. GetTableContentStr(v, level + 1, return_counter)
end
end
-- print(indent_str .. "}")
indent_str = indent_str .. "}\n"
return indent_str
end
function GetCallStackStr()
local level = 1
local str = ""
while true do
local info = debug.getinfo(level, "Sl")
if not info then break end
if info.what == "C" then
str = str..level.."\tC function\n"
else
str = str..string.format("[%s]:%d\n",info.short_src, info.currentline)
end
level = level + 1
end
return str
end
function PrintCallStack( )
if RuntimePlatform and (SystemRuntimePlatform.IsAndroid() or SystemRuntimePlatform.IsIphone()) then
return
end
local level = 1
while true do
local info = debug.getinfo(level, "Sl")
if not info then break end
if info.what == "C" then
print(level, "C function")
else
print(string.format("[%s]:%d",
info.short_src, info.currentline))
end
level = level + 1
end
end
--屏幕坐标转视口坐标
function ScreenToViewportPoint(x,y)
return x / ScreenConvertRatio, y / ScreenConvertRatio
end
--视口坐标转换屏幕坐标
function ViewportToScreenPoint(x,y)
return x * ScreenConvertRatio, y * ScreenConvertRatio
end
--统一错误码提示,Config.Errorcode
function ErrorCodeShow(code, strParam)
local tmp = Config.Errorcode[code] or GlobalErrorCode[code]
local str = "未知返回码" .. code
if tmp then
str = tmp.about or tmp
if strParam then
local args = Split(strParam, ",")
for i, v in ipairs(args) do
str = string.gsub(str, "{"..i.."}", v)
end
end
end
print("HWR:utilManager [983]error_code: ",code)
Message.show(str,"fault")
end
--删除<color></color>标签
function DeleteColorTag(text)
if text == nil or Trim(text) =="" then return text end
--text = Trim(text)
local function replaceLeft(str)
return ""
end
local text = string.gsub(text, "%<color[^%>^/]+%>", replaceLeft)
local function replaceRight(str)
return ""
end
local text = string.gsub(text, "%</color%>", replaceRight)
return text
end
--获取跨服长名称
function GetCSLongName( role_name, server_name, no_dot, server_color )
if not server_name then return role_name end
local tb = {}
if string.find(server_name, "-") then
tb = Split(server_name, "-")
elseif string.find(server_name, "_") then
tb = Split(server_name, "_")
else
tb[1] = server_name
end
local server_id = tonumber(tb[1])
if server_id == 0 then
server_id = 1
end
server_id = server_id%1000
if server_id == 0 then
server_id = 1000
end
local ser_str = ""
if no_dot then
ser_str = "S" .. server_id
else
ser_str = "S" .. server_id .. ". "
end
if server_color then
ser_str = "<color=" .. server_color .. ">" .. ser_str .. "</color>"
end
return ser_str .. role_name
end
--解析链接点击标签,适用于这种格式<a@类型@参数1@参数2>XXX</a>, 例如<a@goods@110101>强化石</a>
function FormatHyperLinkParam(txt, cache_text)
local final_list = {}
--如果文本为空 或者没有需要解释的下划线或者点击事件 则过滤掉
if txt == nil or Trim(txt) == "" or (not string.find(txt, "</a>") and not string.find(txt, "</u>")) then return final_list end
--txt = Trim(txt)
local a_list = {} --保存a标签的所有数据
local p1, p2, param_str = string.find(txt, "%<a([^%>^/.]-)%>")
local count = 1
while p1 do
a_list[count] = {}
a_list[count].param = param_str
a_list[count].has_link = true
a_list[count].start_pos = p1
local _, _, text = string.find(txt,"(.-)%<%/a%>", p2 + 1)
text = text or ""
text = string.gsub(text, "<u>", "")
a_list[count].text = string.gsub(text, "</u>", "")
p1, p2, param_str = string.find(txt, "%<a([^%>^/.]-)%>", p1 + 1)
count = count + 1
end
local u_list = {}--保存u标签的所有数据
p1, p2, param_str = string.find(txt, "%<u%>(.-)%<%/u%>")
count = 1
while p1 do
u_list[count] = {}
u_list[count].start_pos = p1
param_str = string.gsub(param_str, "<a[^%>^/.]->", "")
u_list[count].text = string.gsub(param_str, "</a>", "")
u_list[count].has_under_line = true
p1, p2, param_str = string.find(txt, "%<u%>(.-)%<%/u%>", p1 + 1)
count = count + 1
end
local n_list = {}--保存</a>后面没有标签的所有数据
p1, p2, param_str = string.find(txt, "%</a%>([^<u>]+)%<")
count = 1
while p1 do
n_list[count] = {}
n_list[count].text = param_str
n_list[count].start_pos = p1
p1, p2, param_str = string.find(txt, "%</a%>([^<u>]+)%<%a", p1 + 1)
count = count + 1
end
local n2_list = {}--保存</u>后面没有标签的所有数据
p1, p2, param_str = string.find(txt, "%</u%>([^</a>]+)%<")
count = 1
while p1 do
n2_list[count] = {}
n2_list[count].text = param_str
n2_list[count].start_pos = p1
p1, p2, param_str = string.find(txt, "%</u%>([^</a>]+)%<", p1 + 1)
count = count + 1
end
local c_list = {}--保存color标签的所有数据
if cache_text then
p1, p2, color_str, content_str = string.find(cache_text, "%<color%=([^%>^/.]-)%>([^%>^/.]-)%<%/color")
count = 1
while p1 do
c_list[count] = {}
c_list[count].color = color_str
c_list[count].text = content_str
c_list[count].start_pos = p1
p1, p2, color_str, content_str = string.find(cache_text, "%<color%=([^%>^/.]-)%>([^%>^/.]-)%<%/color", p1 + 1)
count = count + 1
end
end
p1, p2, param_str = string.find(txt, "([^<u>]+)")
local p3, p4, param_str2 = string.find(txt, "%<u%>")
if p1 and param_str and not p3 and not param_str2 then
param_str = param_str
elseif not p1 and not param_str and p3 and param_str2 then
param_str = param_str2
elseif p1 and param_str and p3 and param_str2 then
param_str = p1 < p3 and param_str or param_str2
end
if param_str and string.len(param_str) > 0 then
table.insert(final_list, 1, {text = param_str, start_pos = 0})--开头没有标签的内容插入队列里作为第一个元素
end
--------------------------把以上所有列表存入总表------------------------
for i, vo in ipairs(a_list) do
table.insert(final_list, vo)
end
local function getFinalVoByText(text)
for i, vo in ipairs(final_list) do
if text == vo.text then
return vo
end
end
end
local have = false
for i, vo in ipairs(u_list) do
have = getFinalVoByText(vo.text)
if not have then
table.insert(final_list, vo)
end
end
local final_vo = nil
for i, vo in ipairs(u_list) do
final_vo = getFinalVoByText(vo.text)
if final_vo then
final_vo.has_under_line = true
else
table.insert(final_list, vo)
end
if final_vo then
for j, c_vo in ipairs(c_list) do
if c_vo.text == vo.text then
vo.color = c_vo.color
final_vo.color = c_vo.color
break
end
end
end
end
for i, vo in ipairs(n_list) do
table.insert(final_list, vo)
end
for i, vo in ipairs(n2_list) do
table.insert(final_list, vo)
end
---------------------------------对总表做排序---------------------
local function sort_func(v1, v2)
return v1.start_pos < v2.start_pos
end
table.sort(final_list, sort_func)
return final_list
end
--判断一段文本是否添加了超链接
function HasLink(txt)
if txt and string.find(txt, "</a>") then
return true
end
return false
end
--封装一些比较特殊的标签数据
function PackageSpecialTab(txt)
txt = IsContainsUrlTab(txt)
if txt == nil or Trim(txt) == "" or not string.find(txt, "</a>") then return txt end
--txt = Trim(txt)
local function replaceFunc(str)
local txt = string.sub(str, 2, -2)
local arr = Split(txt,"@")
PrintTable(arr)
local name = ""
if tostring(arr[2]) == "goods" or tostring(arr[2]) == "goods2" or tostring(arr[2]) == "goods5" or tostring(arr[2]) == "goods7" or tostring(arr[2]) == "goods9" then --物品
local basic = GoodsModel:getInstance():GetGoodsBasicByTypeId(tonumber(arr[3])) or GoodsModel:getInstance():GetGoodsBasicByTypeId(tonumber(arr[5]))
local empower_lv = tonumber(arr[6]) or 0
if basic then
local color = WordManager.GetGoodsColor(basic.color + empower_lv)
if tonumber(basic.color) == 0 then -- 对主界面的提示框的绿色物品特殊处理
color = ColorUtil.SHALLOW_GREEN
end
if empower_lv == 3 then
name = SetSevenColorStr("[" .. Trim(basic.goods_name) .. "]")
else
name = "<color=" .. color .. ">" .. "[" .. Trim(basic.goods_name) .. "]" .. "</color>"
end
if basic.type == 11 and (basic.subtype == 10 or basic.subtype == 11)then --装备鉴定物, 碎片,显示鉴定物对应的装备图标
local type_id, _name, icon = EquipModel:getInstance():GetIdentifyGoodsNameAndIcon(basic.type_id, RoleManager.Instance.mainRoleInfo.career, basic.color)
goods_icon = icon
name = _name
end
end
elseif tostring(arr[2]) == "goods6" or tostring(arr[2]) == "goods3" or tostring(arr[2]) == "goods4" or tostring(arr[2]) == "goods6" then --物品 加括号
local basic = GoodsModel:getInstance():GetGoodsBasicByTypeId(tonumber(arr[3]))
if basic then
local color = WordManager.GetGoodsColor(basic.color)
if tonumber(basic.color) == 0 then -- 对主界面的提示框的绿色物品特殊处理
color = ColorUtil.SHALLOW_GREEN
end
name = "<color=" .. color .. ">" .. "[" .. Trim(basic.goods_name) .. "]" .. "</color>"
if basic.type == 11 and (basic.subtype == 10 or basic.subtype == 11) then --装备鉴定物, 碎片,显示鉴定物对应的装备图标
local type_id, _name, icon = EquipModel:getInstance():GetIdentifyGoodsNameAndIcon(basic.type_id, RoleManager.Instance.mainRoleInfo.career, basic.color)
goods_icon = icon
name = "<" .. Trim(_name) .. ">"
end
end
elseif tostring(arr[2]) == "goods8" then --消耗物品
local basic = GoodsModel:getInstance():GetGoodsBasicByTypeId(tonumber(arr[3]))
if basic then
local have_num = GoodsModel:getInstance():GetCountWithType(0, tonumber(arr[3]))
if tonumber(arr[4]) > have_num then
name = "<color=" ..ColorUtil.RED.. ">"..Trim(basic.goods_name)..""..have_num.."/"..tonumber(arr[4])..")</color>"
else
name = "<color=" ..ColorUtil.GREEN.. ">"..Trim(basic.goods_name)..""..have_num.."/"..tonumber(arr[4])..")</color>"
end
--[[if basic.type == 11 and (basic.subtype == 10 or basic.subtype == 11)then --装备鉴定物, 碎片,显示鉴定物对应的装备图标
local type_id, _name, icon = EquipModel:getInstance():GetIdentifyGoodsNameAndIcon(basic.type_id, RoleManager.Instance.mainRoleInfo.career, basic.color)
goods_icon = icon
name = "<" .. Trim(_name) .. ">"
end--]]
end
elseif tostring(arr[2]) == "scene" then --场景
local scene_info = SceneManager.Instance:GetSceneInfo(tonumber(arr[3]))
if scene_info then
name = Trim(scene_info.name)
end
elseif tostring(arr[2]) == "scene2" or tostring(arr[2]) == "treasure3" or tostring(arr[2]) == "valhallapk" then
local scene_info = SceneManager.Instance:GetSceneInfo(tonumber(arr[3]))
if scene_info then
name = "<color=" .. ColorUtil.GREEN .. "><" .. Trim(scene_info.name) .. "(".. arr[4] ..",".. arr[5] ..")".. "></color>"
end
-- elseif tostring(arr[2]) == "partner" or arr[2] == "partner2" then --伙伴
-- local color, name_str = PartnerModel:getInstance():GetPartnerQualityAndName(tonumber(arr[3]))
-- if color and name_str then
-- logWarn(color,name_str)
-- name = "<color='" .. WordManager.GetPartnerColor(color) .. "'>" .. name_str .. "</color>"
-- end
-- elseif tostring(arr[2]) == "partner3" then --伙伴 加括号
-- local color, name_str = PartnerModel:getInstance():GetPartnerQualityAndName(tonumber(arr[3]))
-- if color and name_str then
-- logWarn(color,name_str)
-- name = "<color='" .. WordManager.GetPartnerColor(color) .. "'>" .. "<" .. name_str .. ">" .. "</color>"
-- end
-- elseif tostring(arr[2]) == "treasure" then --藏宝图地点
-- local event_type = tonumber(arr[3])
-- if event_type == 1 then -- 打开宝图介绍界面
-- name = string.format("<color=%s>[查看详情]</color>", WordManager.GetChuanwenColor(0))
-- elseif event_type == 2 then -- 跳转到藏宝图boss位置
-- name = string.format("<color=%s>[立即前往]</color>", WordManager.GetChuanwenColor(0))
-- end
elseif tostring(arr[2]) == "scene3" then --点击前往
-- name = string.format("<color='%s'>点击前往</color>", ColorUtil.GREEN)
name = string.format("<color=%s>点击前往</color>", WordManager.GetChuanwenColor(0))
elseif tostring(arr[2]) == "player" then
name = arr[3]
elseif tostring(arr[2]) == "player2" then
name = arr[3]
elseif tostring(arr[2]) == "angel" then
-- name = string.format("<color='%s'>点击前往</color>", ColorUtil.GREEN)
name = string.format("<color=%s>点击前往</color>", WordManager.GetChuanwenColor(0))
elseif tostring(arr[2]) == "skill" then
local cfg = ConfigItemMgr.Instance:GetSkillItem(tonumber(arr[3]))
if cfg then
name = string.format("<color=#ff3232>%s</color>",Trim(cfg.name))..","..Trim(cfg.lvs[1].desc)
end
elseif tostring(arr[2]) == "mate_show" then
name = MateConst.ShowMateText
elseif tostring(arr[2]) == "beachcallgift" then
name = "<color=#04bd27>[给我投票]</color>"
elseif tostring(arr[2]) == "dunManyTeam" then
name = string.format("<color=%s>[前往组队]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "dunManyGuardianTeam" then
name = string.format("<color=%s>[我要进组]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "firstrecharge" then
name = string.format("<color=%s>[我也要首充]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "fortuneCat" then -- 招财猫
name = string.format("<color=%s>[我也要翻倍]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "racerank" then -- 竞榜活动
name = string.format("<color=%s>[我也要冲榜]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "kfGroupBuying"then -- 开服团购活动
name = string.format("<color=%s>[前往砍价拼团]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "mobilizationGroupBuying" then
name = string.format("<color=%s>[前往砍价拼团]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "attr_id_val" then -- 属性id和数值
local _, name1, _, val1 = WordManager:GetPropertyInfo(tonumber(arr[3]), tonumber(arr[4]))
name = name1 .. "" .. val1
elseif tostring(arr[2]) == "mon" then -- 怪物id,表现为读取配置显示怪物名称
local monster_cfg = ConfigItemMgr.Instance:GetMonsterDataItem(tonumber(arr[3]))
name = monster_cfg and Trim(monster_cfg.name) or ""
elseif tostring(arr[2]) == "marble" then -- 弹珠机
name = string.format("<color=%s>[我也要弹]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "mono" then -- 大富翁
name = string.format("<color=%s>[前往超级富豪]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "contract" then -- 万物宝典
name = string.format("<color=%s>[我也要解锁]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "contractLv" then -- 万物宝典
name = string.format("<color=%s>[我也要升级]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "escortHelp" then -- 护送协助
name = string.format("<color=%s>[立即前往]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "guild_csgr_enter" then -- 本国团战
name = string.format("<color=%s>[立即前往]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "bosspass" then -- 幻魔宝典
name = string.format("<color=%s>[我也要解锁]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "bosspassLv" then -- 幻魔宝典
name = string.format("<color=%s>[立即前往]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "hopegift" then--明日之礼
name = string.format("<color=%s>[我也要抽]</color>", WordManager.GetChuanwenColor(1))
elseif tostring(arr[2]) == "playername" then -- 聊天@别人
name = HtmlColorTxt( "@" .. arr[3], ColorUtil.BLUE_DARK)
elseif tostring(arr[2]) == "mobilize" then -- 全民动员
name = string.format("<color=%s>[我也要达成]</color>", WordManager.GetChuanwenColor(1))
end
return "<" .. txt..">" .. name
end
txt = string.gsub(txt, "%<a[^%>^/]+%>", replaceFunc)
return txt
end
--是否包含Url标签
function IsContainsUrlTab( content )
if string.find(content, "[[]/url[]]") then
local function replaceFunc( str )
local arr
local new_str
arr = Split(str,"]")
new_str = string.format("<a@url@%s><color='%s'> %s</color></a>",arr[1],WordManager.GetChuanwenColor(4),arr[2])
return new_str
end
content = string.gsub(content, "%[url%s(.-)%[%/url%]",replaceFunc)
end
return content
end
--封装带url的特殊标签
function PackageSpecialUrlTab( content,url )
if string.find(url, "[[]/url[]]") then
local function replaceFunc( str )
local arr
local new_str
arr = Split(str,"]")
PrintTable(arr)
if tostring(arr[2]) and tostring(arr[2]) ~= "" then
new_str = string.format("<a@url@%s><color='%s'> %s</color></a>",arr[1],WordManager.GetChuanwenColor(4),arr[2])
elseif tostring(arr[2]) == "" then
new_str = string.format("<a@url@%s><color='%s'> 点击前往</color></a>",arr[1],WordManager.GetChuanwenColor(4))
end
return new_str
end
url = string.gsub(url, "%[url%s(.-)%[%/url%]",replaceFunc)
end
return PackageSpecialTab(content) .. url
end
--设置inlinetext的文本(no_chat_general在聊天栏部分颜色需要进行一次转换)
function SetInlineText(inline_text, content, url, no_chat_general)
if inline_text == nil then return end
content = content or ""
if url then
content = PackageSpecialUrlTab(content, url)
else
content = PackageSpecialTab(content)
end
if no_chat_general then
content = string.gsub(content, ColorUtil.GREEN_DARK, ColorUtil.GREEN_DARK_CH)
end
inlineSpriteMgr:PackageInlineText(inline_text, content)
end
--给inlinetext添加点击事件 可支持多行换行以及各种图文混排
function AddInlineLickEvent(inline_text, call_back)
if inline_text then
local function lua_callback(param, x, y)
local param_list = Split(param, "@", 2)
GlobalEventSystem:Fire(EventName.UNDER_LINE_CLICK_EVENT, param_list, x, y)
if call_back then
call_back(param_list,x,y)
end
end
inline_text:AddLinkEvent(lua_callback)
end
end
--[[
这个东西改成了支持下划线的方法
--下划线,标识<u></u>
--超链接,标识<a@类型@参数1@参数2>XXX</a>, 例如<a@goods@110101>强化石</a> 参数用@开始分隔
@param :
ref_tar必须是继承baseclass的对象
parent_transform:父控件
call_back:回调
hide_click:是否取消点击事件
hide_line:是否隐藏下滑线
]]
function AddUnderLineAndClick(ref_tar, parent_transform, call_back, hide_click, hide_line)
if parent_transform == nil then return end
local txt = parent_transform:GetComponent("Text").text
local cache_label_list = ref_tar[parent_transform]
if cache_label_list == nil then
cache_label_list = {}
ref_tar[parent_transform] = cache_label_list
else
for i, item in ipairs(cache_label_list) do
item:SetActive(false)
end
end
txt = PackageSpecialTab(txt)
local txt_cache = txt --保存一份文本
txt_cache = string.gsub(txt_cache, "%<a[^%>^/]+%>", "")
txt_cache = string.gsub(txt_cache, "</a>", "")
txt_cache = string.gsub(txt_cache, "<u>", "")
txt_cache = string.gsub(txt_cache, "%<%/u>", "")
--先去掉颜色标签,不然颜色标签会影响下划线的位置运算
txt = DeleteColorTag(txt)
--解析超链接
local final_list= FormatHyperLinkParam(txt, txt_cache)
parent_text = parent_transform:GetComponent("Text")
parent_text.text = txt_cache
local inlie
if not hide_click then
inlie = parent_transform:GetComponent("InlieText")
if inlie then --inlieText监听超链接点击
AddInlineLickEvent(parent_text, call_back)
end
end
local label_cache_list = {}
local current_width = 0
local label_count = 0
if not IsTableEmpty(final_list) then
for i, vo in ipairs(final_list) do
if vo.has_under_line or vo.has_link then
label_count = label_count + 1
--创建下划线的label
local child_label = cache_label_list[label_count]
if child_label == nil then
child_label = UiFactory.createChild(parent_transform, UIType.Label2,"child_label")
child_label.transform.pivot = Vector2(0, 1)
cache_label_list[label_count] = child_label
child_label.transform.anchorMin = Vector2(0, 1)
child_label.transform.anchorMax = Vector2(0, 1)
child_label.transform:GetComponent("Text").fontSize = parent_text.fontSize
child_label.transform:GetComponent("Text").raycastTarget = true
child_label.transform:GetComponent("Text").alignment = UnityEngine.TextAnchor.LowerCenter
else
child_label:SetActive(true)
end
parent_text.text = vo.text .. " "--这里先临时加两个空格,否则会出现最后一个下划线符号不显示
local curr_text_width = parent_text.preferredWidth
parent_text.text = vo.text
local curr_text_height = parent_text.preferredHeight + 5 --暂时加增大文本高度 为了避免下划线渲染不出来,+1不够 改成5
child_label.transform.sizeDelta = Vector2(curr_text_width, curr_text_height)
child_label.transform.localPosition = Vector3(current_width - parent_transform.pivot.x * parent_transform.sizeDelta.x, 0, 0)
--设置"___"下划线文本
local str = ""
for i = 1, string.len(vo.text) do
if vo.has_under_line == false or hide_line then
str = str .. " "
else
str = str .. "_"
end
end
local color_str = vo.color or "#31ee4a"
child_label:GetComponent("Text").text = "<color="..color_str..">"..str.."</color>"
if not hide_click and not inlie then --每一个下划线都有点击事件 如果是inlieText就不要监听,inlieText有超链接的监听
local function onBtnClickHandler(target, x, y)
local param_list = {}
if vo.param then
param_list = Split(vo.param, "@", 2)
GlobalEventSystem:Fire(EventName.UNDER_LINE_CLICK_EVENT, param_list, x, y)
end
if call_back then
call_back(param_list, x, y)
end
end
AddClickEvent(child_label, onBtnClickHandler)
end
end
parent_text.text = vo.text
current_width = current_width + parent_text.preferredWidth
end
end
parent_text.text = txt_cache
end
-- left 靠左或者居中 调用此方法前必须先赋值text!!!
-- 目标,头衔,头衔Img,名字,是否靠左,vip,vipImg
function SetTitlePos(target,title,t_img,text,left,vip,v_img)
-- print(target,title,t_img,text,left,vip,v_img)
local delta_x = 6
local width = text.preferredWidth
t_img.gameObject:SetActive(title ~= 0)
if title ~= 0 then
RoleTitleModel:getInstance():SetTitleImageByTouxian(target, t_img, title)
-- lua_resM:setImageSprite(target,t_img,"common_asset","title_icon_"..title)
t_img.rectTransform.anchoredPosition = Vector2.zero
text.rectTransform.anchoredPosition = Vector2(t_img.transform.sizeDelta.x + delta_x,0)
width = width + t_img.transform.sizeDelta.x + delta_x
t_img.gameObject:SetActive(true)
else
t_img.gameObject:SetActive(false)
t_img.rectTransform.anchoredPosition = Vector2(-t_img.transform.sizeDelta.x,0)
end
if vip then
VipModel:GetInstance():GetVipIcon(target,v_img,vip)
width = vip ~= 0 and width + v_img.transform.sizeDelta.x + delta_x or width
end
if not left then
--217是整个父物体的宽度
t_img.rectTransform.anchoredPosition = Vector2(217/2 - width/2, 0)
end
--无论居中还是靠左,text和vip都是在它左边组件的右边
text.rectTransform.anchoredPosition = Vector2(t_img.rectTransform.anchoredPosition.x + t_img.transform.sizeDelta.x + delta_x, 0)
v_img.rectTransform.anchoredPosition = Vector2(text.rectTransform.anchoredPosition.x + text.preferredWidth + delta_x, 0)
end
function utf8_to_unicode(str)
if not str or str == "" then
return nil
end
local res, seq, val = {}, 0, nil
for i = 1, #str do
local c = string.byte(str, i)
if seq == 0 then
if val then
res[#res + 1] = string.format("%04x", val)
end
seq = c < 0x80 and 1 or c < 0xE0 and 2 or c < 0xF0 and 3 or
c < 0xF8 and 4 or --c < 0xFC and 5 or c < 0xFE and 6 or
0
if seq == 0 then
return str
end
val = bit.band(c, 2 ^ (8 - seq) - 1)
else
val = bit.bor(bit.lshift(val, 6), bit.band(c, 0x3F))
end
seq = seq - 1
end
if val then
res[#res + 1] = string.format("%04x", val)
end
if #res == 0 then
return str
end
return "\\u" .. table.concat(res, " \\u")
end
-- function HasLimitChar(str)
-- -- if not ClientConfig.is_chinese_verison then
-- -- return str
-- -- end
-- local unicode_str = utf8_to_unicode(str)
-- if not unicode_str or type(unicode_str) ~= "string" or unicode_str == "" then
-- return false
-- end
-- local str = string.gsub(unicode_str,"\\u","0x")
-- str = Split(str," ")
-- for k,v in pairs(str) do
-- local value = tonumber(v)
-- --中文
-- if not ((value >= 0x4E00 and value <= 0x9FA5) or (value >= 0x0021 and value <= 0x007F)) and
-- --韩文
-- not ((value >= 0xAC00 and value <= 0xD7AF) or (value >= 0x0021 and value <= 0x007F)) and
-- --日文
-- not ((value >= 0x3040 and value <= 0x31FF) or (value >= 0x0021 and value <= 0x007F)) then
-- return true
-- end
-- end
-- return false
-- end
--计算单位,保证数字最多只有4个(军衔进阶界面战力显示用)
function CalUnitNumWithMaxNum(num,max_num)
local max_num = max_num and max_num or 4
local str = ""
if num < 10000 then --小于1万
str = num
elseif num < 100000000 then --小于1亿
-- local a,b = math.modf(num/10000)
-- local left_num = 1--整数部分位数
-- for i=1,max_num + 1 do
-- if a~=0 then
-- a = math.floor(a/10)
-- else
-- left_num = i - 1
-- break
-- end
-- end
-- if b == 0 then
-- str = string.format("%d万", num/10000)
-- else
-- local cal_str = "%0."..(max_num-left_num).."f"
-- str = string.format(cal_str.."万", num/10000)
-- end
--万单位的不显示小数点
str = string.format("%d万", math.floor(num/10000))
elseif num < 1000000000000 then --小于1万亿
local a,b = math.modf(num/100000000)
local left_num = 1--整数部分位数
for i=1,max_num + 1 do
if a~=0 then
a = math.floor(a/10)
else
left_num = i - 1
break
end
end
if b == 0 then
str = string.format("%d亿", num/100000000)
else
local cal_str = "%0."..(max_num-left_num).."f"
str = string.format(cal_str.."亿", num/100000000)
end
else --超过1万亿
str = string.format("%0.2f万亿", num/1000000000000)
end
return str
end
--计算单位
function CalUnitNum( num )
local str = ""
if num < 10000 then --小于1万
str = num
elseif num < 100000000 then --小于1亿
str = string.format("%0.2f万", num/10000)
elseif num < 1000000000000 then --小于1万亿
str = string.format("%0.2f亿", num/100000000)
else --超过1万亿
str = string.format("%0.2f万亿", num/1000000000000)
end
return str
end
--计算单位,不留小数和万字
function CalUnitNum1(num)
local str = ""
if num < 10000 then --小于1万
str = num
elseif num < 100000000 then --小于1亿
str = string.format("%d", num/10000)
elseif num < 1000000000000 then --小于1万亿
str = string.format("%d", num/100000000)
else --超过1万亿
str = string.format("%d", num/100000000)
end
return str
end
--计算单位,不留小数版本
function CalUnitNum2( num )
local str = ""
if num < 10000 then --小于1万
str = num
elseif num < 100000000 then --小于1亿
str = string.format("%d万", num/10000)
elseif num < 1000000000000 then --小于1万亿
str = string.format("%d亿", num/100000000)
else --超过1万亿
str = string.format("%d亿", num/100000000)
end
return str
end
--计算单位
function CalUnitNum3( num )
local str = ""
if num < 100000000 then --小于1亿
str = num
elseif num < 1000000000000 then --小于1万亿
str = string.format("%0.2f亿", num/100000000)
else --超过1万亿
str = string.format("%0.2f亿", num/100000000)
end
return str
end
--计算单位 保留一位小数
function CalUnitNum4( num )
local str = ""
if num < 10000 then --小于1万
str = num
elseif num < 100000000 then --小于1亿
str = string.format("%0.1f万", num/10000)
elseif num < 1000000000000 then --小于1万亿
str = string.format("%0.1f亿", num/100000000)
else --超过1万亿
str = string.format("%0.1f亿", num/100000000)
end
return str
end
--万以上的数转为万单位
function ChangeNumByTenThousand(num)
local str = num
if str and tonumber(str) >= 10000 then --万
str = string.format("%.1f万", str / 10000)
str = string.gsub(str,"%.0","")
end
return str
end
local function chsize(char)
if not char then
print("not char")
return 0
elseif char > 240 then
return 4
elseif char > 225 then
return 3
elseif char > 192 then
return 2
else
return 1
end
end
-- 计算utf8字符串字符数, 各种字符都按一个字符计算
-- 例如utf8len("1你好") => 3
function utf8len(str)
local len = 0
local currentIndex = 1
while currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
len = len +1
end
return len
end
--计算战力,适用于配置表的属性格式
function CalAttrPowerByBaseAttr( pro_list )
local coe_arr = {
[1] = 0.25, --生命
[3] = 2.5, --攻击
[4] = 2.5, --防御
[5] = 7.5, --命中
[6] = 7.5, --闪避
[7] = 7.5, --暴击
[8] = 7.5, --坚韧
[29] = 100, --暴击伤害
[30] = 100, --暴伤减免
[35] = 160, --伤害加成
[36] = 160, --伤害减免
}
local power = 0
local coe_arr_val = 0
for k, v in ipairs(pro_list) do
coe_arr_val = coe_arr[tonumber(v[1])] and coe_arr[tonumber(v[1])] or 0
power = power + coe_arr_val*tonumber(v[2])
end
return round(power)
end
function HtmlColorTxt(content, color, sizeScale)
local ncolor = color or "#ffffff"
if sizeScale then
return "<size=".. sizeScale .. "em><color=" .. ncolor .. ">" .. content .. "</color></size>"
else
return "<color=" .. ncolor .. ">" .. content .. "</color>"
end
end
function PairsByKeysInvert(t)
local temp = {}
for k in pairs(t) do
temp[#temp+1] = k
end
table.sort(temp)
local i = #temp+1
return function()
i = i-1
return temp[i], t[temp[i]]
end
end
--根据pairs修改而来,保证遍历的顺序是从小到大
function pairsByKeys(t)
local temp = {}
for k in pairs(t) do
temp[#temp+1] = k
end
table.sort(temp)
local i = 0
return function()
i = i+1
return temp[i], t[temp[i]]
end
end
function UtilGetRolePicPath(role_id,out_server,head_ver)
head_ver = head_ver or 0
local playerInfo = LoginController.Instance:GetPlatUserInfo()
local server_id = out_server or playerInfo.server_id
local file_path = Util.DataPath .. "/rolehead/"
local file_name = role_id .. "_" .. head_ver .. ".jpg"
return file_path,file_name
end
local rechange_tab = {
['['] = "{",
[']'] = "}",
['<'] = "",
['>'] = "",
key = "[%[%]<>]"
}
function stringtotable(str,is_check_chinese)
if str == "" then
return nil
end
local tab = {}
if str == nil or str == "nil" then
return nil
elseif type(str) ~= "string" then
tab = {}
return tab
elseif #str == 0 then
tab = {}
return tab
end
local _s = ""
local number = 0
str = string.gsub(str , rechange_tab.key,function(s,...)
return rechange_tab[s] or s
end)
local index,_ = string.find(str , "%b{}")
if not index then
str = string.format("{%s}",str)
end
string.gsub(str , "%b{}",function(s)
-- print(s)
number = number + 1
if number >= 2 then
_s = _s .. ","
end
_s = _s .. s
end)
if number > 1 then
_s = "{" .. _s .. "}"
end
if is_check_chinese then
_s = string.gsub(_s , "([%z\1-\31\33-\43\45-\122\124\126\127\194-\244].-)([,}].-)",function(s,f)
if tonumber(s) == nil then
s = "'"..s.."'"
end
return s..f
end)
else
_s = string.gsub(_s , "([%w%d].-)([,}].-)",function(s,f)
if tonumber(s) == nil then
s = "'"..s.."'"
end
return s..f
end)
end
local code, ret = pcall(loadstring(string.format("do local _=%s return _ end", _s)))
if code then
return ret
else
tab = {}
return tab
end
end
function GetSkillPowerAttrList(skill_power_info)
local result = {}
local data = stringtotable(skill_power_info.attr)
local coe_arr = {
[1] = true, --生命
[3] = true, --攻击
[4] = true, --防御
[5] = true, --命中
[6] = true, --闪避
[7] = true, --暴击
[8] = true, --坚韧
[29] = true, --暴击伤害
[30] = true, --暴伤减免
[35] = true, --伤害加成
[36] = true, --伤害减免
}
local function get_coe(key)
for k,v in pairs(coe_arr) do
if tonumber(key) == k then
local arr = coe_arr[k]
coe_arr[k] = nil
return arr
end
end
end
--目前暂不判断
--被动技能 对象(自己):v[4] == 1
--被动技能 概率:v[3] == 1000
for i,v in pairs(data) do
if get_coe(v[1]) and v[5] > 0 then
local item = {v[1], v[5]}
table.insert(result, item)
end
end
return result
end
function GetSkillPower( skill_power_info )
return CalAttrPowerByBaseAttr(GetSkillPowerAttrList(skill_power_info))
end
function GetSkillAttrBySkill( skill_id, skill_lv, need_power ,is_have)
local new_atr_tb = {}
-------------------------
skill_lv = skill_lv or 1
local power_conf = 0
local skill_conf = SkillManager:getInstance():getSkillFromConfig(skill_id)
if skill_conf and skill_conf.lvs and skill_conf.lvs[skill_lv] then
local temp_tb = stringtotable(skill_conf.lvs[skill_lv].base_attr)
power_conf = tonumber(skill_conf.lvs[skill_lv].power) or 0
for k,v in pairs(temp_tb) do
table.insert( new_atr_tb, {v[2],v[3]} )
end
end
if need_power then
return new_atr_tb,GetFighting(new_atr_tb, is_have) + power_conf
else
return new_atr_tb
end
end
function GetSkillConfPowerBySkill( skill_id, skill_lv)
local new_atr_tb = {}
-------------------------
skill_lv = skill_lv or 1
local power_conf = 0
local skill_conf = SkillManager:getInstance():getSkillFromConfig(skill_id)
if skill_conf and skill_conf.lvs and skill_conf.lvs[skill_lv] then
local temp_tb = stringtotable(skill_conf.lvs[skill_lv].base_attr)
power_conf = tonumber(skill_conf.lvs[skill_lv].power) or 0
end
return power_conf
end
function SetGameFrameRate( value )
if not FINAL_FRAMERATE then
if SystemMemoryLevel.Cur == SystemMemoryLevel.Low then
FINAL_FRAMERATE = GameSettingManager.PerformanceList[1].val_list[1]
elseif SystemMemoryLevel.Cur == SystemMemoryLevel.Middle then
FINAL_FRAMERATE = GameSettingManager.PerformanceList[1].val_list[2]
else
FINAL_FRAMERATE = GameSettingManager.PerformanceList[1].val_list[3]
end
end
local value = value or FINAL_FRAMERATE
Application.targetFrameRate = value
end
--千万以上的数转为亿单位
function ChangeNum(num)
local str = num
if str and tonumber(str) >= 100000000 then --千万
str = string.format("%.2f亿", str / 1000000000)
end
return str
end
--模拟器设置
function InitSimulatorSetting( )
if SystemMemoryLevel.Cur == SystemMemoryLevel.Low then
SystemMemoryLevel.Cur = SystemMemoryLevel.Middle
lua_settingM:SetPostEffectLevel(2)
end
--Optimizer.SetShaderLodValue(300)
lua_settingM.sysSet.quality = 3
lua_settingM.sysSet.fps = 50
lua_settingM:ApplySetting()
end
function InitResLoadSpeed( scale_speed )
if SystemRuntimePlatform.IsWindows() then
return
end
local scale = scale_speed or 1
local load_count = 6
local download = 3
if SystemMemoryLevel.Cur == SystemMemoryLevel.Low then
load_count = 4
download = 2
elseif SystemMemoryLevel.Cur == SystemMemoryLevel.Middle then
load_count = 5
download = 2
end
resMgr:SetLoadAssetsMaxCount( load_count * scale )
resMgr:SetDownloadMaxCount( download * scale )
end
function SetAsyncUpLoadLevel( level )
if SystemRuntimePlatform.IsWindows() then
return
end
local time_slice = 4
local buff_size = 16
if SystemMemoryLevel.Cur == SystemMemoryLevel.Low then
time_slice = 4
buff_size = 8
end
time_slice = time_slice * level
buff_size = buff_size * level
QualitySettings.asyncUploadTimeSlice = time_slice
QualitySettings.asyncUploadBufferSize = buff_size
end
function InitEngineData()
if tonumber(AppConst.EnglineVer) >= 77 then
resMgr:SetCacheDownloadMode(false)
resMgr:SetNewDownloadMode(true)
resMgr.m_download_timeout = 20
end
-- if SystemRuntimePlatform.IsAndroid() then
-- if tonumber(AppConst.EnglineVer) >= 91 then
-- networkMgr.socket.mUseThread = true --是否开启多线程收发协议模式
-- if SystemMemoryLevel.Cur == SystemMemoryLevel.Hight and SystemRuntimePlatform.IsAndroid() then
-- networkMgr.socket.mUseThread = false
-- networkMgr.socket.writeFunc = 1
-- networkMgr.socket.use_read_cache_state = false
-- networkMgr.socket.use_sent_cache_state = false
-- end
-- end
-- else
networkMgr.socket.mUseThread = true
-- end
end
function GameDontDestroyOnLoad()
local obj = GameObject.Find("root").transform
while obj.parent ~= nil do
obj = obj.parent
end
UnityEngine.Object.DontDestroyOnLoad(obj.gameObject)
end
function CheckIphoneXState()
local iphonex_offset = 55 --像素
local mode_func = function()
ClientConfig.iphone_x_offset_left = iphonex_offset
local orientation = SDKUtil.CallIntFunc( "IosSystem", "GetIosOrientation", "")
if tonumber(orientation) ~= 0 then
ClientConfig.orientation_did_change = tonumber(orientation)
end
if ClientConfig.orientation_did_change == 3 then --默认
ClientConfig.iphone_x_offset_left = iphonex_offset
ClientConfig.iphone_x_offset_right = 0
elseif ClientConfig.orientation_did_change == 4 then --反转
ClientConfig.iphone_x_offset_right = iphonex_offset
ClientConfig.iphone_x_offset_left = 0
end
end
if ClientConfig.iphone_x_model then
mode_func()
end
local device_list = {}
if SystemRuntimePlatform.IsIphone() then
device_list = {
["iPhone10,3"] = true,
["iPhone10,6"] = true,
["iPhone11,2"] = true,
["iPhone11,4"] = true,
["iPhone11,6"] = true,
["iPhone11,8"] = true,
}
elseif SystemRuntimePlatform.IsAndroid() and OriginalResolutionWidth == 2280 then
device_list =
{
["OPPOPACM00"] = true,
["OPPOPACT00"] = true,
["OPPOPAAT00"] = true,
["OPPOPAAM00"] = true,
["OPPOPADT00"] = true,
["OPPOPADM00"] = true,
["VIVOVIVOY85"] = true,
["VIVOVIVOY85A"] = true,
["VIVOVIVOX21"] = true,
["VIVOVIVOX21A"] = true,
}
elseif SystemRuntimePlatform.IsAndroid() and OriginalResolutionWidth == 1520 then
device_list = {
["VIVOV1732A"] = true,
["VIVOV1732T"] = true,
["OPPOPBAM00"] = true,
}
elseif SystemRuntimePlatform.IsAndroid() and OriginalResolutionWidth == 2340 then
device_list = {
["SAMSUNGSM-G8870"] = true,
["VIVOV1824A"] = true,
}
else
return
end
local device = string.gsub(SystemInfo.deviceModel," ","")
if SystemRuntimePlatform.IsAndroid() then
device = string.upper(device)
end
if device_list[device] then
ClientConfig.iphone_x_model = true
if SystemRuntimePlatform.IsAndroid() then
CheckAndroidHairAndOrientation(iphonex_offset)
else
mode_func()
end
else
if SystemRuntimePlatform.IsIphone() then
local hair_size = SDKUtil.CallIntFunc( "IosSystem", "GetIosHairSystemSize", "")
if tonumber(hair_size) > 0 then
ClientConfig.iphone_x_model = true
iphonex_offset = tonumber(hair_size)
mode_func()
end
end
end
end
function CheckAndroidHairAndOrientation(size)
if tonumber(AppConst.EnglineVer) >= 85 then
--local orientation = SDKUtil.CallIntFunc( "SystemData", "OrientationChanged", "")
if orientation and tonumber(orientation) > 0 then
ClientConfig.orientation_did_change = tonumber(orientation)
end
if ClientConfig.orientation_did_change == 3 then
ClientConfig.iphone_x_offset_left = size
ClientConfig.iphone_x_offset_right = size
else
ClientConfig.iphone_x_offset_left = size
ClientConfig.iphone_x_offset_right = size
end
else
ClientConfig.iphone_x_offset_left = size
ClientConfig.iphone_x_offset_right = size
end
end
function CheckAndroid9SystemHair()
if SystemRuntimePlatform.IsAndroid() and not ClientConfig.iphone_x_model then
local size = SDKUtil.CallIntFunc( "SystemData", "GetSafeTop", "")
local size_num = tonumber(size)
-- local temp_str = "GetSafeTop = " .. tostring(size_num)
-- GameError.Instance:SendErrorMsg(temp_str)
if size_num then
local temp_size = size_num > 55 and 55 or size_num
temp_size = temp_size <= 0 and 10 or temp_size
ClientConfig.iphone_x_model = true
CheckAndroidHairAndOrientation(temp_size)
end
end
end
--设置材质贴图
function SetMaterialTexture(material, texture)
if material:HasProperty("_MainTex") then
material:SetTexture("_MainTex", texture)
elseif material:HasProperty("_AmitTex") then
material:SetTexture("_AmitTex", texture)
end
end
--获取材质贴图
function GetMaterialTexture(material)
local texture
if material:HasProperty("_MainTex") then
texture = material:GetTexture("_MainTex")
elseif material:HasProperty("_AmitTex") then
texture = material:GetTexture("_AmitTex")
elseif material:HasProperty("_Amitex") then
texture = material:GetTexture("_Amitex")
end
return texture
end
--取等级模型id列表的衣服id
function GetRoleClotheId(level_model_list)
local model_res_list = level_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionPartPos.Clothe then
return v.level_model_id
end
end
end
end
--取时装衣服贴图id
--is_only_have_fashion_id:fashion_model_id如果是表示时装id而不是资源id,则要去FashionModel转化一下
function GetRoleClotheTextureId(vo, is_only_have_fashion_id)
local model_res_list = vo.fashion_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionModel.FashionType.CLOTHES then
--需要折算id返回
local id = v.fashion_model_id
if is_only_have_fashion_id and v.fashion_model_id ~= 0 then
id = FashionModel:GetInstance():GetFashionModelId(v.fashion_model_id, vo.career, v.fashion_color)
end
if id < 1000 then
id = id + vo.career * 1000
end
if v.fashion_chartlet_id > 1 then--配色大于1要多连接一个配色
id = id .. v.fashion_chartlet_id
end
return tonumber(id), 0
end
end
end
end
--取坐骑id
function GetHorseTextureId(foster_list)
local model_res_list = foster_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.type_id == FosterConst.ModuleId.FHorse then
local cfg = FosterModel.Instance:GetBaseConfOne(v.type_id, v.stage_id, 0)
if cfg then
return cfg.resource
end
end
end
end
return 1000
end
--上面取坐骑id的先不删,新建一个方法,先取珍宝再取进阶
function GetHorseClotheId( vo )
if vo then
local function get_foster_skin( type_id )
for k,v in pairs(vo.foster_skin_list) do
if not v.skin_id then
--数据结构改了,写法要修正,补全一个skin_id
if v.type_id == FosterConst.ModuleId.FHorse then
--武器的珍宝需要手动折算2次成资源名
v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
--你的数据要有职业哦,不然我没法完全正确地补全skin_id
-- v.skin_id = GameResPath:GetFWeaponResName( vo.career or 1,v.skin_id)--写错了,等祖荣哥回来改
-- else
-- v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
end
end
if v.type_id == type_id and v.skin_id > 0 then
return v.skin_id
end
end
end
for k,v in pairs(vo.foster_skin_list) do
if v.type_id == FosterConst.ModuleId.FHorse then
return get_foster_skin(v.type_id)
end
end
for k,v in pairs(vo.foster_list) do
if v.type_id == FosterConst.ModuleId.FHorse then
return FosterModel:GetInstance():GetModuleResIdByStage(v.type_id,v.stage_id)
end
end
end
return 1000
end
--取时装头发id
--is_only_have_fashion_id:fashion_model_id如果是表示时装id而不是资源id,则要去FashionModel转化一下
function GetRoleHeadId(vo, is_only_have_fashion_id)
local model_res_list = vo.fashion_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionModel.FashionType.HEAD then
--需要折算id返回
local id = v.fashion_model_id
if is_only_have_fashion_id and v.fashion_model_id ~= 0 then
id = FashionModel:GetInstance():GetFashionModelId(v.fashion_model_id, vo.career, v.fashion_color)
end
if id < 1000 then
id = id + vo.career * 1000
end
if v.fashion_chartlet_id > 1 then
id = id .. v.fashion_chartlet_id
end
return tonumber(id)
end
end
end
model_res_list = vo.level_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionPartPos.Head then
return v.level_model_id
end
end
end
end
--取时装发饰id
function GetRoleHatId(vo)
local model_res_list = vo.fashion_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionModel.FashionType.HAT then
return v.fashion_model_id
end
end
end
end
--明日之星直接取发饰的资源id
function GetRoleHatTextureId(vo)
local model_res_list = vo.fashion_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionModel.FashionType.HAT then
return FashionModel:GetInstance():GetFashionModelId(v.fashion_model_id, 0, v.fashion_color)
end
end
end
end
--is_only_have_fashion_id:fashion_model_id如果是表示时装id而不是资源id,则要去FashionModel转化一下
function GetWingClotheId( vo ,is_only_have_fashion_id)
if vo then
--珍宝
local function get_foster_skin( type_id )
for k,v in pairs(vo.foster_skin_list) do
if not v.skin_id then
--数据结构改了,写法要修正,补全一个skin_id
if v.type_id == FosterConst.ModuleId.FWing then
--武器的珍宝需要手动折算2次成资源名
v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
--你的数据要有职业哦,不然我没法完全正确地补全skin_id
-- v.skin_id = GameResPath:GetFWeaponResName( vo.career or 1,v.skin_id)--写错了,等祖荣哥回来改
-- else
-- v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
end
end
if v.type_id == type_id and v.skin_id > 0 then
return v.skin_id
end
end
end
for k,v in pairs(vo.foster_skin_list) do
if v.type_id == FosterConst.ModuleId.FWing then
local foster_skin_id = get_foster_skin(v.type_id)
if foster_skin_id and foster_skin_id > 0 then
return get_foster_skin(v.type_id)
end
end
end
for k,v in pairs(vo.foster_list) do
if v.type_id == FosterConst.ModuleId.FWing then
return FosterModel:GetInstance():GetModuleResIdByStage(v.type_id,v.stage_id)
end
end
--时装
local model_res_list = vo.fashion_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionModel.FashionType.WING then
if v.fashion_model_id ~= 0 then--明日之星可能会出现modelid为0的情况,这里要跳过
if is_only_have_fashion_id then
return FashionModel:GetInstance():GetFashionModelId(v.fashion_model_id, vo.career, v.fashion_color),v.fashion_chartlet_id
else
return v.fashion_model_id
end
end
end
end
end
--进阶
model_res_list = vo.level_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionPartPos.wing then
return v.level_model_id
end
end
end
end
end
--取宝具id
function GetTalismanClotheId( vo )
if vo then
local function get_foster_skin( type_id )
for k,v in pairs(vo.foster_skin_list) do
if not v.skin_id then
--数据结构改了,写法要修正,补全一个skin_id
if v.type_id == FosterConst.ModuleId.FPearl then
--武器的珍宝需要手动折算2次成资源名
v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
--你的数据要有职业哦,不然我没法完全正确地补全skin_id
-- v.skin_id = GameResPath:GetFWeaponResName( vo.career or 1,v.skin_id)--写错了,等祖荣哥回来改
-- else
-- v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
end
end
if v.type_id == type_id and v.skin_id > 0 then
return v.skin_id
end
end
end
for k,v in pairs(vo.foster_skin_list) do
if v.type_id == FosterConst.ModuleId.FPearl then
local foster_id = get_foster_skin(v.type_id)
if foster_id and foster_id > 0 then
return foster_id
end
end
end
for k,v in pairs(vo.foster_list) do
if v.type_id == FosterConst.ModuleId.FPearl then
return FosterModel:GetInstance():GetModuleResIdByStage(v.type_id,v.stage_id)
end
end
end
end
--先去时装模型列表的 再取等级模型id列表的武器id
--is_only_have_fashion_model_id:fashion_model_id如果是表示资源id(居然和翅膀不一样,再特殊处理一下吧)
function GetWeaponClotheId(vo,is_only_have_fashion_model_id)
if vo then
--珍宝
if vo.foster_skin_list then
for k,v in pairs(vo.foster_skin_list) do
if not v.skin_id then
--数据结构改了,写法要修正,补全一个skin_id
if v.type_id == FosterConst.ModuleId.FWeapon then
--武器的珍宝需要手动折算2次成资源名
v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
--你的数据要有职业哦,不然我没法完全正确地补全skin_id
if v.skin_id and v.skin_id > 0 then
v.skin_id = GameResPath:GetFWeaponResName( vo.career or 1,v.skin_id)
end
-- else
-- v.skin_id = ShapeModel:GetInstance():GetModelRes( v.type_id, v.sub_id, v.star )
end
end
if v.type_id == FosterConst.ModuleId.FWeapon and v.skin_id > 0 then
return v.skin_id
end
end
end
for k,v in pairs(vo.foster_list) do
if v.type_id == FosterConst.ModuleId.FWeapon then
--防止stage_id等于0
local stage_id = v.stage_id == 0 and 1 or v.stage_id
local res_id = FosterModel:GetInstance():GetModuleResIdByStage(v.type_id, stage_id)
return GameResPath:GetFWeaponResName(vo.career,res_id)
end
end
--时装
local model_res_list = vo.fashion_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionModel.FashionType.WEAPON then
local figure_id = v.fashion_model_id
if is_only_have_fashion_model_id then
local figure_id = FashionModel:GetInstance():GetFashionModelId(v.fashion_model_id, vo.career, v.fashion_color)
--需要折算id返回
if figure_id < 1000 then
figure_id = figure_id + vo.career * 1000
end
return figure_id
else
--需要折算id返回
if figure_id < 1000 then
figure_id = figure_id + vo.career * 1000
end
return figure_id
end
end
end
end
--进阶
model_res_list = vo.level_model_list
if model_res_list then
for k,v in ipairs(model_res_list) do
if v.part_pos == FashionPartPos.Weapon then
return v.level_model_id
end
end
end
end
end
function GetRoleHeadPath(career,sex,turn)
career = career or 1
sex = sex or 1
turn = turn or 1
local cfg = Config.Transfercareer[career.."@"..turn]
if cfg then
return "head_circle_" .. cfg.icon
end
return ""
end
--[[
local test = {1, 2, 3, 4}
_G.next(test) = nil
for i, v in pairs(test) do
print(v)
end]]
--中文字符串的截取
function SubStringUTF8(str, startIndex, endIndex)
if startIndex < 0 then
startIndex = SubStringGetTotalIndex(str) + startIndex + 1;
end
if endIndex ~= nil and endIndex < 0 then
endIndex = SubStringGetTotalIndex(str) + endIndex + 1;
end
if endIndex == nil then
return string.sub(str, SubStringGetTrueIndex(str, startIndex));
else
return string.sub(str, SubStringGetTrueIndex(str, startIndex), SubStringGetTrueIndex(str, endIndex + 1) - 1);
end
end
--获取中英混合UTF8字符串的真实字符数量
function SubStringGetTotalIndex(str)
local curIndex = 0;
local i = 1;
local lastCount = 1;
repeat
lastCount = SubStringGetByteCount(str, i)
i = i + lastCount;
curIndex = curIndex + 1;
until(lastCount == 0);
return curIndex - 1;
end
--[[
获取一个字符串在unity里面实际占位大小(有误差,英文每个字母占的像素大多不一样)
取一个中文字符为标准占位(16号字体一个中文宽高都是16像素)
不同字体不同又不一样,很坑爹,于是大致认定为数字和英文都算半个中文。
]]--
function CalStringTrueLength( str )
if not str then
return 0
end
str = DeleteColorTag(str)
local length = 0;
local i = 1;
local lastCount = 1;
repeat
lastCount = SubStringGetByteCount(str, i)
i = i + lastCount;
if lastCount >= 2 then
length = length + 1;
else
length = length + 0.5;
end
until(lastCount == 0);
return length - 1;
end
function SubStringGetTrueIndex(str, index)
local curIndex = 0;
local i = 1;
local lastCount = 1;
repeat
lastCount = SubStringGetByteCount(str, i)
i = i + lastCount;
curIndex = curIndex + 1;
until(curIndex >= index);
return i - lastCount;
end
--返回当前字符实际占用的字符数
function SubStringGetByteCount(str, index)
local curByte = string.byte(str, index)
local byteCount = 1;
if curByte == nil then
byteCount = 0
elseif 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
return byteCount;
end
--[[
删除表中数据
@param
list:数据列表
deleteKey:判断条件的key
deleteValue:等于判断条件的value
]]
function DeleteTable( list, deleteKey, deleteValue )
local delete_index={}
for i,v in ipairs(list) do
if v[deleteKey]==deleteValue then
table.insert(delete_index,i)
end
end
local del_num=0
for i,v in ipairs(delete_index) do
local index = v - del_num
table.remove(list, index)
del_num = del_num + 1
end
end
--删除表中数据 判断不相等版本
function DeleteTableUnEqual( list, deleteKey, deleteValue )
local delete_index={}
for i,v in ipairs(list) do
if v[deleteKey]~=deleteValue then
table.insert(delete_index,i)
end
end
local del_num=0
for i,v in ipairs(delete_index) do
local index = v - del_num
table.remove(list, index)
del_num = del_num + 1
end
end
function ToStringEx(value)
if type(value)=='table' then
return TableToStr(value)
elseif type(value)=='string' then
return "\'"..value.."\'"
else
return tostring(value)
end
end
function TableToStr(t)
if t == nil then return "" end
local retstr= "{"
local i = 1
for key,value in pairs(t) do
local signal = ","
if i==1 then
signal = ""
end
if key == i then
retstr = retstr..signal..ToStringEx(value)
else
if type(key)=='number' or type(key) == 'string' then
retstr = retstr..signal..'['..ToStringEx(key).."]="..ToStringEx(value)
else
if type(key)=='userdata' then
retstr = retstr..signal.."*s"..TableToStr(getmetatable(key)).."*e".."="..ToStringEx(value)
else
retstr = retstr..signal..key.."="..ToStringEx(value)
end
end
end
i = i+1
end
retstr = retstr.."}"
return retstr
end
function FindInTable( tbl, key, value )
for k,v in pairs(tbl) do
if (key and v[key] or v) == value then
return v
end
end
return nil
end
function StrToTable(str)
if str == nil or type(str) ~= "string" or str=="[]" then
return
end
return loadstring("return " .. str)()
end
--获取进度的最大值(返回空表示不显示进度)
function GetMaxProgress(list)
if list[1] and list[1][1] then
if list[1][1] == "attr" then
return list[1][#list[1]]
elseif list[1][1] == "boss" then
return #list[1][2]
elseif list[1][1] == "suit_type" then
return list[#list][2]
elseif list[1][1] == "vip" then
return 1
elseif list[1][1] == "equip_ids" then
return 1
elseif list[1][1] == "equip" then
return 1
elseif list[1][1] == "equip_suit" then
return 1
elseif list[1][1] == "equipment" then
if list[1][2] == "0" then
return 10
else
return list[1][3]
end
elseif list[1][1] == "equipment_sumstren_lv" then
return list[1][2]
else
return list[1][2] or 1
end
end
end
--删除字符串中的所有空格
function NoBlankStr(str)
local str = Trim(str)
str = string.gsub(str, "%s", "")
return str
end
--出现严重问题时触发后台报警流程
function UtilSentServerError( error_msg )
local server_name = "未知"
if LoginController and LoginController.Instance then
local playerInfo = LoginController.Instance:GetPlatUserInfo()
if playerInfo then
server_name = playerInfo.server_name or ""
end
end
local plat_name = ClientConfig.plat_name
local ticket = "e04201e54b49a941434c48d971b59af5"
local now_method = "send_voice"
local cur_time = tostring(os.time())
local post_param = {
time = cur_time,
method = now_method,
sign = string.lower(Util.md5( ticket .. cur_time .. now_method )),
server = server_name,
platform = plat_name,
game = "qhbgd",
issue = error_msg or "出问题了",
}
local call_func = function(ret,error_msg,data)
print("-- SentServerError result --",ret,error_msg,data)
end
local url = string.gsub(ClientConfig.php_website_error,"api.php","api_admin.php")
HttpUtil.HttpPostRequest(url, post_param, call_func)
end
--把数组的顺序打乱[只支持连续的自然数key值]
function DisruptListSequence(list)
if not list or type(list) ~= "table" or not next(list) then
return
end
local len = TableSize(list)
local end_list = {}
for i = 1, len do
local index = len - i + 1
if index > 0 then
local random_key = math.random(1, index)
table.insert(end_list, list[random_key])
table.remove(list, random_key)
end
end
for i,v in ipairs(end_list) do
table.insert(list, v)
end
end
function PrintResList()
local func = function(load_count,load_list,request_count,request_list,loading_count,loading_list,hight_count,hight_list,mid_count,mid_list,low_count,low_list)
local msg = string.format("res count:%d@%d@%d@%d@%d@%d",load_count,request_count,loading_count or 0,hight_count or 0,mid_count or 0,low_count or 0)
if request_count > 0 then
for i=1,request_count do
msg = msg .. "\n" .. "request:" .. request_list[i-1]
end
end
if load_count > 0 then
for i=1,load_count do
msg = msg .. "\n" .. "load:" .. load_list[i-1]
end
end
if loading_count and loading_count > 0 then
for i=1,loading_count do
msg = msg .. "\n" .. "loading_list:" .. loading_list[i-1]
end
end
if hight_count and hight_count > 0 then
for i=1,hight_count do
msg = msg .. "\n" .. "hight_list:" .. hight_list[i-1]
end
end
if mid_count and mid_count > 0 then
for i=1,mid_count do
msg = msg .. "\n" .. "mid_list:" .. mid_list[i-1]
end
end
if low_count and low_count > 0 then
for i=1,low_count do
msg = msg .. "\n" .. "low_list:" .. low_list[i-1]
end
end
GameError.Instance:SendErrorToPHP(msg,LogType.Warning)
print(msg)
end
resMgr:PrintResourceLog(func)
end
--- nNum 源数字
--- n 小数位数
function GetPreciseDecimal(nNum, n)
if type(nNum) ~= "number" then
return nNum
end
n = n or 0;
n = math.floor(n)
if n < 0 then
n = 0
end
local nDecimal = 10 ^ n
local nTemp = math.floor(nNum * nDecimal);
local nRet = nTemp / nDecimal;
return nRet
end
function AttachGameRoot( transform )
if not G_GAMEROOT_TRANSFORM then
G_GAMEROOT_TRANSFORM = GameObject.Find("root").transform
end
transform:SetParent(G_GAMEROOT_TRANSFORM)
end
--传入{ vector3,vector3,...}
function ToVector3Array( table )
if AppConst.EnglineVer >= 74 then
return Util.ToVector3Array( table )
else
return nil
end
end
--传入{ vector2,vector2,...}
function ToVector2Array( table )
if AppConst.EnglineVer >= 74 then
return Util.ToVector2Array( table )
else
return nil
end
end
function GetPathFiles(path,pre, match_str)
if EnglineVersion and AppConst_EnglineVer >= 70 then
return FileTools.GetPathFiles(path,pre, match_str)
end
return {}
end
function OutPutValue(file_name, str)
if EnglineVersion and AppConst_EnglineVer >= 70 then
return FileTools.OutPutValue(file_name, str)
end
end
function CheckPathExists(path)
if EnglineVersion and AppConst.EnglineVer >= 70 then
return FileTools.CheckPathExists(path)
end
return false
end
function MatchCfg(path, pre, match_str, config)
if EnglineVersion and AppConst.EnglineVer >= 70 then
return FileTools.MatchCfg(path, pre, match_str, config)
end
return false
end
function ClearTrailRenderer(game_object)
if TrailRenderer and game_object and not IsNull(game_object) then
local com = game_object:GetComponentsInChildren(typeof(TrailRenderer),true)
if com.Length > 0 then
for i=1,com.Length do
com[i-1]:Clear()
end
end
end
end
function GetAssetBundleDependList(ab_name, callback)
if tonumber(AppConst.EnglineVer) < 81 then
Message.show("低版本引擎不支持该功能")
return
end
local func = function(state,objs)
if state and objs then
callback(objs)
else
callback(nil)
end
end
resMgr:GetDependResList(ab_name,func)
end
function ExportTerrainPreloadConfig()
local preload_res = {}
local function search_Dependencies(res,scene_id)
local function callback(objs)
if objs then
local len = objs.Length
for i = 1, len do
local str = objs[i-1]
local a,b = string.find(str, "/.*%.")
local name = string.sub(str,a+1,b-1)
if not preload_res[name] and not string.find(name,"shader") then
preload_res[name] = scene_id
end
end
end
end
GetAssetBundleDependList(res, callback)
end
local scene_list = Split(StepPackModule.PRELOAD_MAP_RES,",")
for _,scene_id in ipairs(scene_list) do
local name = "model"..scene_id
local config = Config[name]
if config then
for _, item in ipairs(config) do
local res = "terrain_prefab_"..item[1]
if not preload_res[res] then
preload_res[res] = scene_id
search_Dependencies(res,scene_id)
end
end
local data = ConfigItemMgr.Instance:GetSceneItem(scene_id)
if data then
local obj_cfg = nil
local res = nil
if data.Npcs then
for id, _ in pairs(data.Npcs) do
obj_cfg = ConfigItemMgr.Instance:GetNpcItem(id)
if obj_cfg and obj_cfg.icon > 0 then
res = "model_clothe_"..obj_cfg.icon
if not preload_res[res] then
preload_res[res] = scene_id
end
end
end
end
if data.mon then
for _, id in ipairs(data.mon) do
obj_cfg = ConfigItemMgr.Instance:GetMonsterDataItem(id)
if obj_cfg and obj_cfg.icon > 0 then
res = "model_clothe_"..obj_cfg.icon
if not preload_res[res] then
preload_res[res] = scene_id
end
end
end
end
else
LogError("场景DB文件缺失数据,id = " .. scene_id)
end
end
end
local preload_res_map = {}
local list_temp
for res, scene_id in pairs(preload_res) do
preload_res_map[scene_id] = preload_res_map[scene_id] or {}
list_temp = preload_res_map[scene_id]
list_temp[#list_temp+1] = res
end
local function sort_func(a,b)
return a < b
end
for scene_id, list in pairs(preload_res_map) do
table.sort(list, sort_func)
end
for _,scene_id in ipairs(scene_list) do
list_temp = preload_res_map[scene_id]
if list_temp then
table.insert(list_temp, 1, "terrain_scene_"..scene_id)
else
preload_res_map[scene_id] = {[1] = "terrain_scene_"..scene_id}
list_temp = preload_res_map[scene_id]
end
if Config.ConfigSceneEffect.EffectInfo[tonumber(scene_id)] then
local particle_name = scene_id .. "effect"
local file_path = AppConst.AppDataPath.."/StreamingAssets/rdata/" .. particle_name .. ".syrd"
local file = io.open(file_path, "rb")
if file then
table.insert(list_temp,particle_name)
else
print(file_path .. " is not exist")
end
end
end
local str = [[
--预加载的场景由策划配置,为新手200级使用的地图资源的顺序
--每个场景预加载配置承接上个场景,即上个场景出现的资源配置不需要在之后的场景配置中(上个场景配置了,就已经预加载了,不需要重复配置)
]]
str = str.."Config.ConfigTerrainPreload = \n{\n"
for _, scene_id in ipairs(scene_list) do
local list = preload_res_map[scene_id]
if list then
str = str.." ["..scene_id.."] =\n {\n"
for i, res in ipairs(list) do
res = Util.GetBase64String(string.lower(res))
str = str.." ["..i.."] = "..[["]]..res..[["]]..",\n"
end
str = str.." },\n"
end
end
str = str.."}\n"
local fileName = AppConst.AppDataPath.."/Lua/config/client/ConfigTerrainPreload.lua"
local f = assert(io.open(fileName,'w'))
f:write(str)
f:close()
end
function SortTerrainShaderResUse()
local map_list = {1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,2001,2081,2102,2400,2500,3001,3100,3200,4001,4063,4064,4100,4200,4300,6100,7001,7100,7200}
local str
local shader_list = {}
local cache = {}
for index,map in pairs(map_list) do
local name = "model"..map
local config = Config[name]
if config then
for _, item in ipairs(config) do
local obj = item[1] .." " .. map
local shader = item[19]
if shader then
if not shader_list[shader] then
shader_list[shader] = {}
end
if not cache[obj] then
cache[obj] = true
table.insert(shader_list[shader],obj)
end
else
print("----------------shader is empty--------------",map,obj)
end
end
end
end
local str = "Config.ConfigTerrainShaderUse = \n{\n"
for shader, data in pairs(shader_list) do
str = str.." ["..[["]] .. shader .. [["]] .."] =\n {\n"
for i, res in ipairs(data) do
str = str.." ["..i.."] = "..[["]]..res..[["]]..",\n"
end
str = str.." },\n"
end
str = str.."}\n"
local fileName = AppConst.AppDataPath .."/Lua/config/client/ConfigTerrainShaderUse.lua"
local f = assert(io.open(fileName,'w'))
f:write(str)
f:close()
end
function SetSystemClipboard(value)
SDKUtil.CallSDKFunc("SystemData","Clipboard",{ data = tostring(value) })
end
function GetNoNewPlayerSmallMonster()
local mon = {}
for i=1000,9999 do
local data = ConfigItemMgr.Instance:GetSceneItem(i)
if data then
for _, id in ipairs(data.mon) do
local mon_cfg = ConfigItemMgr.Instance:GetMonsterDataItem(id)
if mon_cfg then
mon[mon_cfg.icon] = true
end
end
end
end
local data = ConfigItemMgr.Instance:GetSceneItem(1000)
if data then
for _, id in ipairs(data.mon) do
local mon_cfg = ConfigItemMgr.Instance:GetMonsterDataItem(id)
if mon_cfg then
mon[mon_cfg.icon] = nil
end
end
end
local sort_mon = {}
for i in pairs(mon) do
if i ~= nil then
table.insert(sort_mon, i)
end
end
table.sort(sort_mon, function(a,b) return (a < b) end)
for k,v in ipairs(sort_mon) do
print("------monster---------",v)
end
end
--输出定时器
function PrintTimerQuest()
local timer = GlobalTimerQuest
local str = ""
str = str.."timer_list:\n"
for i,vo in pairs(timer.timer_list) do
if vo.loop ~= 0 then
str = str.."TimerQuest:"..tostring(vo.source).."\n"
end
end
str = str.."\n\n"
str = str.."timer_list2:\n"
for i,vo in pairs(timer.timer_list2) do
if vo.loop ~= 0 then
str = str.."TimerQuest:"..tostring(vo.source).."\n"
end
end
str = str.."\n\n"
str = str.."timer_list3:\n"
for i,vo in pairs(timer.timer_list3) do
if vo.loop ~= 0 then
str = str.."TimerQuest:"..tostring(vo.source).."\n"
end
end
print(str)
local fileName = AppConst.AppDataPath.."/StreamingAssets/log/timer_quest.txt"
local f = assert(io.open(fileName,'w'))
f:write(str)
f:close()
end
--注册分帧执行器
function RegisterFraming(ref_tar,func_list,need_framing_load,interval,end_callback)
local func_len = #func_list
if not ref_tar or ref_tar._use_delete_method or func_len < 1 then
return
end
if ref_tar.framing_timer_id then
GlobalTimerQuest:CancelQuest(ref_tar.framing_timer_id)
ref_tar.framing_timer_id = nil
end
if need_framing_load == nil then
need_framing_load = true
end
if need_framing_load then
interval = interval or 0.01
local frame = 0
local function frame_func()
frame = frame + 1
local args = func_list[frame]
if type(args) == "function" then
args(ref_tar)
elseif type(args) == "table" then
if type(args[1]) == "function" then
args[1](ref_tar, unpack(args,2))
end
end
if func_len == frame then
if end_callback then
end_callback()
end
if ref_tar.framing_timer_id then
GlobalTimerQuest:CancelQuest(ref_tar.framing_timer_id)
ref_tar.framing_timer_id = nil
end
end
end
ref_tar.framing_timer_id = GlobalTimerQuest:AddPeriodQuest(frame_func, interval)
else
for _, args in ipairs(func_list) do
if type(args) == "function" then
args(ref_tar)
elseif type(args) == "table" then
if type(args[1]) == "function" then
args[1](ref_tar, unpack(args,2))
end
end
end
end
end
--界面销毁时取消分帧执行器
function UnregisterFraming(ref_tar)
if ref_tar.framing_timer_id then
GlobalTimerQuest:CancelQuest(ref_tar.framing_timer_id)
ref_tar.framing_timer_id = nil
end
end
function SetGoodsIcon(ref_tar, icon_img, type_id, setNativeSize, width, height, x, y)
local basic = GoodsModel:getInstance():GetGoodsBasicByTypeId(type_id)
lua_resM:setOutsideImageSprite(ref_tar,icon_img,GameResPath.GetGoodsIcon(basic.goods_icon),setNativeSize)
if width and height then
SetSizeDelta(icon_img.transform, width, height)
end
if x and y then
SetAnchoredPosition(icon_img.transform, x, y)
end
end
function FindInScene(str)
local args = Split(str, "/")
if #args < 2 then
return GameObject.Find(str)
else
local root = GameObject.Find(args[1])
if root then
local len = string.len(args[1])+2
str = string.sub(str,len)
local child = root.transform:Find(str)
if child then
return child.gameObject
end
end
end
end
function SetFogStartDistance( value )
local render = UnityEngine.RenderSettings
if render then
render.fogStartDistance = value
end
end
function SetFogEndDistance( value )
local render = UnityEngine.RenderSettings
if render then
render.fogEndDistance = value
end
end
function SetGreenScreen(target)
local GreenImage = UiFactory.createChild(target,UIType.Image,"GreenImage")
local Image = GreenImage:GetComponent("Image")
Image.raycastTarget = false
Image.color = Color(0,1,0.13,1)
Image.sprite = nil
GreenImage:GetComponent("RectTransform").sizeDelta = Vector2(2000,1500)
end
-------------------------
--获取是否为百分比属性
function GetPropIsPercent( id )
id = id or 0
return (Config.ConfigItemAttr.Normal[id] and Config.ConfigItemAttr.Normal[id].is_percent) and id or false
end
function GetPropIsBasePercent( id )
id = id or 0
local tab = {
base_att = 1,
base_maxHp = 2,
base_def = 4,
base_hit = 5,
base_dodge = 6,
base_crit = 7,
base_ten = 8,
base_abs_att = 15,
base_abs_def = 16,
}
if (Config.ConfigItemAttr.Normal[id] and Config.ConfigItemAttr.Normal[id].base_per_add) then
return Config.ConfigItemAttr.Normal[id].base_per_add,tab[Config.ConfigItemAttr.Normal[id].base_per_add]
else
return false
end
end
--获取角色属性列表
function GetRolePropList( )
local mainVo = RoleManager.Instance.mainRoleInfo
return {
[1] = mainVo.att or 0,
[2] = mainVo.maxHp or 0,
[4] = mainVo.def or 0,
[5] = mainVo.hit or 0,
[6] = mainVo.dodge or 0,
[7] = mainVo.crit or 0,
[8] = mainVo.ten or 0,
[9] = mainVo.hurt_add_ratio or 0,
[10] = mainVo.hurt_del_ratio or 0,
[11] = mainVo.hit_ratio or 0,
[12] = mainVo.dodge_ratio or 0,
[13] = mainVo.crit_ratio or 0,
[14] = mainVo.uncrit_ratio or 0,
[15] = mainVo.abs_att or 0,
[16] = mainVo.abs_def or 0,
[19] = mainVo.att_add_ratio or 0,
[20] = mainVo.hp_add_ratio or 0,
[22] = mainVo.def_add_ratio or 0,
[23] = mainVo.hit_add_ratio or 0,
[24] = mainVo.dodge_add_ratio or 0,
[25] = mainVo.crit_add_ratio or 0,
[26] = mainVo.ten_add_ratio or 0,
[27] = mainVo.skill_hurt_add_ratio or 0,
[28] = mainVo.skill_hurt_del_ratio or 0,
[29] = mainVo.final_hurt_add_ratio or 0,
[30] = mainVo.final_hurt_del_ratio or 0,
[48] = mainVo.parry_ratio or 0,
[49] = mainVo.stab_ratio or 0,
[50] = mainVo.pvp_hurt_del_ratio or 0,
[51] = mainVo.pvp_hurt_add_ratio or 0,
[52] = mainVo.crit_hurt_add_ratio or 0,
[53] = mainVo.crit_hurt_del_ratio or 0,
[54] = mainVo.heart_ratio or 0,
[55] = mainVo.heart_add_hurt or 0,
[56] = mainVo.heart_resist_ratio or 0,
[57] = mainVo.heart_del_hurt or 0,
[95] = mainVo.suck_blood or 0,
[96] = mainVo.suck_blood_add or 0,
[97] = mainVo.suck_blood_minus or 0,
[98] = mainVo.boss_hurt_add_ratio or 0,
[99] = mainVo.boss_hurt_del_ratio or 0,
[100] = mainVo.mon_hurt_add_ratio or 0,
[101] = mainVo.mon_hurt_del_ratio or 0,
}
end
--获取百分比属性的实际使用加成
function GetPropPercentAdd( attr_id,attr_num )
attr_id = attr_id or 0
attr_num = attr_num or 0
if not GetPropIsPercent(attr_id) then
return 0
end
attr_num = attr_num or 0
return (1 + (5 * attr_num - 10000) / (2 * attr_num + 10000) ) * GetPropOneAddNum(attr_id) * 0.0002
end
--获得属性的加成系数
function GetPropOneAddNum( attr_id )
attr_id = attr_id or 0
local num = 0
if Config.ConfigItemAttr.Normal[attr_id] and Config.ConfigItemAttr.Normal[attr_id].add_num then
num = Config.ConfigItemAttr.Normal[attr_id].add_num
end
return num
end
--[[
注意:is_have计算已有的属性战力,预览战力别传!
Author:LZR
Description:战力计算公式,做法就是计算出当前真实属性的战力,同时计算加上需要计算的属性之后,两者相减获得战力差值返回
parameters
list = {
[id] = { [1] = attr_id, [2] = attr_num },
}
list = {
[id] = { [1] = FuncId ,[2] = attr_id, [3] = attr_num }, 功能id
}
]]
function GetFighting( list,is_have )
list = list or {}
list = ComposeAttr(list)--合并属性
local cur_power = 0
local final_power = 0
-------------------------
--更改数据格式便于计算
local base_list = {}
for k,v in pairs(list) do
if #v == 3 then
base_list[tonumber(v[2])] = tonumber(v[3])
else
base_list[v[1]] = v[2]
end
end
-------------------------
local main_role = RoleManager.Instance.mainRoleInfo
if main_role then
-------------------------
--如果当前检查未获得的属性,包含了基础属性,那还要把那几个百分比基础加成加上去的参数补上
if not is_have then
local base_per_list = {[19] = true,[20] = true,[22] = true,[23] = true,[24] = true,[25] = true,26,[29] = true,[30] = true}
local base_add_id,match_id = 0, 0
local add_temp_num = 0
for k,v in pairs(base_per_list) do
base_add_id,match_id = GetPropIsBasePercent(k)
if base_add_id and base_list[match_id] then
--加成的这波属性,要算进基础属性百分比里面
add_temp_num = main_role[Config.ConfigItemAttr.Normal[k].tag] + (base_list[k] or 0)
base_list[match_id] = base_list[match_id] + math.floor( base_list[match_id] * add_temp_num/10000 )
end
end
end
-------------------------
--生成新旧属性表
local cur_prop_list = GetRolePropList()
local new_prop_list = DeepCopy(cur_prop_list)
for k,v in pairs(base_list) do
if new_prop_list[k] then
if is_have then
new_prop_list[k] = new_prop_list[k] - v
else
new_prop_list[k] = new_prop_list[k] + v
end
end
end
-------------------------
--百分比基础加成
for k,v in pairs(base_list) do
local base_add_id,match_id = GetPropIsBasePercent(k)
if base_add_id then
main_role[base_add_id] = main_role[base_add_id] or 1000
if is_have then
new_prop_list[match_id] = new_prop_list[match_id] - main_role[base_add_id]*(v / 10000)
else
new_prop_list[match_id] = new_prop_list[match_id] + main_role[base_add_id]*(v / 10000)
end
end
end
-------------------------
--罗列需要计算的属性id
local id_list = {
1,2,4,5,6,7,8,15,16,9,10,11,12,13,14,27,28,48,49,50,51,52,53,54,55,56,57,
95,96,97,98,99,100,101
}
-------------------------
--计算新旧战力
local PowerFactor_cur = 0
local PowerFactor_final = 0
for k,v in pairs(id_list) do
if GetPropIsPercent(v) then
PowerFactor_cur = PowerFactor_cur + GetPropPercentAdd(v,cur_prop_list[v])
PowerFactor_final = PowerFactor_final + GetPropPercentAdd(v,new_prop_list[v])
else
cur_power = cur_power + cur_prop_list[v] * GetPropOneAddNum( v )
final_power = final_power + new_prop_list[v] * GetPropOneAddNum( v )
end
end
cur_power = cur_power * (1 + PowerFactor_cur)
final_power = final_power * (1 + PowerFactor_final)
-------------------------
end
if is_have then
return math.floor(cur_power - final_power)
else
return math.floor(final_power - cur_power)
end
end
--判断模块是否开启
function GetModuleIsOpen( main_id,child_id,is_fade_show )
local _,conf = GetModuleOpenLevel(main_id,child_id)
if not conf or not RoleManager.Instance.mainRoleInfo then return end
-------------------------
local op_day,op_lv,op_task = 0,0,0
if is_fade_show and conf.icon_lv > 0 then
op_day = conf.icon_day
op_lv = conf.icon_lv
op_task = conf.icon_task or 0
else
op_day = conf.open_day
op_lv = conf.open_lv
op_task = conf.task_id or 0
end
-------------------------
local is_open = op_day == 0 or op_day <= ServerTimeModel:getInstance():GetOpenServerDay()--开服天数
is_open = is_open and MainUIModel:getInstance():GetFunOpenState(op_lv, op_task)--任务和等级
return is_open , conf
end
--获取开放等级, is_fade_show代表使用客户端的展示等级
function GetModuleOpenLevel( main_id,child_id,is_fade_show)
if not main_id then return end
child_id = child_id or 0
local base_conf = child_id == 0 and Config.Moduleid[main_id] or Config.Modulesub[main_id .. "@" .. child_id]
local open_lv = base_conf and base_conf.open_lv or 0
if is_fade_show and base_conf and base_conf.icon_lv > 0 then
return base_conf.icon_lv, base_conf
else
return open_lv, base_conf
end
end
--传入两属性,获得格式一样的属性
function GetAttrMatch( list_1,list_2,need_sort )
local data_1,data_2 = {},{}
list_1 = list_1 or {}
list_2 = list_2 or {}
for k,v in pairs(list_1) do
data_1[v[1]] = v[2]
end
for k,v in pairs(list_2) do
data_2[v[1]] = v[2]
end
-------------------------
for k,v in pairs(data_1) do
if not data_2[k] then
data_2[k] = 0
end
end
for k,v in pairs(data_2) do
if not data_1[k] then
data_1[k] = 0
end
end
-------------------------
local result_1,result_2 = {},{}
local index = 1
for k,v in pairs(data_1) do
result_1[index] = {k,v}
result_2[index] = {k,data_2[k]}
index = index + 1
end
-------------------------
if need_sort then
result_1 = SortAttrList(result_1)
result_2 = SortAttrList(result_2)
end
return result_1,result_2
end
--给属性列表排序,高级属性在前
function SortAttrList( list )
if not list then return {} end
local list_1 = {}
local list_2 = {}
for k,v in pairs(list) do
if WordManager:GetAttrIsSpecial(v[1]) then
table.insert( list_1, v )
else
table.insert( list_2, v )
end
end
local function sort_call( a,b )
return tonumber(a[1]) < tonumber(b[1])
end
if list_1[2] then
table.sort( list_1, sort_call )
end
if list_2[2] then
table.sort( list_2, sort_call )
end
for i,v in ipairs(list_2) do
table.insert( list_1, v )
end
return list_1
end
--通过condition获得关键值
function GetKeyValue( condition,key )
local value = nil
if condition then
for i,v in ipairs(condition) do
if v[1] and v[1] == key then
return v[2]
end
end
end
return value
end
--顺序表排序翻转
function StartToEnd(list)
if type(list) == "table" then
local len = #list
local new_list = {}
for i=1,len do
new_list[i] = list[len-i+1]
end
return new_list
end
end
-- 计算utf8字符串字符数, 各种中文算俩字符其他按一个字符计算
-- 为什么这么算呢 因为字号20的文本 在u3d里面
-- 例如utf8len("1你好") => 5 width = 5 *(20/2)
function utf8lenU3D(str)
local len = 0
local currentIndex = 1
while currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
if chsize(char) == 3 then
len = len + 2
else
len = len + 1
end
end
return len
end
--10进制数值转2进制 以table形式返回
--从左往右读
function TenbyteToTwobyte(num)
local num_table = {};
while num ~= 0 do
table.insert(num_table, math.fmod(num, 2));
num = math.floor(num/2)
end
return num_table
end
-- 属性图标根据颜色类型
function SetAttrIconByColorType(ref_tar, img_component, attr_id, force, color_type)
if not ref_tar or not img_component then return end
local color_list = {
[1] = "7d91ac",--暗淡的蓝色
[2] = "fdfdc9",--黄色
[3] = "ffffff",--白色
[4] = "a9c1e1",--浅蓝
}
img_component.color = ColorUtil:ConvertHexToRGBColor(color_list[color_type])
local a_name,b_name = GameResPath.GetAttrIcon(attr_id, force, 1)
lua_resM:setImageSprite(ref_tar, img_component, a_name, b_name, true)
end
function UrlEncode(s)
s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
return string.gsub(s, " ", "+")
end
function UrlDecode(s)
s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
return s
end
--货币单位
function GetPriceCompany( )
return ""
end
--合并两属性列表,结果会写入list_a
function CombineAttrList( list_a, list_b )
if not list_a or not list_b then return {} end
for kk,vv in pairs(list_b) do
local has_attr = false
for k,v in pairs(list_a) do
if v[1] == vv[1] then
v[2] = v[2]+vv[2]
has_attr = true
break
end
end
if not has_attr then
table.insert(list_a, vv)
end
end
return list_a
end
--获取属性差值,以attr_list2减去attr_list1的每个属性值,write_to_witch_list为1或2或nil,指定要把差值写入attr_list1还是attr_list2
function GetAttributeOffset( attr_list1, attr_list2, write_to_witch_list )
local result = {}
for k,v in pairs(attr_list2) do
local has_attr = false
for kk,vv in pairs(attr_list1) do
if v.index and v.index == vv.index then
result[v.index] = v.attr_value-vv.attr_value
has_attr = true
if write_to_witch_list then
if write_to_witch_list == 1 then
vv.add_attr = result[vv.index]
vv.add_attr_for_show = WordManager:GetPropertyValue(vv.index, vv.add_attr)
else
v.add_attr = result[v.index]
v.add_attr_for_show = WordManager:GetPropertyValue(v.index, v.add_attr)
end
end
break
elseif v[1] and v[1] == vv[1] then
--有些是用数组的,这里兼容下
result[v[1]] = v[2]-vv[2]
has_attr = true
if write_to_witch_list then
if write_to_witch_list == 1 then
vv.add_attr = result[vv[1]]
vv.add_attr_for_show = WordManager:GetPropertyValue(vv[1], vv.add_attr)
elseif write_to_witch_list == 2 then
v.add_attr = result[v[1]]
v.add_attr_for_show = WordManager:GetPropertyValue(v[1], v.add_attr)
end
end
break
end
end
if not has_attr then
--如果在列表1里没找到
if v.attr_value then
result[v.index] = v.attr_value
if write_to_witch_list then
if write_to_witch_list == 1 then
vv.add_attr = vv.attr_value
vv.add_attr_for_show = WordManager:GetPropertyValue(vv.index, vv.add_attr)
else
v.add_attr = v.attr_value
v.add_attr_for_show = WordManager:GetPropertyValue(v.index, v.add_attr)
end
end
elseif v[2] then
result[v[1]] = v[2]
if write_to_witch_list then
if write_to_witch_list == 1 then
vv.add_attr = vv[2]
vv.add_attr_for_show = WordManager:GetPropertyValue(vv[1], vv.add_attr)
else
v.add_attr = v[2]
v.add_attr_for_show = WordManager:GetPropertyValue(v[1], v.add_attr)
end
end
end
end
end
local new_attr_list = {}
for k,v in pairs(result) do
table.insert(new_attr_list, {k,v})
end
return new_attr_list
end
--上面那个放大有毒算不对 太菜了 计算两属性的差值attr_list2 - attr_list1
function GetAttributeOffset2( attr_list1, attr_list2 )
attr_list1 = ComposeAttr(attr_list1)
attr_list2 = ComposeAttr(attr_list2)
local new_list = {}
local is_find = false
for i,v in ipairs(attr_list2) do
is_find = false
for ii,vv in ipairs(attr_list1) do
if v[1] == vv[1] then
is_find = true
new_list[#new_list + 1] = {v[1],v[2]-vv[2] > 0 and v[2]-vv[2] or 0}
break
end
end
if not is_find then
new_list[#new_list + 1] = {v[1],v[2]}
end
end
return new_list
end
--合并相同属性值
function ComposeAttr( attr_list )
local com_list = {}--合并同样属性的战力值
for i,v in ipairs(attr_list) do
if not com_list[v[1]] then
com_list[v[1]] = {v[1],v[2]}
else
com_list[v[1]] = {v[1],v[2]+com_list[v[1]][2]}
end
end
local fight_attr_list = {}
for i,v in pairs(com_list) do
fight_attr_list[#fight_attr_list + 1] = v
end
return fight_attr_list
end
-- 根据字符长度限制文本展示内容,超过字符限制的内容就用...或addition_str代替
-- 例如: LimitTextByCharNum(玩家名称): 玩家名称
-- LimitTextByCharNum(玩家名称称): 玩家名称...
function LimitTextByCharNum(txt_str, len, sub_len, addition_str)
if not txt_str then return "" end
len = len or 4 -- 默认四个字符
sub_len = sub_len or len -- 截断位置,默认跟长度字符数相等
addition_str = addition_str or "..."
if utf8len(txt_str) > len then --
txt_str = SubStringUTF8(txt_str, 1, sub_len) .. addition_str
end
return txt_str
end
-- 转化角度
-- 类型1 将角度转化为 -180~180之间
function ClampAngleType1(angle)
if angle > 180 then
angle = angle - 360
elseif angle < -180 then
angle = angle + 360
end
return angle
end
-- 类型2 将角度转化为 0~360之间
function ClampAngleType2(angle)
if angle > 360 then
angle = angle - math.floor(angle / 360) * 360
elseif angle < 0 then
angle = angle + math.ceil(math.abs(angle) / 360) * 360
end
return angle
end
--设置七彩颜色字符串
function SetSevenColorStr( str )
str = str or ""
local new_str = ""
local len = #(string.gsub(str, "[\128-\191]", "")) -- 计算字符数(不是字节数)
if len > 0 then
local s = {}
local i = 1
for c in string.gmatch(str, ".[\128-\191]*" ) do -- 21.2 Pattern-Matching Functions
s[i]=c -- 21.7 Unicode
i=i+1
end
local color_index = 1
local max_color_list_len = #EquipModel.ColorList
for i,v in ipairs(s) do
new_str = new_str..HtmlColorTxt(v, EquipModel.ColorList[color_index])
color_index = color_index + 1
if color_index > max_color_list_len then
color_index = 1
end
end
end
return new_str
end
-- 随机打乱一个序列表的元素顺序
function RandomizeSequenceTableData(tb)
if not tb then return nil end
local ram_tb = {}
local len = #tb
for k = 1, len do
ram_tb[#ram_tb+1] = table.remove(tb, math.random(1, len - k + 1))
end
return ram_tb
end
-- 当有输入框然后又有字数限制的时候,要获取限制内的字符串就用这个方法,例:
-- new_str1 = abc啊啊啊 => abc啊啊啊
-- new_str2 = efgd啊啊啊 => efgd啊啊
-- new_str3 = ed啊啊aa啊啊 => ed啊啊aa(都是默认限制6位)
function GetInputLimitResultStr(str, limit)
limit = limit or 6
local len = #(string.gsub(str, "[\128-\191]", "")) -- 计算字符数(不是字节数)
local new_str = ""
local i = 0
if len > 0 then
for c in string.gmatch(str, ".[\128-\191]*" ) do -- 21.2 Pattern-Matching Functions
i = i + 1
new_str = new_str .. c
if i >= limit then
break
end
end
return new_str
end
return ""
end
function UrlEncode(s)
s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
return string.gsub(s, " ", "+")
end
function UrlDecode(s)
s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
return s
end
function ScreenShot( )
local name = "screenshot"..TimeUtil:getServerTime( )
local png_path = "phone/"..name..".png"
local save_path = Util.DataPath..png_path
if SystemRuntimePlatform.IsAndroid() then
local game_path = "luaFramework/"
save_path = game_path..png_path
end
if UnityEngine and UnityEngine.ScreenCapture then
UnityEngine.ScreenCapture.CaptureScreenshot(save_path)
end
local function on_delay( )
Message.show("截图成功:"..save_path)
end
setTimeout(on_delay, 1)
end