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
|