local Msg = require("core.Msg") local Grid = require("bag.Grid") local BagLogic = require("bag.BagLogic") local Broadcast = require("broadcast.Broadcast") local Lang = require("common.Lang") local Util = require("common.Util") local ItemDefine = require("bag.ItemDefine") local BeSkill = require("combat.BeSkill") local HeroLogic = require("hero.HeroLogic") local RoleHeadLogic = require("role.RoleHeadLogic") local SkinExcel = require("excel.skin").skin local HeroExcel = require("excel.hero").hero local SkillExcel = require("excel.skin").skill local OutExcel = require("excel.skin").out local ItemExcel = require("excel.item").item local RoleAttr = require("role.RoleAttr") local CombatDefine = require("combat.CombatDefine") local CombatImpl = require("combat.CombatImpl") local RoleDefine = require("role.RoleDefine") local ObjHuman = require("core.ObjHuman") local function getBag(human) if not (human.skinBag and human.heroSkin) then human.skinBag = {} human.heroSkin = {} human.hasSkin = {} for i = 1,human.db.skinBag[0] do local data = human.db.skinBag[i] if data then if data.heroInd then local skinSkillID local heroGrid = human.db.heroBag[data.heroInd] if not heroGrid then data.heroInd = nil else local heroID = heroGrid.id local heroConf = HeroExcel[heroID] for _,v in ipairs(heroConf.skin) do if v[1] == data.id then human.heroSkin[data.heroInd] = {i,tonumber(v[2])} end end end end human.skinBag[i] = data.id human.hasSkin[data.id] = human.hasSkin[data.id] or {} human.hasSkin[data.id][i] = 1 end end end return human.db.skinBag 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 -- 获取皮肤为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 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 -- 生成发送给客户端的皮肤数据 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 net.body1 = skinCfg.body1 or 0 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 -- 皮肤脱下 --[[ @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) end -- 皮肤穿戴 --[[ @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 if heroGrid.skinOn then skinOff(human,heroIdx) 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 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 SkinExcel = require("excel.skin").skin HeroExcel = require("excel.hero").hero SkillExcel = require("excel.skin").skill ItemExcel = require("excel.item").item end -- 优先使用皮肤的技能,新版本没有默认返回false function setSkill(human,heroInd,heroConf,obj) return false --[[if not human then return end if not human.db.skinBag then --假人 return end local bagDB = getBag(human) local skinSkillID = human.heroSkin[heroInd] and human.heroSkin[heroInd][2] if not skinSkillID then return end local skillConf = SkillExcel[skinSkillID] Skill.setSkill(obj, heroConfig,skillConf) BeSkill.setBeSkill(obj,heroConf,skillConf) return true]] end function checkHeroSkinById(human,heroId) if not human then return end local heroIdxList = HeroLogic.getHeroListById(human,heroId) if not next(heroIdxList) then return end local idx = heroIdxList[1] return human.db.heroBag[idx].skinOn end function checkHeroSkin(human, heroInd) if not heroInd then return end 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,true else return end]] end -- 检查是否有皮肤body function getBody(human,heroInd) if not heroInd then return end local heroId = HeroLogic.getHeroIdByIndex(human,heroInd) local heroGrid = HeroLogic.getHeroGrid(human,heroId,heroInd) if not heroGrid then return end local skinId = heroGrid.skinOn if not skinId then return end if SkinExcel[skinId].heroId == heroId then return SkinExcel[skinId].body,SkinExcel[skinId].head else print("[getBody] 英雄装备的身体ID不正确 heroId = "..heroId) local tHeroCof = HeroExcel[heroId] if tHeroCof then print("[getBody] 英雄装备的身体ID不正确,返回基础配置 heroId = "..heroId.." body = "..tHeroCof.body.." head = "..tHeroCof.head) return tHeroCof.body, tHeroCof.head end 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 return SkinExcel[skinID].body,SkinExcel[skinID].head end]] end function getHeroSkin(human,heroInd) local heroId = HeroLogic.getHeroIdByIndex(human,heroInd) if not heroId then return end 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) if human.heroSkin[heroInd] then local skinInd = human.heroSkin[heroInd][1] local skinID = bagDB[skinInd].id local skinConf = SkinExcel[skinID] local skillConf = SkillExcel[human.heroSkin[heroInd][2]] return skinConf,skillConf end]=] 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 msgRet.isEnd = 1 local bSend = false 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 Msg.send(msgRet,human.fd) msgRet.isEnd = 2 bSend = true end end msgRet.list[0] = cnt if bSend then msgRet.isEnd = 3 end 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) --更新数据 RoleAttr.cleanHeroAttrCache(human) -- RoleAttr.doCalc(human) ObjHuman.doCalcHero(human) ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI) skinQuery(human) 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 -- 登录检测英雄皮肤装备数据 function OnLoginCheckEquipSkin(human, bSyncClient) if not human then return end local skinBag = human.db.skinBag if not skinBag then return end -- 检测的英雄 local tCheckHero = {} for i = 1,#skinBag do local data = skinBag[i] local nSkinID = data.id local tConfig = SkinExcel[nSkinID] if not tConfig then print("[OnLoginCheckEquipSkin] 严重问题, 找不到对应皮肤的配置 nSkinID = "..nSkinID) break end local nHeroID = tConfig.heroId tCheckHero[nHeroID] = tCheckHero[nHeroID] or {} -- 找所有皮肤中是否有装备着的 local bEquip, nNowSkinID = false, 0 for nHaveSkinID, v in pairs(tCheckHero[nHeroID]) do if v == 1 then bEquip = true nNowSkinID = nHaveSkinID break end end if data.state == 1 then if false == bEquip then tCheckHero[nHeroID][nSkinID] = 1 -- 装备标识 -- 所有英雄进行装备皮肤 local heroIdxList = HeroLogic.getHeroListById(human, nHeroID) local headID = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_1) local bodyID = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_3) for _,idx in ipairs(heroIdxList) do human.db.heroBag[idx].skinOn = nSkinID -- RoleHeadLogic.setHead(human,tConfig.head,RoleHeadLogic.HEAD_TYPE_1) -- if tConfig.body ~= 0 then -- RoleHeadLogic.setHead(human,tConfig.body,RoleHeadLogic.HEAD_TYPE_3) -- end end if headID <= 0 then RoleHeadLogic.setHead(human,tConfig.head,RoleHeadLogic.HEAD_TYPE_1) end if bodyID <= 0 and tConfig.body ~= 0 then RoleHeadLogic.setHead(human,tConfig.body,RoleHeadLogic.HEAD_TYPE_3) end print("[OnLoginCheckEquipSkin] 对玩家英雄设置了皮肤 nSkinID = "..nSkinID.." nHeroID = "..nHeroID) else tCheckHero[nHeroID][nSkinID] = 0 -- 未装备标识 data.state = 0 print("[OnLoginCheckEquipSkin] 同一个英雄穿上了两个皮肤!! 进行修正 nHeroID = " .. nHeroID.." nNowSkinID = "..nNowSkinID .. " nSkinID = "..nSkinID) end else tCheckHero[nHeroID][nSkinID] = 0 -- 未装备标识 if false == bEquip then local heroIdxList = HeroLogic.getHeroListById(human, nHeroID) local heroCfg = HeroExcel[nHeroID] 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 headID = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_1) local bodyID = RoleHeadLogic.getRoleAppearance(human, RoleHeadLogic.HEAD_TYPE_3) if headID <= 0 then RoleHeadLogic.setHead(human,tConfig.head,RoleHeadLogic.HEAD_TYPE_1) end if bodyID <= 0 then RoleHeadLogic.setHead(human,tConfig.body,RoleHeadLogic.HEAD_TYPE_3) end print("[OnLoginCheckEquipSkin] 对玩家英雄设置取消了皮肤 nHeroID = "..nHeroID.." nSkinID = "..nSkinID) end end end if bSyncClient then skinQuery(human) print("[OnLoginCheckEquipSkin] 同步数据结束") end end