外观称号系统设计及实现

外观称号系统设计及实现

Scroll Down

前言

时装、头像、称号、头像框、聊天气泡都是统一的数据格式,穿戴外观id、已有列表、有效期,想进行统一管理

外观管理Base类

参考模板和策略设计模式,数据整合和应用接口都放在公共管理类,各实体类只需调用和实现自身简单逻辑

local oo = require "class"
local server = require "server"
local lua_app = require "lua_app"
local AchievementConfig = require "resource.AchievementConfig"

local EffectBase = oo.class()
function EffectBase:ctor(role)
	self.role = role
	self.player = role.player
end

function EffectBase:Load()
	self:WearPartHook(self.cache.wearid)
end

function EffectBase:SecondTimer()
	if self.sectimer then
		lua_app.del_timer(self.sectimer)
		self.sectimer = nil
	end
	local function _DoSecond()
		self.sectimer = lua_app.add_timer(1000, _DoSecond)
		self:CheckTerm()
	end
	self.sectimer = lua_app.add_timer(1000, _DoSecond)
end

function EffectBase:onLogout()
	if self.sectimer then
		lua_app.del_timer(self.sectimer)
		self.sectimer = nil
	end	
end

function EffectBase:onInitClient()
	if self.conf == "TitleConf" then
		self:SecondTimer()
	end	
	self:CheckTerm()
	self:SendClientMsg()
end

-- 检查过期的
function EffectBase:CheckTerm()
	local now = lua_app.now()
	local newownlist = {}
	local outdatelist = {}
	for id, _ in pairs(self.cache.ownlist) do
		if self.cache.ownlist[id].term and self.cache.ownlist[id].term > 0 and now > self.cache.ownlist[id].term then
			table.insert(outdatelist, id)
			self.cache.ownlist[id] = nil
		else
			table.insert(newownlist, id)
		end
	end

	for _, id in pairs(outdatelist) do
		print("EffectBase:CheckTerm effect outdate---", id)
		if self.cache.wearid == id then
			self.cache.wearid = 0
		end
		local itemconf = self:GetItemConfig(id)
		if itemconf then
			-- server.sendErr(self.player, itemconf.name.."已过期")
			self:SendClientMsg()
			if itemconf.attrpower then 
				self.role:UpdateBaseAttr(itemconf.attrpower, {})
			end
		end
	end
end

--激活
function EffectBase:ActivatePart(effectCfg,buytype)
	if buytype then
		local conf = self:GetItemConfig(effectCfg.id)
		if conf.cost then
			if not self.player:PayRewards({conf.cost},server.baseConfig.YuanbaoRecordType.Fashion) then
				server.sendErr(self.player, "物品不足购买")
				return false
			end
		end
	end
	return self:DoActivatePart(effectCfg)
end

function EffectBase:DoActivatePart(effectCfg)
	local partid = effectCfg.id
	local time = effectCfg.time
	local conf = self:GetItemConfig(partid)
	print("EffectBase:DoActivatePart----------", partid)
	self.cache.ownlist[partid] = self.cache.ownlist[partid] or {}
	local term = self.cache.ownlist[partid].term
	if term then
		if term == 0 then
			lua_app.log_info("partid is Activate",partid)
			--server.sendErr(self.player, "partid is Activate",partid)
			if self.conf == "FashionDressConfig" or self.conf == "TouXiangKuangConfig" or self.conf == "QiPaoConfig" then
				--时装提示
				server.chatCenter:sendTipMsg(1212,self.player.dbid)
			end	
			return false
		end 
		if  time == 0 then
			self.cache.ownlist[partid].term = time
		else
			self.cache.ownlist[partid].term = term + time
		end	
	else
		if time == 0 then
			self.cache.ownlist[partid].term = time
		else
			self.cache.ownlist[partid].term = lua_app.now() + time
		end
		--新激活称号增加属性
		--附加属性
		local attrs = {}
		attrs = conf.attrpower
		if attrs then
			self:UpdateBaseAttr(attrs)
		end
	end
	self.cache.wearid = partid
	self:ActivatePartHook(partid,time)
	self:WearPartHook(partid)
	self:SendClientMsg()
	if time == 0 then
		--触发累计装扮成就
		local args = {}
		args.myEntityID = self.player.entityID
		args.require  = AchievementConfig.CountType.fashion_have.name
		args.countType =  AchievementConfig.CountType.fashion_have.name
		args.groupdata =  AchievementConfig.Type.sign
		args.EventID = server.enEvent.PlayerEvnt.EVENTID_ACHIEVEMENT_CHECK
		self.player:FireEvent(args.EventID,args)
	end
	return true
