Explorar o código

皮肤功能相关提交

249435196@qq.com hai 1 ano
pai
achega
b836e35615

+ 18 - 29
script/module/combat/CombatLogic.lua

@@ -55,6 +55,7 @@ local HeroLogic = require("hero.HeroLogic")
 local XingYaoGongMing = require("xingYaoMen.XingYaoGongMing")
 local MoshouLogic = require("moshou.MoshouLogic")
 local LostTempleCombatLogic = require("lostTemple.lostTempleCombatLogic")
+local SkinExcel = require("excel.skin")
 
 FieldsCombat = {
 	lv = 1, name = 1, head = 1, headFrame = 1, unionUuid = 1, lastLogoutTime = 1, 
@@ -160,10 +161,9 @@ function getCombatObjList(human, side, combatType, args)
 			end
 		end
 	end
-	-- 获取战斗模块组件
 	local moduleFn = getModule(combatType)
 	if not moduleFn then return end
-	-- 模块有对应获取战斗对象的方法 ,有则调用
+
 	if moduleFn.getCombatObjList then
 		local objList, helpList, rolebase, formation,jiban = moduleFn.getCombatObjList(human, side, args, combatType)
 		if objList then 
@@ -171,7 +171,6 @@ function getCombatObjList(human, side, combatType, args)
 		end
 	end
 
-
 	local monsterOutID, zhandouli = getCombatMonsterOutID(human, side, combatType, args)
 	if monsterOutID then
 		local objList, helpList, rolebase, formation, jiban = getMonsterObjList(monsterOutID, nil, args)
@@ -385,8 +384,9 @@ function createHeroObjByID(heroId, lv, star, quality, index)
 end
 
 -- 根据英雄表信息创建临时对象
-function createHeroObj(human, heroId, lv, star, index)
+function createHeroObj(human, heroId, lv, star, index,skin)
 	local heroConfig = HeroExcel.hero[heroId]
+	local skinCfg = skin and SkinExcel.skin[skin]
 	if not heroConfig then return end
 	
 	local obj = {}
@@ -397,8 +397,14 @@ function createHeroObj(human, heroId, lv, star, index)
 	obj.job = heroConfig.job			
 	obj.quality = HeroGrid.getMaxQuality(star)
 	obj.star = star
-    obj.body = heroConfig.body
-    obj.head = heroConfig.head
+    obj.body = skinCfg and skinCfg.body --or heroConfig.body
+    obj.head = skinCfg and skinCfg.head --or heroConfig.head
+	if not obj.body or obj.body == 0 then 
+		obj.body = heroConfig.body
+	end
+	if not obj.head or obj.head == 0 then 
+		obj.head = heroConfig.head
+	end
 
     local attrConfig =  HeroDefine.getAttrConfig(obj.id, obj.star)
     BeSkill.initBeSkill(obj)
@@ -432,7 +438,6 @@ function createHeroObjByHeroGrid(human, heroGrid)
     obj.sex = heroConfig.sex
     local attrConfig =  HeroDefine.getAttrConfig(obj.id, obj.star)
     BeSkill.initBeSkill(obj)
-	-- 初始化技能和普攻数据
     if not SkinLogic.setSkill(human,obj.bagIndex,attrConfig,obj) then
 		Skill.setSkill(obj, attrConfig)	
 		BeSkill.setBeSkill(obj, attrConfig)
@@ -1099,6 +1104,7 @@ function onFightBegin(human, combatType, cbParam, param)
 	end
 	
 	BeSkill.onFightBegin(human)
+	SkinLogic.onFightBegin(human) -- 处理皮肤属性
 	CombatPosLogic.onFightBegin(human)
 	recalcHpFightBegin(human, combatType, cbParam)
 end
@@ -1115,7 +1121,7 @@ local function setCombatInfo(formation,objList, side)
 				-- 出战英雄站位
 			if CombatPosLogic.checkPos(formation,index, side) then
 				local pos = CombatDefine.SIDE2POS[side][index]
-				CombatImpl.setData(pos, obj) --初始化对象数据
+				CombatImpl.setData(pos, obj)
 			end
 		end
 	end
@@ -1185,12 +1191,6 @@ function setSkillAndBeskill(human,combatInfo)
 	end	
 end
 
---[[
-	@param1 : agent
-	@param2 : mapID 目前看来已经被遗弃了
-	@oaram3 : 对应参数
-	@param4 : 战斗类型
-]]
 function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
 	if COMBAT_CACHE[human.db._id] and COMBAT_CACHE[human.db._id][combatType] then
 		--assert(nil, "has combat cache "..combatType .. " " .. human.db.account) -- reyes test
@@ -1199,12 +1199,9 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
 		return
 	end
 
-    -- 初始化战斗实现类
+    -- 获得地图ID
     CombatImpl.init(combatType)
-	-- 获得地图ID
     mapID = getMapID(human, combatType, param)
-
-	-- 获取上阵列表
 	local defender, defHelp, defRBase,defFormation,defJiban = getCombatObjList(human, CombatDefine.DEFEND_SIDE, combatType, param)
 	local attacker, atkHelp, atkRBase, atkFormation,atkJiban
 	if defender then
@@ -1230,10 +1227,8 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
  	combatInfo.defHelp = defHelp or {}
  	combatInfo.defFormation = defFormation
 	combatInfo.defJiban = defJiban
-	-- 代码看来,种族属性功能还未实现 @mafei
 	combatInfo.posAttr[CombatDefine.ATTACK_SIDE] = CombatPosLogic.getPosAttr(attacker)
 	combatInfo.posAttr[CombatDefine.DEFEND_SIDE] = CombatPosLogic.getPosAttr(defender) 
-	-- 获取英雄列表的羁绊
 	combatInfo.jiban[CombatDefine.ATTACK_SIDE] = JibanLogic.getJiban(attacker,atkJiban)
 	combatInfo.jiban[CombatDefine.DEFEND_SIDE] = JibanLogic.getJiban(defender,defJiban) 
 	combatInfo.maxRound = getMaxRound(human,combatType)
@@ -1245,7 +1240,7 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
 	JibanLogic.setBeSkill(attacker,combatInfo.jiban[CombatDefine.ATTACK_SIDE])
 	JibanLogic.setBeSkill(defender,combatInfo.jiban[CombatDefine.DEFEND_SIDE])
 
-	-- 遗迹五号位?
+	
     local changePos = nil
     if combatType == CombatDefine.COMBAT_TYPE10 then
         for k,v in pairs(attacker) do
@@ -1255,15 +1250,11 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
             break
         end
     end
-	-- 将符合阵法的战斗对象封装到objList里面? 其他对象如何处理?
 	setCombatInfo(atkFormation, attacker, CombatDefine.ATTACK_SIDE)
 	setCombatInfo(defFormation, defender, CombatDefine.DEFEND_SIDE)
-	-- 设置援军
 	setHelp(atkHelp, CombatDefine.ATTACK_SIDE)
 	setHelp(defHelp, CombatDefine.DEFEND_SIDE)
-	-- 设置最大回合数
 	CombatImpl.setMaxRound(combatInfo.maxRound)
-	-- 设置战斗模式
 	CombatImpl.setFightMode(combatInfo.fightMode)
 	--需要对技能特殊处理的(比如不重置cd)
 	setSkillAndBeskill(human,combatInfo)
@@ -1274,11 +1265,9 @@ function combatBegin(human, mapID, param, combatType, cbParam, isSaodang)
         tempParam.cbParam = cbParam
         tempParam.changePos = changePos
     end
-	-- 战前准备(种族 阵法等开战触发),同步属性
 	onFightBegin(human, combatType, tempParam, param)
 	makeAttrLogStr(human)
 
-	-- 战斗开始
 	while CombatImpl.calcFrame() do end    
     copyToCombatInfo(combatInfo)
 
@@ -1442,7 +1431,7 @@ function combatFightVedio(human, heroID)
            end
         end
         if atkConf then
-           VEDIO_COMBAT_INFO.attacker[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i)
+           VEDIO_COMBAT_INFO.attacker[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i,atkConf[5])
         end 
 
         atkConf = nil
@@ -1453,7 +1442,7 @@ function combatFightVedio(human, heroID)
            end
         end
         if atkConf then
-           VEDIO_COMBAT_INFO.defender[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i)
+           VEDIO_COMBAT_INFO.defender[i] = createHeroObj(VEDIO_COMBAT_INFO, atkConf[1], atkConf[3], atkConf[4], i,atkConf[5])
         end
     end
 

+ 1 - 1
script/module/drawCard/DrawCardLogic.lua

@@ -342,7 +342,7 @@ function sendDrawOp(human, id, op, heroList, items, heroNewList, heroIndexList,
         local heroID = heroList[i]
         local isNew = heroNewList and heroNewList[i]
         local index = heroIndexList and heroIndexList[i]
-        HeroGrid.makeHeroNice(dataNet.heros[i], heroID, nil, isNew, index)
+        HeroGrid.makeHeroNice(dataNet.heros[i], heroID, nil, isNew, index,human)
     end
     dataNet.items[0] = 0
     if items and type(items) == "table" then

+ 8 - 1
script/module/hero/HeroGrid.lua

@@ -329,7 +329,7 @@ function makeHeroSimpleByGeneral(net, id)
 	end
 end
 
-function makeHeroNice(net, id, cnt, isNew, index)
+function makeHeroNice(net, id, cnt, isNew, index,human)
 	net.itemData[0] = 0 
 	net.heroSimple[0] = 0 
 	net.heroStatic[0] = 0
@@ -343,6 +343,13 @@ function makeHeroNice(net, id, cnt, isNew, index)
 		net.heroSimple[0] = 1
 		makeHeroSimpleByID(net.heroSimple[1], id, index)
 
+		if human then
+			local skinbody = SkinLogic.getBodyByHeroId(human, id)
+			if skinbody then
+				net.heroSimple[1].body = skinbody
+			end
+		end
+
 		net.heroStatic[0] = 1
 		makeHeroStatic(net.heroStatic[1], id)
 	end

+ 1 - 1
script/module/hero/HeroLogic.lua

@@ -1432,7 +1432,7 @@ function getHeroGridByUuid(human, uuid)
         local heroGrid = human.db.heroBag[index]
         if heroGrid and type(heroGrid) == "table" then
             if heroGrid.uuid == uuid then
-                return heroGrid
+                return heroGrid,index
             end
         end
     end

+ 15 - 25
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")
@@ -37,8 +36,6 @@ local ItemDefine = require("bag.ItemDefine")
 local EquipLogic = require("equip.EquipLogic")
 local CombatPosLogic = require("combat.CombatPosLogic")
 local CombatDefine = require("combat.CombatDefine")
-local Json = require("common.Json")
-local Log                    = require("common.Log")
 
 -- 计算人数属性
 function doCalc(human)
@@ -69,9 +66,9 @@ function cleanHeroAttrCache(human)
 end
 
 -- 重算英雄属性
-function doCalcHero(human, index, heroAttrs)
+function doCalcHero(human, index)
 	local heroGrid = human.db.heroBag[index]
-	local attrs = calcHeroGrid(heroGrid, index, human,heroAttrs)	
+	local attrs = calcHeroGrid(heroGrid, index, human)	
 	if not attrs then return end
     
     RoleStrongLogic.doCalcMoShouPingFen(human, attrs)
@@ -120,7 +117,7 @@ end
 local TEMP_HERO_ATTRS = {}
 local HERO_BASE_ATTRS = {}
 local HERO_OTHER_ATTRS = {}
-function calcHeroGrid(heroGrid, index, human,heroAttrs)	
+function calcHeroGrid(heroGrid, index, human)	
 	if type(heroGrid) ~= "table" then 
 		return 
 	end
@@ -128,28 +125,21 @@ function calcHeroGrid(heroGrid, index, human,heroAttrs)
 	initCombatAttr(TEMP_HERO_ATTRS)
 	initCombatAttr(HERO_BASE_ATTRS)	
 	initCombatAttr(HERO_OTHER_ATTRS)
-
-    local isMerge = nil
-    if heroAttrs then 
-        isMerge = true
-        for key, value in pairs(heroAttrs) do
-            HERO_BASE_ATTRS[key] = value
-        end
-    else
-        --默认
-        HERO_BASE_ATTRS[RoleDefine.INIT_MP] = 50
-        -- 默认命中100% 暴击伤害
-        HERO_BASE_ATTRS[RoleDefine.JINGZHUN] = RoleDefine.DEFAUT_MINGZHONG
-        HERO_BASE_ATTRS[RoleDefine.BAOJI_HURT_RATE] = RoleDefine.DEFAUT_BAOJI_HURT_RATE
-    end
+	HERO_BASE_ATTRS[RoleDefine.INIT_MP] = 50
+    -- 默认命中100% 暴击伤害
+    HERO_BASE_ATTRS[RoleDefine.JINGZHUN] = RoleDefine.DEFAUT_MINGZHONG
+    HERO_BASE_ATTRS[RoleDefine.BAOJI_HURT_RATE] = RoleDefine.DEFAUT_BAOJI_HURT_RATE
 
 	--不同模块在英雄属性计算 begin
-	HeroLogic.doCalcHero(heroGrid, HERO_BASE_ATTRS, isMerge) -- 基础属性
-	local heroSkinID, heroSkinSkill = SkinLogic.checkHeroSkin(human, index) 
-	if heroSkinID and heroSkinSkill then -- 皮肤属性
-		HeroLogic.doCalcHeroSkin(heroSkinID, HERO_OTHER_ATTRS)
+	HeroLogic.doCalcHero(heroGrid, HERO_BASE_ATTRS) -- 基础属性
+	-- 防止循环引用
+	local SkinLogic = require("skin.SkinLogic")
+	--local heroSkinID, heroSkinSkill = SkinLogic.checkHeroSkin(human, index) 
+	if human and human.db and human.db.skinBag then -- 皮肤属性
+		--HeroLogic.doCalcHeroSkin(heroSkinID, HERO_OTHER_ATTRS)
+		SkinLogic.doCalcSkinHero(human,HERO_BASE_ATTRS)
 	end
-	BeSkill.doCalcHero(heroGrid, HERO_BASE_ATTRS, heroSkinSkill) -- 被动技能属性
+	BeSkill.doCalcHero(heroGrid, HERO_BASE_ATTRS) -- 被动技能属性
 	HeroEquip.doCalcHero(heroGrid, HERO_OTHER_ATTRS) -- 装备
     FuwenLogic.doCalcHero(heroGrid, HERO_OTHER_ATTRS) -- 符文	
 	UnionTecLogic.doCalcHero(human, heroGrid, HERO_OTHER_ATTRS) -- 公会科技	

+ 8 - 5
script/module/skin/Handler.lua

@@ -1,8 +1,12 @@
 local SkinLogic = require("skin.SkinLogic")
 function CG_SKIN_BAG(human, msg)
-	SkinLogic.bag(human)
+	SkinLogic.skinQuery(human)
 end
 
+function CG_SKIN_ON(human, msg)
+	SkinLogic.skinOp(human,msg.heroInd,msg.skinIn)
+end
+--[[
 function CG_SKIN_FENJIE(human, msg)
 	SkinLogic.fenjie(human,msg.ind)
 end
@@ -35,10 +39,9 @@ function CG_SKIN_HERO(human, msg)
 	SkinLogic.heroSkin(human,msg.heroInd)
 end
 
-function CG_SKIN_ON(human, msg)
-	SkinLogic.skinOn(human,msg.heroInd,msg.skinInd)
-end
+
 
 function CG_SKIN_BOOK(human, msg)
 	SkinLogic.book(human)
-end
+end
+]]

+ 31 - 108
script/module/skin/Proto.lua

@@ -1,134 +1,57 @@
 local Attr = require("role.Proto").Attr
-local ItemData = require("bag.Proto").ItemData
+----------------------------------------------------------------------------------
 
+-- 鐨�偆鏁版嵁鏌ヨ�
 CG_SKIN_BAG = {}
+
 SkinNet = {
 	{"id",		1,		"int"},  --id
-	{"heroName",	1,		"string"},  --英雄名字
-	{"name",	1,		"string"},  --名字
-	{"desc",	1,		"string"},  --描述
-	{"head",	1,		"int"},  --头像
-	{"body",	1,		"int"},  --模型
-	{"icon",    1,      "int"},  --原画
-	{"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"},  --品阶
+	{"heroId",  1,      "int"}, -- 鑻遍泟ID
+	{"heroName",	1,		"string"},  --鑻遍泟鍚嶅瓧
+	{"name",	1,		"string"},  --鍚嶅瓧
+	{"desc",	1,		"string"},  --鎻忚堪
+	{"head",	1,		"int"},  --澶村儚
+	{"body",	1,		"int"},  --妯″瀷
+	{"icon",    1,      "int"},   --鍘熺敾
+	{"camp",    1,      "int"},  --闃佃惀
+	{"order",	1,		"int"},  --閰嶇疆琛ㄦ帓搴�
+	{"type",	1,		"byte"},  --绫诲瀷
+	{"attrs",	5,		Attr},  --灞炴€�
 }
 SkinBagNet = {
 	{"data",	1,	SkinNet},
-	{"ind",		1,		"int"},  --皮肤索引
-	{"isOn",	1,		"byte"},  --0未穿戴,1已穿戴
+	{"ind",		1,		"int"},  --鐨�偆绱㈠紩
+	{"isOn",	1,		"byte"},  --0鏈�┛鎴达紝1宸茬┛鎴�
+}
+
+SkinBag = {
+	{"ind",		1,		"int"},  --鐨�偆绱㈠紩
+	{"id",      1,       "int"},  -- 鐨�偆id
+	{"isOn",	1,		"byte"},  --0鏈�┛鎴达紝1宸茬┛鎴�
 }
+
 GC_SKIN_BAG = {
-	{"isEnd",		1,		"byte"},  --分包 1第一个包 2其他 3 最后一个包
-	{"list",	30,		SkinBagNet},
+	{"isEnd",		1,		"byte"},  --鍒嗗寘 1绗�竴涓�寘 2鍏朵粬 3 鏈€鍚庝竴涓�寘
+	{"list",	256,		SkinNet},
+	{"data",    256,        SkinBag},
 }
 
 SkinUpdateNet = {
 	{"data",		1,		SkinBagNet},
-	{"op",		1,		"byte"},  --1 新增 2 删除 3 更新
+	{"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 历史拥有过
-}

+ 358 - 564
script/module/skin/SkinLogic.lua

@@ -6,7 +6,6 @@ local Lang = require("common.Lang")
 local Util = require("common.Util")
 local ItemDefine = require("bag.ItemDefine")
 local BeSkill = require("combat.BeSkill")
-local Skill = require("combat.Skill")
 local HeroLogic = require("hero.HeroLogic")
 local RoleHeadLogic = require("role.RoleHeadLogic")
 local SkinExcel = require("excel.skin").skin
@@ -14,15 +13,9 @@ 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 CombatDefine = require("combat.CombatDefine")
+local CombatImpl = require("combat.CombatImpl")
 
 local function getBag(human)
 	if not (human.skinBag and human.heroSkin) then
@@ -56,561 +49,179 @@ 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
+--[[
+    skin = {
+        ttl = number -- 有效时长 -1表示永久
+        state = number -- 0表示未穿戴 1 表示穿戴
+    } -- skin 拥有唯一性
+]]
+
+-- 获取所有皮肤信息
+local function skinListQuery(human)
+    local skinBag = human.db.skinBag
+    local ret = {}
+    for i = 1,#skinBag do 
+        local data = skinBag[i]
+        ret[data.id] = {
+            idx = i,
+            id = data.id,
+            ttl = data.ttl,
+            state = data.state,
+        }
+    end
+    return ret
 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
+-- 获取皮肤为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 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)
-
+local function skinQueryIdxById(human,skinId)
+    local skinBag = human.db.skinBag
+    for i = 1,#skinBag do 
+        local data = skinBag[i]
+        if data.id == skinId then 
+            return i
+        end
+    end
 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
+-- 生成发送给客户端的皮肤数据
+local function skinNetGen(human,net,id)
+    local skinCfg = assert(SkinExcel[id],"invalid skinId is ",id)
+    net.id = id
+    net.heroId = skinCfg.heroId or 0
+    net.name = skinCfg.name
+    net.desc = skinCfg.desc
+	net.head = skinCfg.head
+	net.body = skinCfg.body
+	net.icon = skinCfg.icon
+	net.camp = skinCfg.camp
+	net.order = skinCfg.order
+	net.type = skinCfg.type
+    local attrLen = 0
+	for k,v in ipairs(skinCfg.attrs) do
+        attrLen = attrLen + 1
+        net.attrs[attrLen].key = v[1]
+        net.attrs[attrLen].value = v[2]
+    end
+    net.attrs[0] = attrLen
+    net.heroName = HeroExcel[skinCfg.heroId] and HeroExcel[skinCfg.heroId].name or ""
 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
+-- 皮肤穿戴
+--[[
+    @param2 = id -- 皮肤Id
+    @param3 = heroIdx -- 对应英雄存档的idx
+]]
+local function skinOn(human,skinIdx,heroIdx)
+    --local idx = skinQueryIdxById(human,skinIdx)
+    local skin = human.db.skinBag[skinIdx]
+    -- 当前skin不存在 或者 皮肤已经穿戴
+    if not skin or skin.state == 1 then
+        return Broadcast.sendErr(human, skinIdx..":skinOn:"..Lang.SKIN_PARAM_ERR)
+    end
+
+    local heroId = HeroLogic.getHeroIdByIndex(human,heroIdx)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroId,heroIdx)
+    -- 英雄不存在 或者 英雄已经装备当前皮肤
+    if not heroGrid then 
+        return Broadcast.sendErr(human, heroIdx..":heroIdx:"..Lang.SKIN_PARAM_ERR)
+    end
+
+    if heroGrid.skinOn == skin.id then
+        return Broadcast.sendErr(human, Lang.SKIN_DOUBLE_ON)
+    end
+
+    local skinCfg = SkinExcel[skin.id]
+    human.db.skinBag[skinIdx].state = 1
+	-- 对所有heroId相同的英雄操作
+	local heroIdxList = HeroLogic.getHeroListById(human,heroId)
+	for _,idx in ipairs(heroIdxList) do
+		human.db.heroBag[idx].skinOn = skin.id
+        RoleHeadLogic.setHead(human,skinCfg.head,RoleHeadLogic.HEAD_TYPE_1)
+        if skinCfg.body ~= 0 then
+            RoleHeadLogic.setHead(human,skinCfg.body,RoleHeadLogic.HEAD_TYPE_3)
+        end
+	end
+
+     -- 回复给客户端
+     local msgRet = Msg.gc.GC_SKIN_UPDATE
+     local data = msgRet.list[1].data
+     data.ind = skinIdx
+     data.isOn = 1
+     skinNetGen(human,data.data,skin.id)
+     msgRet.list[1].op = 3
+     msgRet.list[0] = 1
+     Msg.send(msgRet,human.fd)
 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)
