Explorar el Código

皮肤功能提交代码

249435196@qq.com hace 1 año
padre
commit
439d0f3bb3

+ 8 - 0
script/module/bag/ItemLogic.lua

@@ -28,6 +28,7 @@ local DropExchangeLogic = require("absAct.DropExchangeLogic")
 local HeroGrowUp = require("absAct.HeroGrowUp")
 local BuyExcel = require("excel.buy")
 local LostTempleLogic = require("lostTemple.lostTempleLogic")
+local SkinLogic = require("skin.SkinLogic")
 
 cmd 		= {}
 
@@ -334,6 +335,13 @@ function cmd.lostRevice(data, human, value)
 
    return true
 end
+
+function cmd.skinGen(data,human,skinId)
+    if data.left < 1 then return end
+    SkinLogic.skinUnlock(human,skinId)
+    return true
+end
+
 -----------------------------------------------------------------------------
 
 -- 仅使用道具,不扣道具

+ 14 - 3
script/module/hero/HeroLogic.lua

@@ -190,10 +190,10 @@ end
 
 -- 时装
 function doCalcHeroSkin(skinID, attrs)
-	local skinConfig = SkinExcel.skin[skinID]
+	--[[local skinConfig = SkinExcel.skin[skinID]
 	for _, v in ipairs(skinConfig.attrs) do
 		RoleAttr.updateValue(v[1], v[2], attrs)
-	end	
+	end]]
 end
 
 -------------------------------------------------------------------------------------
@@ -529,7 +529,7 @@ function delHeroByIndex(human, index, logType, noSend)
 		return
 	end
 	
-	SkinLogic.onDelHero(human, index)
+	--SkinLogic.onDelHero(human, index)
 	local heroGrid = human.db.heroBag[index]	
     human.db.heroBag[index] = nil
 	human.heroAttrs[index] = nil
@@ -1396,6 +1396,17 @@ function huituiHero(human, heroID, heroIndex)
 	checkChangeMaxZDL(human, heroGrid)
 end
 