end

--删除
function EffectBase:RemovePart(partid)
	if not self.cache.ownlist[partid] then
		return
	end	

	if self.cache.wearid == partid then
		self.cache.wearid = 0
	end
	local itemconf = self:GetItemConfig(partid)
	if itemconf then
		if itemconf.attrpower then 
			self.role:UpdateBaseAttr(itemconf.attrpower, {},self.attrRecord)
		end
	end
	self.cache.ownlist[partid] = nil
	self:RemovePropid(partid)
	self:SendClientMsg()
end

function EffectBase:ActivatePartHook(_, _)
end

function EffectBase:RemovePropid(_)
end

function EffectBase:WearPartHook(_)
end

--改变
function EffectBase:ChangePart(partid)
	if not self.cache.ownlist[partid] and partid ~= 0 then 
		print("EffectBase:notPart----------", partid)
		return
	end
	--双击取消
	if self.cache.wearid == partid then
		self.cache.wearid = 0 
	else
		self.cache.wearid = partid
	end
	self:SendClientMsg()
	self:WearPartHook(self.cache.wearid)
end

function EffectBase:UpdateBaseAttr(attrs)
	self.role:UpdateBaseAttr({}, attrs,self.attrRecord)
end

function EffectBase:GetMsgData()
	local datas = {}
	datas.wearid = self.cache.wearid
	datas.ownlist = {}
	for id,data in pairs(self.cache.ownlist) do
		table.insert(datas.ownlist, {
				id = id,
				term = data.term,
			})
	end
	return datas
end

function EffectBase:GetBaseConfig()
	return server.configCenter[self.conf]
end

function EffectBase:GetItemConfig(id)
	local confing = self:GetBaseConfig()
	local item = confing[id]
	if not item then
		lua_app.log_error(">>EffectBase:GetItemConfig not exist id.", self.conf, id)
		return 
	end
	return (item[self.player.cache.sex] or item)
end

function EffectBase:GetOwnlistData()
	return self.cache.ownlist
end

function EffectBase:SendClientMsg()
end

return EffectBase

时装类

继承base类,创建时加载玩家数据,调用只需激活自身模型id和发送提示即可
SendClientMsg推送接口其实也能提取出来按type类型区分

local oo = require "class"
local server = require "server"
local EffectConfig = require "resource.EffectConfig"
local EffectBase = require "player.role.effect.EffectBase"
local AchievementConfig = require "resource.AchievementConfig"

local Fashion = oo.class(EffectBase)
Fashion.id = server.baseConfig.YuanbaoRecordType.Fashion
Fashion.describe = ""
Fashion.conf = "FashionDressConfig"
Fashion.attrRecord = 17

function Fashion:ctor(_)
end

function Fashion:onCreate()
	self:onLoad()
end

function Fashion:onLoad()
	self.cache = self.role.cache.fashion_data
	self:Load()
end

function Fashion:WearPartHook(partid)
	--模型更新
	local modelID = 0
	if partid == 0 then
		modelID = server.configCenter.RaceConfig[self.player.cache.character].model
	else
		modelID = self:GetItemConfig(partid).appearanceID
	end
	self.player.prop.modelID = modelID
	self.role:SetShow(EffectConfig.SpecialType.Fashion, modelID)
end

function Fashion:ActivatePartHook(partid,time)
	--激活特殊处理
	local conf = self:GetItemConfig(partid)
	local str = ""
	if time == 0 then
		str = "永久"
	else
		str = math.floor(time / 60 /60 /24).."天"
	end
	server.chatCenter:sendTipMsg(1211,self.player.dbid,conf.name,str)
	--同时激活时装成就
	local args = {}
	args.myEntityID = self.player.entityID
	args.groupdata =  AchievementConfig.Type.sign
	args.require =  "fashion_dress"
	args.value =  #self.cache.ownlist
	args.EventID = server.enEvent.PlayerEvnt.EVENTID_ACHIEVEMENT_CHECK
	self.player:FireEvent(args.EventID,args)