-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
-	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(human,heroIdx)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroId,heroIdx)
+    local skinId = heroGrid.skinOn
+    -- 英雄不存在 或者 英雄未穿戴皮肤
+    if not heroGrid or not skinId then 
+        return Broadcast.sendErr(human, heroIdx..":heroIdx:"..Lang.SKIN_PARAM_ERR)
+    end
+    local skinIdx = nil
+    for idx,skin in pairs(human.db.skinBag) do 
+        if idx > 0 and skin.id == skinId then
+            skinIdx = idx
+            human.db.skinBag[idx].state = 0
+            break 
+        end
+    end
+    assert(skinIdx,"param error")
+	-- 对所有heroId相同的英雄操作
+	local heroIdxList = HeroLogic.getHeroListById(human,heroId)
+    local heroCfg = HeroExcel[heroId]
+	for _,idx in ipairs(heroIdxList) do
+        -- 脱下皮肤 并且还原默认身体 icon和head
+		human.db.heroBag[idx].skinOn = nil
+        --local defaultHead = RoleHeadLogic.getDefaultHead(human)
+        RoleHeadLogic.setHead(human,heroCfg.head,RoleHeadLogic.HEAD_TYPE_1)
+
+        RoleHeadLogic.setHead(human,heroCfg.body,RoleHeadLogic.HEAD_TYPE_3)
+	end
+
+    -- 回复给客户端
+    local msgRet = Msg.gc.GC_SKIN_UPDATE
+    local data = msgRet.list[1].data
+    data.ind = skinIdx
+    data.isOn = 0
+    skinNetGen(human,data.data,skinId)
+    msgRet.list[1].op = 3
+    msgRet.list[0] = 1
 	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