+function getHeroListById(human,heroId)
+	local heroDBBag = human.db.heroBag
+	local list = {}
+	for idx,grid in pairs(heroDBBag) do
+		if heroGrid.id ~= heroId then
+			list[#list+1] = idx
+		end
+	end
+	return list
+end
+
 function getHeroGrid(human, heroID, heroIndex)
     if not heroID then return end
     if not heroIndex then return end

+ 5 - 3
script/module/role/RoleAttr.lua

@@ -23,7 +23,6 @@ local FuwenLogic = require("fuwen.FuwenLogic")
 local HeroLogic = require("hero.HeroLogic")
 local HeroEquip = require("hero.HeroEquip")
 local RoleDefine = require("role.RoleDefine")
-local SkinLogic = require("skin.SkinLogic")
 local TheStarsLogic = require("theStars.TheStarsLogic")
 local UnionTecLogic = require("union.UnionTecLogic")
 local MoshouLogic = require("moshou.MoshouLogic")
@@ -133,9 +132,12 @@ function calcHeroGrid(heroGrid, index, human)
 
 	--不同模块在英雄属性计算 begin
 	HeroLogic.doCalcHero(heroGrid, HERO_BASE_ATTRS) -- 基础属性
+	-- 防止循环引用
+	local SkinLogic = require("skin.SkinLogic")
 	local heroSkinID, heroSkinSkill = SkinLogic.checkHeroSkin(human, index) 
-	if heroSkinID and heroSkinSkill then -- 皮肤属性
-		HeroLogic.doCalcHeroSkin(heroSkinID, HERO_OTHER_ATTRS)
+	if heroSkinID then -- 皮肤属性
+		--HeroLogic.doCalcHeroSkin(heroSkinID, HERO_OTHER_ATTRS)
+		SkinLogic.doCalcSkinHero(human,HERO_BASE_ATTRS)
 	end
 	BeSkill.doCalcHero(heroGrid, HERO_BASE_ATTRS, heroSkinSkill) -- 被动技能属性
 	HeroEquip.doCalcHero(heroGrid, HERO_OTHER_ATTRS) -- 装备

+ 1 - 1
script/module/role/RoleDBLogic.lua

@@ -201,7 +201,7 @@ function createDefaultRole(account)
 		onlineTime = nil,						-- 在线时长
 		onlineTimeDay = nil, 					-- 本日在线时长	
 		onlineTimeDayReport = nil,	
-		heroBag = {[0] = HeroDefine.HERO_BAG_CNT},		-- 英雄背包[index] ={id,lv等级,quality品阶}
+		heroBag = {[0] = HeroDefine.HERO_BAG_CNT},		-- 英雄背包[index] ={id,lv等级,quality品阶,skin皮肤列表}
 		heroLevelUpgrade = 0,                   -- 英雄手动升级最大值
 		bag = {},								-- 道具背包 {itemID->itemCnt}
 		fuwenBag = {},							-- 符文背包 [index] = {id, 属性, 技能}

+ 9 - 94
script/module/skin/Proto.lua

@@ -1,9 +1,12 @@
 local Attr = require("role.Proto").Attr
-local ItemData = require("bag.Proto").ItemData
+----------------------------------------------------------------------------------
 
+-- 皮肤数据查询
 CG_SKIN_BAG = {}
+
 SkinNet = {
 	{"id",		1,		"int"},  --id
+	{"heroId",  1,      "int"}, -- 英雄ID
 	{"heroName",	1,		"string"},  --英雄名字
 	{"name",	1,		"string"},  --名字
 	{"desc",	1,		"string"},  --描述
@@ -13,13 +16,7 @@ SkinNet = {
 	{"camp",    1,      "int"},  --阵营
 	{"order",	1,		"int"},  --配置表排序
 	{"type",	1,		"byte"},  --类型
-	{"upID",		1,		"int"},  --0不可升级,大于0为下一级的皮肤id
 	{"attrs",	5,		Attr},  --属性
-	{"fenjie",		2,		ItemData},  --空道具不可分解,分解产出
-	{"upAddExp",		1,		"int"},  --0不可被用来升级,大于0被用来升级增加的经验值
-	{"upNeedExp",		1,		"int"},  --0不可升级,大于0可升级
-	{"ronghe",	1,		"byte"},  --0不可融合,1可融合
-	{"quality",	1,		"byte"},  --品阶
 }
 SkinBagNet = {
 	{"data",	1,	SkinNet},
@@ -28,107 +25,25 @@ SkinBagNet = {
 }
 GC_SKIN_BAG = {
 	{"isEnd",		1,		"byte"},  --分包 1第一个包 2其他 3 最后一个包
-	{"list",	30,		SkinBagNet},
+	{"list",	256,		SkinBagNet},
 }
 
 SkinUpdateNet = {
 	{"data",		1,		SkinBagNet},
 	{"op",		1,		"byte"},  --1 新增 2 删除 3 更新
 }
+-- 获得皮肤推送
 GC_SKIN_UPDATE = {
 	{"list",	30,		SkinUpdateNet},
 }
-CG_SKIN_FENJIE = {
-	{"ind",		1,		"int"},  --皮肤索引
-}
-GC_SKIN_FENJIE = {
-	{"ind",		1,		"int"},  --皮肤索引
-}
-
-CG_SKIN_UP_QUERY = {
-	{"ind",		1,		"int"},  --皮肤索引
-}
-
-GC_SKIN_UP_QUERY = {
-	{"ind",		1,		"int"},   --皮肤索引
-	{"nowData",		1,		SkinNet},  --当前皮肤
-	{"upData",	1,		SkinNet},   --升级后皮肤
-	{"nowExp",		1,		"int"},  --当前经验值
-	{"maxExp",		1,		"int"}, --需要经验值
-}
-
-CG_SKIN_UP = {
-	{"ind",		1,		"int"},  --��������
-	{"list",		10,		"int"},  --��������
-}
-
-GC_SKIN_UP = {
-	{"ind",		1,		"int"}, 
-	{"nowData",		1,		SkinNet},  --��ǰƤ��
-	{"upData",	1,		SkinNet},  --������Ƥ��
-	{"nowExp",		1,		"int"}, --��ǰ����ֵ
-	{"maxExp",		1,		"int"}, --��Ҫ����ֵ
-}
-
-SkinPreviewNet = {
-	{"data",    1,      SkinNet}, 
-	{"weight",    1,      "int"},  --Ȩ��
-}
-
-CG_SKIN_SUIPIAN_PREVIEW = {
-	{"id",		1,		"int"}, --Ƥ����Ƭid
-}
-
-GC_SKIN_SUIPIAN_PREVIEW = {
-	{"id",		1,		"int"},
-	{"list",		20,		SkinPreviewNet},
-}
-CG_SKIN_SUIPIAN = {
-	{"id",		1,		"int"}, --Ƥ����Ƭid
-	{"cnt",		1,		"int"}, 
-}
-GC_SKIN_SUIPIAN = {
-	{"id",		1,		"int"}, --Ƥ����Ƭid
-	{"out",		10,		SkinNet},  --����
-}
-
-CG_SKIN_RONGHE_PREVIEW = {
-}
-
-GC_SKIN_RONGHE_PREVIEW = {
-	{"list",		20,		SkinPreviewNet},
-}
-
-CG_SKIN_RONGHE = {
-	{"list",		10,		"int"},  --�ں���������
-}
-
-GC_SKIN_RONGHE = {
-	{"out",		1,		SkinNet},  --����
-}
-
-CG_SKIN_HERO = {
-	{"heroInd",		1,		"int"},
-}
-
-GC_SKIN_HERO = {
-	{"list",		10,	SkinBagNet}--ind=0 δӵ��Ƥ����ind>0 Ƥ������
-}
 
+-- 穿戴皮肤
 CG_SKIN_ON = {
-	{"skinInd",		1,		"int"}, -- skinInd = 0 δ����Ƥ����>0 ���϶�ӦƤ��
+	{"skinIn",		1,		"int"}, -- skinId = 0 脱下皮肤,>0 穿上对应皮肤ID
 	{"heroInd",		1,		"int"},
 }
 
 GC_SKIN_ON = {
-	{"heroInd",		1,		"int"},
+	{"heroId",		1,		"int"},
 	{"skinInd",		1,		"int"}, 
 }
-
-CG_SKIN_BOOK = {
-
-}
-GC_SKIN_BOOK = {
-	{"isEnd",		1,		"byte"},  --�ְ� 1��һ���� 2���� 3 ���һ����
-	{"list",		30,	SkinBagNet}--ind=0 δӵ��Ƥ����ind=1 ��ʷӵ�й�
-}

+ 219 - 559
script/module/skin/SkinLogic.lua

@@ -13,15 +13,7 @@ local HeroExcel = require("excel.hero").hero
 local SkillExcel = require("excel.skin").skill
 local OutExcel = require("excel.skin").out
 local ItemExcel = require("excel.item").item
-
-function initAfterHot()
-	for _,outConf in pairs(OutExcel) do
-		outConf.totalWeight = 0
-		for _,v in ipairs(outConf.out) do
-			outConf.totalWeight = outConf.totalWeight + v[2]
-		end
-	end
-end
+local RoleAttr = require("role.RoleAttr")
 
 local function getBag(human)
 	if not (human.skinBag and human.heroSkin) then
@@ -55,561 +47,133 @@ local function getBag(human)
 	return human.db.skinBag
 end
 
-local function fontSkinNet(data,id)
-	if not id or id == 0 then
-		data.id = 0
-		data.name = ""
-		data.desc = ""
-		data.head = 0
-		data.body = ""
-		data.icon = 0
-		data.camp = 0
-		data.order = 0
-		data.type = 0
-		data.upID = 0
-		data.attrs[0] = 0
-		data.fenjie[0] = 0
-		data.upAddExp = 0
-		data.upNeedExp = 0
-		data.ronghe = 0
-		data.heroName = ""
-		data.quality = 0
-	else
-		local conf = SkinExcel[id]
-		data.id = id
-		data.name = conf.name
-		data.desc = conf.desc
-		data.head = conf.head
-		data.body = conf.body
-		data.icon = conf.icon
-		data.camp = conf.camp
-		data.order = conf.order
-		data.type = conf.type
-		data.upID = conf.upID
-		local len = 0
-		for k,v in ipairs(conf.attrs) do
-			len = len + 1
-			data.attrs[len].key = v[1]
-			data.attrs[len].value = v[2]
-		end
-		data.attrs[0] = len
-		len = 0
-		for k,v in ipairs(conf.fenjie) do
-			len = len + 1
-			Grid.makeItem(data.fenjie[len],v[1],v[2])
-		end
-		data.fenjie[0] = len
-		data.upAddExp = conf.upAddExp
-		data.upNeedExp = conf.upNeedExp
-		data.ronghe = conf.ronghe
-		data.heroName = HeroExcel[conf.id] and HeroExcel[conf.id].name or ""
-		data.quality = conf.quality
-	end
-end
-
-local function fontBagNet(net,human,ind)
-	net.ind = ind or 0
-	if human.db.skinBag[ind] then
-		net.isOn = human.db.skinBag[ind].heroInd and 1 or 0
-		fontSkinNet(net.data,human.db.skinBag[ind].id)
-	else
-		net.isOn = 0
-		fontSkinNet(net.data)
-	end
-end
-
-function bag(human)
-	local bagDB = getBag(human)
-	local msgRet = Msg.gc.GC_SKIN_BAG
-	local len = 0
-	msgRet.isEnd = 1
-	for k in pairs(human.skinBag) do
-		len = len + 1
-		local net = msgRet.list[len]
-		fontBagNet(net,human,k)
-		if len >=30 then
-			msgRet.list[0] = 30
-			Msg.send(msgRet,human.fd)
-			len = 0
-			msgRet.isEnd = 2
-		end
-	end
-
-	msgRet.isEnd = 3
-	msgRet.list[0] = len
-	Msg.send(msgRet,human.fd)
-
-end
-
-OP_ADD = 1
-OP_UPDATE = 2
-OP_DEL = 3
-function sendChange(human,changeList)
-	if #changeList == 0 then
-		return
-	end
-	table.sort(changeList,function(a,b)
-		return a[2] > b[2]
-	end)
-	local msgRet = Msg.gc.GC_SKIN_UPDATE
-	local len = 0
-	for _,v in ipairs(changeList) do
-		len = len + 1
-		local net = msgRet.list[len]
-		net.op = v[2]
-		fontBagNet(net.data,human,v[1])
-		if len >= 30 then
-			break
-		end
-	end
-	msgRet.list[0] = len
-	Msg.send(msgRet,human.fd)
-end
-
-function onAddSkin(human,id,list)
-	local ind 
-	for i = 1,human.db.skinBag[0] do
-		if not human.db.skinBag[i] then
-			ind = i
-			break
-		end
-	end
-	local skinConf = SkinExcel[id]
-	if ind and skinConf then
-		human.db.skinBag[ind] = {id = id}
-		human.skinBag = nil
-		list[#list + 1] = {ind,OP_ADD}
-		RoleHeadLogic.active(human, RoleHeadLogic.HEAD_TYPE_1, skinConf.head)
-		return ind
-	end
-end
-
-function onDelSkin(human,ind,list)
-	if human.db.skinBag[ind] then
-		human.db.skinBag[ind] = nil
-		human.skinBag = nil
-		list[#list + 1] = {ind,OP_DEL}
-		return ind
-	end
-end
-
-function checkDel(human,list)
-	if #list == 0 then
-		return Broadcast.sendErr(human, "empty checkDel:"..Lang.SKIN_PARAM_ERR)
-	end
-	local bagDB = getBag(human)
-	for _,v in ipairs(list) do
-		if not bagDB[v] then
-			return Broadcast.sendErr(human, Lang.SKIN_NO_HAS)
-		elseif bagDB[v].heroInd then
-			return Broadcast.sendErr(human, Lang.SKIN_IS_ON)
-		end
-	end
-	return true
-end
-
-function delSkin(human,delList,changeList)
-	if checkDel(human,delList) then
-		for _,v in ipairs(delList) do
-			onDelSkin(human,v,changeList)
-		end
-		return true
-	end
+--[[
+    skin = {
+        ttl = number -- 有效时长 -1表示永久
+        state = number -- 0表示未穿戴 1 表示穿戴
+    } -- skin 拥有唯一性
+]]
+
+-- 获取所有皮肤信息
+local function skinListQuery(human)
+    local skinBag = human.db.skinBag
+    local ret = {}
+    for id,data in pairs(skinBag) do 
+        ret[id] = {
+            id = id,
+            ttl = data.ttl,
+            state = data.state,
+        }
+    end
+    return ret
 end
 
-function addSkin(human,id,cnt)
-	if not SkinExcel[id] then
-		return
-	end
-	cnt = cnt or 1
-	local changeList = {}
-	for i = 1,cnt do
-		onAddSkin(human,id,changeList)
-	end
-	sendChange(human,changeList)
-	human.db.skinLog[id] = 1
+-- 获取皮肤为skinId的皮肤
+local function skinQueryById(human,skinId) 
+    local skin = human.db.skinBag[skinId]
+    if skin then
+        return {
+            id = skinId,
+            ttl = skin.ttl,
+            state = skin.state,
+        }
+    end
 end
 
-function fenjie(human,ind)
-	local bagDB = getBag(human)
-	if not bagDB[ind] then
-		return
-	end
-
-	local id = bagDB[ind].id
-	local conf = SkinExcel[id]
-	if not conf.fenjie[1] then
-		return
-	end
-	local changeList = {}
-	if not delSkin(human,{ind},changeList) then
-		return
-	end
-	for k,v in ipairs(conf.fenjie) do
-		BagLogic.addItem(human, v[1], v[2], "skin")
-	end
-	sendChange(human,changeList)
-	local msgRet = Msg.gc.GC_SKIN_FENJIE
-	msgRet.ind = ind
-	Msg.send(msgRet,human.fd)
+-- 生成发送给客户端的皮肤数据
+local function skinNetGen(human,net,id)
+    local skinCfg = assert(SkinExcel[id],"invalid skinId is ",id)
+    net.id = id
+    net.name = skinCfg.name
+    data.desc = skinCfg.desc
+	data.head = skinCfg.head
+	data.body = skinCfg.body
+	data.icon = skinCfg.icon
+	data.camp = skinCfg.camp
+	data.order = skinCfg.order
+	data.type = skinCfg.type
+    local attrLen = 0
+	for k,v in ipairs(skinCfg.attrs) do
+        attrLen = attrLen + 1
+        data.attrs[attrLen].key = v[1]
+        data.attrs[attrLen].value = v[2]
+    end
+    data.attrs[0] = attrLen
+    data.heroName = HeroExcel[skinCfg.heroId] and HeroExcel[skinCfg.heroId].name or ""
 end
 
-function upQuery(human,ind,nosend)
-	local bagDB = getBag(human)
-	if not bagDB[ind] then
-		return
-	end
-	if type(bagDB[ind]) == "number" then
-		if nosend then
-			Broadcast.sendErr(human, ind..":upQuery:"..Lang.SKIN_PARAM_ERR)
-		end
-		return 
-	end
-
-	local id = bagDB[ind].id
-	local conf = SkinExcel[id]
-	local upConf = SkinExcel[conf.upID]
-	if not (upConf and conf.upNeedExp > 0) then
-		if not nosend then
-			Broadcast.sendErr(human, id..":upQuery:"..Lang.SKIN_CONF_ERR)
-		end
-		return
-	end
-
-	local msgRet = Msg.gc.GC_SKIN_UP_QUERY
-	msgRet.ind = ind
-	fontSkinNet(msgRet.nowData,id)
-	fontSkinNet(msgRet.upData,conf.upID)
-	msgRet.maxExp = conf.upNeedExp
-	msgRet.nowExp = bagDB[ind].exp or 0
+-- 皮肤穿戴
+--[[
+    @param2 = id -- 皮肤Id
+    @param3 = heroIdx -- 对应英雄存档的idx
+]]
+local function skinOn(human,id,heroIdx)
+    local skin = skinQueryById(human,id)
+    -- 当前skin不存在 或者 皮肤已经穿戴
+    if not skin or skin.state == 1 then
+        return Broadcast.sendErr(human, id..":skinOn:"..Lang.SKIN_PARAM_ERR)
+    end
+
+    local heroId = HeroLogic.getHeroIdByIndex(heroIdx)
+    local heroGrid = HeroLogic.getHeroGrid(human.heroIdx,heroId)
+    -- 英雄不存在 或者 英雄已经装备当前皮肤
+    if not heroGrid then 
+        return Broadcast.sendErr(human, heroIdx..":heroIdx:"..Lang.SKIN_PARAM_ERR)
+    end
+    if heroGrid.skin == id then
+        return Broadcast.sendErr(human, Lang.SKIN_DOUBLE_ON)
+    end
+
+    human.db.skinBag[id].state = 1
+	-- 对所有heroId相同的英雄操作
+	local heroIdxList = HeroLogic.getHeroListById(human,heroId)
+	for _,idx in ipairs(heroIdxList) do
+		human.db.heroBag[heroIdx].skinOn = id
+	end
+    local msgRet = Msg.gc.GC_SKIN_ON
+	msgRet.heroInd = heroIdx
+	msgRet.skinInd = id
 	Msg.send(msgRet,human.fd)
 end
 
-function up(human,ind,list)
-	local bagDB = getBag(human)
-	if not bagDB[ind] then
-		return
-	end
-
-	local id = bagDB[ind].id
-	local conf = SkinExcel[id]
-	local upConf = SkinExcel[conf.upID]
-	if not (upConf and conf.upNeedExp > 0) then
-		return Broadcast.sendErr(human, id..":up:"..Lang.SKIN_CONF_ERR)
-	end
-	local addExp = 0
-	for _,v in ipairs(list) do
-		if not bagDB[v] then--皮肤不存在
-			return Broadcast.sendErr(human, v..":up1:"..Lang.SKIN_PARAM_ERR)
-		elseif bagDB[v].heroInd then--被使用
-			return Broadcast.sendErr(human, v..":up2:"..Lang.SKIN_PARAM_ERR)
-		elseif v == ind then--升级目标和升级皮肤一样
-			return Broadcast.sendErr(human, v..":up3:"..Lang.SKIN_PARAM_ERR)
-		end
-		local costID = bagDB[v].id
-		local costConf = SkinExcel[costID]
-		if not (costConf and costConf.upAddExp > 0) then
-			return Broadcast.sendErr(human, costID..":up3:"..Lang.SKIN_PARAM_ERR)
-		else
-			addExp = addExp + costConf.upAddExp
-		end
-	end
-
-	if addExp == 0 then
-		return Broadcast.sendErr(human, #list..":up3:"..Lang.SKIN_PARAM_ERR)
-	end
-
-	local nowExp = bagDB[ind].exp or 0
-	nowExp = nowExp + addExp
-	if nowExp >  conf.upNeedExp then
-		return
-	end
-	local heroInd =  bagDB[ind].heroInd
-	local isUp = false
-	local changeList = {}
-	for _,v in ipairs(list) do
-		onDelSkin(human,v,changeList)
-	end
-
-	if nowExp == conf.upNeedExp then
-		onDelSkin(human,ind,changeList)
-		ind = onAddSkin(human,conf.upID,changeList)
-		bagDB[ind].exp = nowExp - conf.upNeedExp
-		id = conf.upID
-		conf = SkinExcel[id]
-		upConf = conf.upID and SkinExcel[conf.upID]
-		isUp = true
-	else
-		bagDB[ind].exp = nowExp
-	end
-
-	sendChange(human,changeList)
-
-	local msgRet = Msg.gc.GC_SKIN_UP
-	msgRet.ind = ind
-	fontSkinNet(msgRet.nowData,id)
-	fontSkinNet(msgRet.upData,conf.upID)
-	msgRet.maxExp = conf.upNeedExp
-	msgRet.nowExp = bagDB[ind].exp or 0
+-- 皮肤脱下
+--[[
+    @param2 = heroIdx -- 对应英雄存档的idx
+]]
+local function skinOff(human,heroIdx)
+    local heroId = HeroLogic.getHeroIdByIndex(heroIdx)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroIdx,heroId)
+    local skinId = heroGrid.skin
+    -- 英雄不存在 或者 英雄未穿戴皮肤
+    if not heroGrid or not skinId then 
+        return Broadcast.sendErr(human, heroIdx..":heroIdx:"..Lang.SKIN_PARAM_ERR)
+    end
+    human.db.skinBag[skinId].state = 0
+	-- 对所有heroId相同的英雄操作
+	local heroIdxList = HeroLogic.getHeroListById(human,heroId)
+	for _,idx in ipairs(heroIdxList) do
+		human.db.heroBag[idx].skinOn = nil
+	end
+    local msgRet = Msg.gc.GC_SKIN_ON
+	msgRet.heroInd = heroIdx
+	msgRet.skinInd = skinId
 	Msg.send(msgRet,human.fd)
-	
-	upQuery(human,ind,true)
-
-	if isUp and heroInd then
-		skinOn(human,heroInd,ind)
-	end
 end
+--------------------------------------------------------------
 
-function fontPreviewNet(net,id,weight)
-	net.weight = weight
-	fontSkinNet(net.data,id)
-end
-
-function suipianPreview(human,id)
-	local itemConf = ItemExcel[id]
-	if not (itemConf and itemConf.type == ItemDefine.ITEM_SUBTYPE_SUIPIAN_SKIN) then
-		return Broadcast.sendErr(human, id..":suipianPreview:"..Lang.SKIN_PARAM_ERR)
-	end
-	local msgRet = Msg.gc.GC_SKIN_SUIPIAN_PREVIEW
-	msgRet.id = id
-	local len = 0
-	if itemConf.get[1] == 1 then
-		len = len + 1
-		fontPreviewNet(msgRet.list[len],itemConf.get[3],10000)
-	else
-		for _,v in ipairs(OutExcel[itemConf.get[3]].out) do
-			len = len + 1
-			local weight = math.floor(10000*v[2]/OutExcel[itemConf.get[3]].totalWeight)
-			fontPreviewNet(msgRet.list[len],v[1],v[2])
-		end 
-	end
-	msgRet.list[0] = len
-	Msg.send(msgRet,human.fd)
-end
-SUIPIAN_CNT = 10
-function suipian(human,id,cnt)
-	local itemConf = ItemExcel[id]
-	
-	if cnt > SUIPIAN_CNT then
-		return Broadcast.sendErr(human, Util.format(Lang.SKIN_SUIPIAN_LIMIT,SUIPIAN_CNT))
-	end
-
-	if not (itemConf and itemConf.type == ItemDefine.ITEM_SUBTYPE_SUIPIAN_SKIN) then
-		return Broadcast.sendErr(human, id..":suipian:"..Lang.SKIN_PARAM_ERR)
-	end
-	if BagLogic.getItemCnt(human,id) < itemConf.fullCnt * cnt then
-		return Broadcast.sendErr(human, Util.format(Lang.COMMON_NO_ITEM,itemConf.name))
-	end
-	local skinIDList = {}
-	for i = 1,cnt do
-		if itemConf.get[1] == 1 then
-			skinIDList[#skinIDList + 1] = itemConf.get[3]
-		else
-			local outConf = OutExcel[itemConf.get[3]]
-			local r = math.random(1,outConf.totalWeight)
-			for _,v in ipairs(outConf.out) do
-				if r <= v[2] then
-					skinIDList[#skinIDList + 1] = v[1]
-					break
-				else
-					r = r - v[2]
-				end
-			end 
-		end
-	end
-
-	if #skinIDList == 0 then
-		return Broadcast.sendErr(human, id..":suipian:"..Lang.SKIN_CONF_ERR)
-	end
-
-	BagLogic.delItem(human, id, itemConf.fullCnt * cnt, "skin")
-	local msgRet = Msg.gc.GC_SKIN_SUIPIAN
-	msgRet.id = id
-	local len = 0
-	local changeList = {}
-	for _,skinID in ipairs(skinIDList) do
-		len = len + 1
-		onAddSkin(human,skinID,changeList)
-		fontSkinNet(msgRet.out[len],skinID)
-	end
-	msgRet.out[0] = len
-	sendChange(human,changeList)
-	Msg.send(msgRet,human.fd)
-end
-
-RONGHE_ID = 1
-RONGHE_CNT = 5
-function ronghePreview(human)
-	local outConf = OutExcel[RONGHE_ID]
-	local msgRet = Msg.gc.GC_SKIN_RONGHE_PREVIEW
-	local len = 0
-	for _,v in ipairs(outConf.out) do
-		len = len + 1
-		local weight = math.floor(10000*v[2]/outConf.totalWeight)
-		fontPreviewNet(msgRet.list[len],v[1],weight)
-	end 
-	msgRet.list[0] = len
-	Msg.send(msgRet,human.fd)
-end
-
-function ronghe(human,list)
-	if #list ~= RONGHE_CNT then
-		return Broadcast.sendErr(human, #list..":ronghe1:"..Lang.SKIN_PARAM_ERR)
-	end
-	local bagDB = getBag(human)
-	for k,v in ipairs(list) do
-		local costID = bagDB[v] and bagDB[v].id or 0
-		local costConf = SkinExcel[costID]
-		if not (costConf and costConf.ronghe == 1) then
-			return  Broadcast.sendErr(human, v..":"..costID..":ronghe2:"..Lang.SKIN_PARAM_ERR)
-		end
-	end
-
-	local outConf = OutExcel[RONGHE_ID]
-	local r = math.random(1,outConf.totalWeight)
-	local skinID = outConf.out[1][1]
-	for _,v in ipairs(outConf.out) do
-		if r <= v[2] then
-			skinID = v[1]
-			break
-		else
-			r = r - v[2]
-		end
-	end
-	local changeList = {}
-	if not delSkin(human,list,changeList) then
-		return
-	end 
-	onAddSkin(human,skinID,changeList)
-
-	sendChange(human,changeList)
-
-	local msgRet = Msg.gc.GC_SKIN_RONGHE
-	msgRet.id = id
-	fontSkinNet(msgRet.out,skinID)
-	Msg.send(msgRet,human.fd)
-end
-
-function heroSkin(human,heroInd)
-	local bagDB = getBag(human)
-	local heroGrid = human.db.heroBag[heroInd]
-	local heroID = heroGrid.id
-	local heroConf = HeroExcel[heroID]
-	local heroSkinInd = human.heroSkin[heroInd] and human.heroSkin[heroInd][1]
-	local heroSkinID = heroSkinInd and bagDB[heroSkinInd].id
-	local msgRet = Msg.gc.GC_SKIN_HERO
-	local len = 0
-	for _,v in ipairs(heroConf.skin) do
-		len = len + 1
-		local net = msgRet.list[len]
-		fontSkinNet(net.data,v[1])
-		if heroSkinID == v[1] then
-			net.ind = heroSkinInd
-			net.isOn = 1
-		elseif human.hasSkin[v[1]] then	
-			net.isOn = 1
-			net.ind = 0
-			for v1 in pairs(human.hasSkin[v[1]]) do
-				if not bagDB[v1].heroInd then
-					net.ind = v1
-					net.isOn = 0
-					break
-				end
-			end
-		else
-			net.ind = 0
-			net.isOn = 0
-		end
-	end
-	msgRet.list[0] = len
-	Msg.send(msgRet,human.fd)
-end
-
-function skinOn(human,heroInd,skinInd)
-	local bagDB = getBag(human)
-	if not (skinInd == 0 or bagDB[skinInd]) then
-		return Broadcast.sendErr(human, skinInd..":skinOn:"..Lang.SKIN_PARAM_ERR)
-	end
-	local heroGrid = human.db.heroBag[heroInd]
-	local heroID = heroGrid.id
-	local heroConf = HeroExcel[heroID]
-
-	if skinInd > 0 then
-		local skinID = skinInd > 0 and bagDB[skinInd].id
-
-		if bagDB[skinInd].heroInd then
-			return Broadcast.sendErr(human, Lang.SKIN_DOUBLE_ON)
-		end
-
-		if bagDB[skinInd].heroInd == heroInd then
-			return
-		end
-
-		isHeroSkin = false
-		for k,v in ipairs(heroConf.skin) do
-			if v[1] == skinID then
-				isHeroSkin = true
-				break
-			end
-		end
-
-		if not isHeroSkin then
-			return Broadcast.sendErr(human, Lang.SKIN_NO_HERO)
-		end
-	end
-	
-	local changeInd
-	for k in pairs(human.skinBag) do
-		if bagDB[k].heroInd == heroInd then
-			bagDB[k].heroInd = nil
-			changeInd = k
-		end
-	end
-	if skinInd > 0 then
-		bagDB[skinInd].heroInd = heroInd
-		changeInd = skinInd
-	end
-	
-	human.heroSkin = nil
-	heroSkin(human,heroInd)
-	local msgRet = Msg.gc.GC_SKIN_ON
-	msgRet.heroInd = heroInd
-	msgRet.skinInd = skinInd
-	Msg.send(msgRet,human.fd)
-	HeroLogic.sendHeroBagDynamic(human,heroID,heroInd)
-	if changeInd then
-		sendChange(human,{{changeInd,OP_UPDATE}})
-	end
-end
-
-function book(human)
-	local msgRet = Msg.gc.GC_SKIN_BOOK
-	local len = 0
-	msgRet.isEnd = 1
-	for k,v in pairs(SkinExcel) do
-		if v.tujian == 1 then
-			len = len + 1
-			local net = msgRet.list[len]
-			net.ind = human.db.skinLog[k] and 1 or 0
-			net.isOn = 0
-			fontSkinNet(net.data,k)
-			if len >=30 then
-				msgRet.list[0] = 30
-				Msg.send(msgRet,human.fd)
-				len = 0
-				msgRet.isEnd = 2
-			end
+function initAfterHot()
+	for _,outConf in pairs(OutExcel) do
+		outConf.totalWeight = 0
+		for _,v in ipairs(outConf.out) do
+			outConf.totalWeight = outConf.totalWeight + v[2]
 		end
 	end
-
-	msgRet.isEnd = 3
-	msgRet.list[0] = len
-	Msg.send(msgRet,human.fd)
-
 end
 
+-- 优先使用皮肤的技能,新版本没有默认返回false
 function setSkill(human,heroInd,heroConf,obj)
-	if not human then return end
+	return false
+	--[[if not human then return end
 	if not human.db.skinBag then
 	--假人
 		return
@@ -623,13 +187,18 @@ function setSkill(human,heroInd,heroConf,obj)
 	local skillConf = SkillExcel[skinSkillID]
 	Skill.setSkill(obj, heroConfig,skillConf)	
 	BeSkill.setBeSkill(obj,heroConf,skillConf)
-	return true
+	return true]]
 end
 
 function checkHeroSkin(human, heroInd)
 	if not heroInd then return end
 	if not human or not human.db then return end
-	if not human.db.skinBag then
+	local heroId = HeroLogic.getHeroIdByIndex(heroInd)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroInd,heroId)
+	if heroGrid.skinOn then 
+		return heroGrid.skinOn,true
+	end
+	--[[if not human.db.skinBag then
 		return
 	end
 	local bagDB = getBag(human)
@@ -641,11 +210,19 @@ function checkHeroSkin(human, heroInd)
 	else
 		return
 	end
-	
+	]]
 end
 
+-- 检查是否有皮肤body
 function getBody(human,heroInd)
-	if not human.db.skinBag then
+	local heroId = HeroLogic.getHeroIdByIndex(heroInd)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroInd,heroId)
+	local skinId = heroGrid.skinOn
+	if not skinId then 
+		return
+	end
+	return SkinExcel[skinId].body,SkinExcel[skinId].head
+	--[[if not human.db.skinBag then
 		return
 	end
 	local bagDB = getBag(human)
@@ -653,11 +230,18 @@ function getBody(human,heroInd)
 		local skinInd = human.heroSkin[heroInd][1]
 		local skinID = bagDB[skinInd].id
 		return SkinExcel[skinID].body,SkinExcel[skinID].head
-	end
+	end]]
 end
 
 function getHeroSkin(human,heroInd)
-	if not human or not human.db.skinBag then
+	local heroId = HeroLogic.getHeroIdByIndex(heroInd)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroInd,heroId)
+	local skinId = heroGrid.skinOn
+	if not skinId then
+		return
+	end
+	return SkillExcel[skinId]
+	--[=[if not human or not human.db.skinBag then
 		return
 	end
 	local bagDB = getBag(human)
@@ -667,12 +251,88 @@ function getHeroSkin(human,heroInd)
 		local skinConf = SkinExcel[skinID]
 		local skillConf = SkillExcel[human.heroSkin[heroInd][2]]
 		return skinConf,skillConf
-	end
+	end]=]
 end
 
-function onDelHero(human,heroInd)
-	local bagDB = getBag(human)
-	if human.heroSkin[heroInd] then
-		skinOn(human,heroInd,0)
-	end
+-------------------------- protocol --------------------------
+-- 皮肤信息查询
+function skinQuery(human)
+    local msgRet = Msg.gc.GC_SKIN_BAG
+    local data = skinListQuery(human)
+    local maxLen = #msgRet.list -- 每次最多只能传30个
+    local cnt = 0
+    for id in pairs(SkinExcel) do
+        cnt = cnt + 1
+        msgRet.list[cnt].ind = id
+        msgRet.list[cnt].isOn = data[id].state
+        skinNetGen(human,msgRet.list[cnt].data,id)
+        if cnt >= maxLen then
+            msgRet.list[0] = maxLen
+            cnt = 0
+            msgRet.isEnd = 1
+            Msg.send(msgRet,human.fd)
+        end
+    end
+    msgRet.list[0] = cnt
+    msgRet.isEnd = 2
+    Msg.send(msgRet,human.fd)
+end
+
+-- 皮肤穿戴功能
+function skinOp(human,id,heroIdx)
+    if id == 0 then 
+        return skinOff(human,heroIdx)
+    end
+    return skinOn(human,id,heroIdx)
+end
+
+-- 皮肤解锁
+function skinUnlock(human,id)
+    local skinCfg = assert(SkinExcel[id],"invalid skinId is ",id)
+    -- 皮肤已经解锁
+    if human.db.skinBag[id] then
+        -- 发放皮肤重复物品
+        local itemList = {}
+        for _,item in pairs(skinCfg.repeated) do 
+            itemList[#itemList+1] =  {
+                item[1],item[2]
+            }
+        end
+        return BagLogic.addItemList(human,itemList,"skin")
+    end
+    local now = os.time()
+    human.db.skinBag[id] = {
+        ttl = -1,
+        state = 0,
+        getTime = now,
+    }
+
+	RoleHeadLogic.active(human, RoleHeadLogic.HEAD_TYPE_1, skinCfg.head)
+    -- 所有角色属性提升
+
+    -- 回复给客户端
+    local msgRet = Msg.gc.GC_SKIN_UPDATE
+    local data = msgRet.list[1].data
+    data.ind = id
+    data.isOn = 0
+    skinNetGen(human,data.data,id)
+    msgRet.list[1].op = 1
+    msgRet.list[0] = 1
+	Msg.send(msgRet,human.fd)
+end
+
+-- 计算皮肤属性
+function doCalcSkinHero(human,attrs)
+    local skinBag = human.db.skinBag
+    local attrMap = {}
+    for id in pairs(skinBag) do
+        local skinCfg = SkinExcel[id]
+        for _,attr in pairs(skinCfg.attrs) do 
+            attrMap[attr[1]] = attrMap[attr[1]] or 0
+            attrMap[attr[1]] = attrMap[attr[1]] + attr[2]
+        end
+    end
+    for attr,cnt in pairs(attrMap) do 
+        RoleAttr.updateValue(attr,cnt, attrs)
+    end
 end