end

function Fashion:Release()
end

function Fashion:SendClientMsg()
	local msg = self:GetMsgData()
	server.sendReq(self.player, "sc_effect_fashion_update", msg)
end

server.playerCenter:SetEvent(Fashion, "role.fashion")
return Fashion

称号类

同上,只需写自身加载属性方法,设置称号即可

local oo = require "class"
local server = require "server"
local EffectBase = require "player.role.effect.EffectBase"
local GuildConfig = require "common.resource.GuildConfig"
local EffectConfig = require "resource.EffectConfig"

local TitleEffect = oo.class(EffectBase)
TitleEffect.id = server.baseConfig.YuanbaoRecordType.Title
TitleEffect.describe = ""
TitleEffect.conf = "TitleConf"
TitleEffect.attrRecord = 15

function TitleEffect:ctor(_)
end

function TitleEffect:onCreate()
	self:onLoad()
end

function TitleEffect:onLoad()
	self.cache = self.role.cache.title_data
	self:Load()
	self:LoadAttrs()
end

function TitleEffect:SendClientMsg()
	local msg = self:GetMsgData()
	server.sendReq(self.player, "sc_effect_title_update", msg)
end

--附加属性
function TitleEffect:LoadAttrs()
	for id, _ in pairs(self.cache.ownlist) do
		local conf = server.configCenter[self.conf][id]
		--附加属性
		if conf.attrpower then
			self.role:UpdateBaseAttr({}, conf.attrpower,self.attrRecord)
		end
	end
end

function TitleEffect:WearPartHook(partid)
	self.player.prop.titleid = partid
	self.role:SetShow(EffectConfig.SpecialType.Title, partid)
end

function TitleEffect:RemovePropid(partid)
	if self.player.prop.titleid == partid then
		self.player.prop.titleid = 0
	end
end

function TitleEffect:Release()
end

server.playerCenter:SetEvent(TitleEffect, "role.titleeffect")
return TitleEffect

客户端协议和接口

--*******************head
local server = require "server"
local lua_app = require "lua_app"
local lua_util = require "lua_util"

--[[
# 激活称号
cs_effect_title_activate 14001 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_title_activate(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.titleeffect:ActivatePart(msg.id,1)
end

--[[
# 改变称号
cs_effect_title_change 14002 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_title_change(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.titleeffect:ChangePart(msg.id)
end

--[[
# 激活皮肤
cs_effect_skin_activate 14011 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_skin_activate(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.skineffect:ActivatePart(msg.id,1)
end

--[[
# 改变皮肤
cs_effect_skin_change 14012 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_skin_change(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.skineffect:ChangePart(msg.id)
end

--[[
# 激活时装
cs_effect_fashion_activate 14021 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_fashion_activate(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.fashion:ActivatePart(msg.id,1)
end

--[[
# 改变时装
cs_effect_fashion_change 14022 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_fashion_change(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.fashion:ChangePart(msg.id)
end

--[[
# 激活头像
cs_effect_headshow_activate 14031 {
	request {
		id			0 : integer
	}
	response {
		ret			0 : boolean
	}
}
]]
function server.cs_effect_headshow_activate(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.headshow:ActivatePart(msg.id,1)
end

--[[
# 改变头像
cs_effect_headshow_change 14032 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_headshow_change(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.headShow:ChangePart(msg.id)
end

--[[
# 改变气泡
cs_effect_qipao_change 14051 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_qipao_change(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.qipao:ChangePart(msg.id)
end

--[[
# 激活气泡
cs_effect_qipao_activate 14052 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_qipao_activate(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.qipao:ActivatePart(msg.id,1)
end

--[[
# 改变头像框
cs_effect_headshowframe_change 14061 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_headshowframe_change(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.headShowFrame:ChangePart(msg.id)
end

--[[
# 激活头像框
cs_effect_headshowframe_activate 14062 {
	request {
		id			0 : integer
	}
}
]]
function server.cs_effect_headshowframe_activate(socketid, msg)
    local player = server.playerCenter:GetPlayerBySocket(socketid)
    player.role.headShowFrame:ActivatePart(msg.id,1)
end