-
-		local 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
@@ -622,31 +233,46 @@ function setSkill(human,heroInd,heroConf,obj)
 	end
 
 	local skillConf = SkillExcel[skinSkillID]
-	Skill.setSkill(obj, heroConf,skillConf)	
+	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
+	if not human or not human.db or not human.db.heroBag then return end
+	local heroId = HeroLogic.getHeroIdByIndex(human,heroInd)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroId,heroInd)
+	if heroGrid.skinOn then 
+		return heroGrid.skinOn,true
+	end
+	--[[if not human.db.skinBag then
 		return
 	end
 	local bagDB = getBag(human)
 	if human.heroSkin[heroInd] then
 		local skinInd = human.heroSkin[heroInd][1]
 		local skinID = bagDB[skinInd].id
-		local skillID = human.heroSkin[heroInd][2]
-		return skinID,skillID
+		--local skillID = human.heroSkin[heroInd][2]
+		return skinID,true
 	else
 		return
-	end
-	
+	end]]
 end
 
+-- 检查是否有皮肤body
 function getBody(human,heroInd)
-	if not human.db.skinBag then
+    if not heroInd then 
+        return
+    end
+	local heroId = HeroLogic.getHeroIdByIndex(human,heroInd)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroId,heroInd)
+	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)
@@ -654,11 +280,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(human,heroInd)
+    local heroGrid = HeroLogic.getHeroGrid(human,heroId,heroInd)
+	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)
@@ -668,12 +301,173 @@ 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
+function getBodyByHeroId(human, heroid)
+    if not human then return end
+    local list = HeroLogic.getHeroListById(human, heroid)
+    if #list > 0 then
+        local heroIdx = list[1]
+        return getBody(human, heroIdx)
+    end
+end
+
+local function calcSkinAttr(human)
+    local skinBag = human.db.skinBag
+    if not skinBag then 
+        return
+    end
+    local attrMap = {}
+    for i = 1,#skinBag do 
+        local data = skinBag[i]
+        local skinCfg = SkinExcel[data.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
+    return attrMap
+end
+
+-------------------------- protocol --------------------------
+-- 皮肤信息查询
+function skinQuery(human)
+    local msgRet = Msg.gc.GC_SKIN_BAG
+    local data = skinListQuery(human)
+    local cnt = 0
+    for _,info in pairs(data) do
+        cnt = cnt + 1   
+        msgRet.data[cnt].ind = info.idx
+        msgRet.data[cnt].id = info.id
+        msgRet.data[cnt].isOn = info.state
+       
+    end
+    msgRet.data[0] = cnt
+    local maxLen = #msgRet.list -- 每次最多只能传30个
+    cnt = 0
+    for id in pairs(SkinExcel) do
+        cnt = cnt + 1
+        skinNetGen(human,msgRet.list[cnt],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,heroIdx,skinIdx)
+    if skinIdx == 0 then 
+        skinOff(human,heroIdx)
+    else
+        skinOn(human,skinIdx,heroIdx)
+    end
+    local retMsg = Msg.gc.GC_SKIN_ON
+    retMsg.heroId = heroIdx
+    retMsg.skinInd = skinIdx
+    Msg.send(retMsg,human.fd)
+end
+
+-- 皮肤解锁
+function skinUnlock(human,id)
+    local skinCfg = assert(SkinExcel[id],"invalid skinId is ",id)
+    local isUnlock = false
+    for i = 1,#human.db.skinBag do 
+        local skin = human.db.skinBag[i]
+        if skin.id == id then 
+            isUnlock =true
+            break
+        end 
+    end
+    --[[for _,skin in pairs(human.db.skinBag) do 
+        if skin.id == id then 
+            isUnlock =true
+            break
+        end
+    end]]
+    -- 皮肤已经解锁
+    if isUnlock then
+        -- 发放皮肤重复物品
+        local itemList = {}
+        for _,item in pairs(skinCfg.repeated) do 
+            itemList[#itemList+1] =  {
+                item[1],item[2]
+            }
+        end
+        return BagLogic.addItemList(human,itemList,"skin")
+        --Broadcast.sendErr(human, ":skin repeat:"..Lang.SKIN_REPEAT)
+        --return
+    end
+    local now = os.time()
+    human.db.skinBag[#human.db.skinBag + 1] = {
+        id = id,
+        ttl = -1,
+        state = 0,
+        getTime = now,
+    }
+    -- 解锁头像
+	RoleHeadLogic.active(human, RoleHeadLogic.HEAD_TYPE_1, skinCfg.head)
+    -- 解锁身体
+    if skinCfg.body ~= 0 then 
+        RoleHeadLogic.active(human, RoleHeadLogic.HEAD_TYPE_3, skinCfg.body)
+        RoleHeadLogic.active(human, RoleHeadLogic.HEAD_TYPE_5, skinCfg.body)
+    end
+
+    -- 所有角色属性提升
+    -- 回复给客户端
+    local msgRet = Msg.gc.GC_SKIN_UPDATE
+    local data = msgRet.list[1].data
+    data.ind = #human.db.skinBag
+    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 i = 1,#skinBag do 
+        local data = skinBag[i]
+        local skinCfg = SkinExcel[data.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 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
+
+function onFightBegin(human)
+    local skinAttrMap = calcSkinAttr(human)
+    if not skinAttrMap or not next(skinAttrMap) then 
+        return
+    end
+    for pos = 1,CombatDefine.COMBAT_HERO_ALL_CNT do
+        local obj = CombatImpl.objList[pos]
+		if obj then
+            for attr,cnt in ipairs(skinAttrMap) do
+                obj.sysAttr[attr] = obj.sysAttr[attr] or 0
+                obj.sysAttr[attr] = obj.sysAttr[attr] +cnt
+            end
+            obj.isSysAttrChange = true
+        end
+    end
 end