成就系统实现

成就系统实现

Scroll Down

简介及需求

成就系统是游戏常见的功能模块,主要就是在用户达成某种条件时进行判定记录成就,难点在于嵌入各种各样的其它功能。
在这里插入图片描述

数据结构

数据库数据

--保存数据字段
{ "achievement" 	 		,"mediumblob"		,{
				achievements = {},
				point = 0,
				pointReward = {},
				countdata = {},
				isrecord = {},
		}		,"成就数据" },
--成就类加载数据		
function Achievement:onLoad()
	self.cache = self.player.cache.achievement
	self.cache.countdata = self.cache.countdata or {}
	self.cache.isrecord = self.cache.isrecord or {}
	self.ConfigList = groupby(server.configCenter.AchievementConfig)
end

数据内容

统计类型的数据种类繁多,还在不断更新增加中,其它的不需统计数据发成就id和value值即可

#成就信息
sc_achievement_info 31301 {
	request {
		achievements	0 : *group_data #成就分组
		point			1 : integer		#成就点
		countdata		2 : valuedata	#成就达成值
	}
}

# 成就数据
.achievement_data {
   	id		0 : integer 	#成就id
	time	1 : integer		#获得时间
	groupID	2 : integer		#组id
	typeID	3 : integer		#子类型id
	value	4 : integer		#达到数值	--更新成就才有此字段
	point	5 : integer		#成就点
}

.type_data {
	typeid			0: integer
	achievedata		1: *achievement_data
}

# 成就类型数据
.group_data {
	groupid		0 : integer
   	typedata	1 : *type_data 	#组类型数据
}

#更新成就
sc_achievement_update 31302 {
	request {
		achievementdata		0 : achievement_data 
	}
}
# 成就统计达成数据
.valuedata {
	equip_gem			0 : integer         #宝石等级
	equip_jinglian		1 : integer         #精炼等级
	equip_wash			2 : integer         #重铸次数
	pet_compose			3 : integer         #宠物合成次数
	partner_unlock		4 : integer         #仙君解锁个数
	partner_call		5 : integer         #仙君召唤次数
	sign				6 : integer         #累计签到次数
	sect				7 : integer         #门派技能
	union				8 : integer         #帮派技能
	xiulian_role		9 : integer         #角色修炼技能
	xiulian_pet			10 : integer        #宠物修炼技能
	chat_speak			11 : integer        #世界聊天次数
	money				12 : integer        #累计获得银币
	fengyao				13 : integer        #封妖任务次数
    chumo			    14 : integer        #除魔任务次数
    chumo_leader		15 : integer        #带队除魔任务次数
    yaowang			    16 : integer        #击杀妖王统计
    shengxiao			17 : integer        #累计击杀十二生肖
    xingguan			18 : integer        #累计击杀九曜星官
    union_guildcontribute	19 : integer    #累计帮派贡献
    union_donate		20 : integer        #累计上交帮派日志
    union_daytask		21 : integer        #累计帮派日常
    kid_num		        22 : integer        #拥有子女数量
	pet_wash			23 : integer        #宠物洗练次数
	pet_skill_learn		24 : integer        #宠物技能学习次数
	pet_catch		    25 : integer        #捕捉宠物累积次数
	partner_call_ten	26 : integer        #仙君十连召唤次数
	mount_num       	27 : integer        #激活坐骑数
	fashion_dress       28 : integer        #同时激活时装数
	fashion_headshow    29 : integer        #同时激活头像数
	fashion_touxiangkuang   30 : integer    #同时激活头像框数
	fashion_qipao       31 : integer        #同时激活气泡数
	bianshen_count      32 : integer        #使用变身卡次数
	union_qiyuan        33 : integer        #帮派祈愿次数
	pet_skill_special   34 : integer        #变异宠物数量
	partner_quality4    35 : integer        #橙色仙君数量
	partner_quality5    36 : integer        #红色仙君数量
	kid_growup_num		37 : integer        #拥有成年子女数量
	mount_top_num		38 : integer        #拥有9阶坐骑数量
	fashion_have		39 : integer        #永久装扮数量
	industry1		    40 : integer        #采矿等级
	industry2		    41 : integer        #炼药等级
	industry3		    42 : integer        #钓鱼等级
	energyUse1		    43 : integer        #累计烹饪次数
	energyUse2		    44 : integer        #累计炼药次数
	energyUse3		    45 : integer        #累计附魔次数
	worldAnswer_num		46 : integer        #累计世界答题次数
	friend_num		    47 : integer        #好友数量
	vipCard_count1		48 : integer        #累计购买周卡次数
    vipCard_count2		49 : integer        #累计购买月卡次数
    building_level1		50 : integer        #房屋等级
    building_level2		51 : integer        #农田等级
    building_level3		52 : integer        #牧场等级
    building_level4		53 : integer        #树圃等级
    building_speed		54 : integer        #累计使用家园卡次数
    house_plant		    55 : integer        #累计种植农田次数
    house_animal		56 : integer        #累计牧场养殖次数
    house_tree		    57 : integer        #累计家园祈愿次数
    house_environment	58 : integer        #家园环境度
    active_point_150	59 : integer        #每日活跃度达成150点累计
    battle_all_shengxiao     60 : integer   #累计击败十二生肖种类
    battle_id_all_shengxiao  61 : integer   #累计击败五星十二生肖
    battle_all_xingguan      62 : integer   #累计击败星官种类
    battle_id_all_xingguan   63 : integer   #累计击败五星星官
    mission_list	         64 : integer   #累计完成师门任务
    mission_yabiao	         65 : integer   #累计完成运镖任务
    mission_xuncheng	     66 : integer   #累计完成巡城任务
    mission_xianyuan	     67 : integer   #累计完成仙缘任务
    achieve_all_xianyuan     68 : integer   #累计完成仙缘种类
    baotu_count              69 : integer   #累计挖宝次数
    baotuxiaoyao_count       70 : integer   #累计逍遥宝图挖宝次数
    baotu_item_low           71 : integer   #累计挖到低阶兽决
    baotu_item_high          72 : integer   #累计挖到高阶兽决
}

成就设计

成就配置

配置表格:
在这里插入图片描述
项目代码对应配置:

local AchievementConfig = {}

--成就类型
AchievementConfig.Type = {
	level		 = {groupID=1,typeID=1},	--等级
	prop 		 = {groupID=1,typeID=2},	--属性
	equip 	   	 = {groupID=1,typeID=3},	--装备
	pet			 = {groupID=1,typeID=4},	--宠物
	partner  	 = {groupID=1,typeID=5},	--仙君
	child 	 	 = {groupID=1,typeID=6},	--子女
	mount	 	 = {groupID=1,typeID=7},	--坐骑
	sign	 	 = {groupID=1,typeID=8},	--累计签到
	guanzhi	 	 = {groupID=1,typeID=9},	--官职
	skill		 = {groupID=2,typeID=1},	--门派技能
	guildskill	 = {groupID=2,typeID=2},	--帮派技能
	xiulian  	 = {groupID=2,typeID=3},	--修炼技能
	fishdrug  	 = {groupID=2,typeID=4},	--副职业技能
	bianshen  	 = {groupID=2,typeID=6},	--变身
	worldchat 	 = {groupID=3,typeID=1},	--世界聊天
	friend 		 = {groupID=3,typeID=2},	--统计好友数量
	money 		 = {groupID=3,typeID=3},	--统计银币数量
	vipCard 	 = {groupID=3,typeID=4},	--统计vip信息
	house 		 = {groupID=3,typeID=5},	--统计家园信息
	houseplan 	 = {groupID=3,typeID=6},	--统计家园农作信息
	environment  = {groupID=3,typeID=7},	--统计家园风水环境信息
	mission 	 = {groupID=4,typeID=1},	--主线任务完成
	fb 	 		 = {groupID=4,typeID=2},	--副本完成
	active	 	 = {groupID=5,typeID=1},	--活跃度
	chumofengyao = {groupID=5,typeID=2},	--封妖除魔任务
	yaowang		 = {groupID=5,typeID=3},	--妖王
	shengxiao	 = {groupID=5,typeID=4},	--生肖
	xingguan	 = {groupID=5,typeID=5},	--星官
	sect		 = {groupID=5,typeID=6},	--门派任务
	baotu		 = {groupID=5,typeID=7},	--挖宝
	xuncheng 	 = {groupID=5,typeID=8},	--累计完成运镖皇城任务
	mission3 	 = {groupID=5,typeID=9},	--累计完成300环任务链
	xianyuan	 = {groupID=5,typeID=10},	--累计完成仙缘任务
	union	 	 = {groupID=6,typeID=1},	--帮派
}

--tupe为1统计数+1,type=2特殊处理
AchievementConfig.CountType = {
	equip_wash	 =  {name = "equip_wash",type = 1},	--锻造装备次数
	pet_wash  =  {name = "pet_wash",type = 1},	--宠物洗练次数
	pet_compose  =  {name = "pet_compose",type = 1},	--宠物合成次数
	pet_skill_learn  =  {name = "pet_skill_learn",type = 1},	--宠物技能学习次数
	pet_catch  =  {name = "pet_catch",type = 1},	--捕捉宠物累积次数
	partner_call =  {name = "partner_call",type = 1},	--仙君召唤次数
	partner_call_ten =  {name = "partner_call_ten",type = 1},	--仙君十连召唤次数
	chat_speak   =  {name = "chat_speak",type = 1},	--世界频道发言
	money   	 =  {name = "money",type = 1},		--累计获得银币
	active_point =  {name = "active_point",type = 2},--每日活跃度达成
	fengyao 	 =  {name = "fengyao",type = 1},		--累计制服捣乱妖怪
	chumo   	 =  {name = "chumo",type = 1},		--除魔任务统计
	chumo_leader =  {name = "chumo_leader",type = 1},	--带队完成除魔任务统计
	yaowang   	 =  {name = "yaowang",type = 1},		--击杀妖王统计
	shengxiao 	 =  {name = "shengxiao",type = 1},	--累计击杀十二生肖
	xingguan   	 =  {name = "xingguan",type = 1},		--累计击杀九曜星官
	union_guildcontribute   =  {name = "union_guildcontribute",type = 1},	--累计帮派贡献
	union_rob  =  {name = "union_rob",type = 1},	--累计击杀帮派强盗
	union_donate  =  {name = "union_donate",type = 1},	--累计上交帮派日志
	union_store   =  {name = "union_store",type = 1},		--累计帮派跑商
	union_daytask =  {name = "union_daytask",type = 1},		--累计帮派日常
	union_qiyuan =  {name = "union_qiyuan",type = 1},	--累计帮派祈愿次数
	bianshen_count =  {name = "bianshen_count",type = 1},	--累计使用变身卡次数
	fashion_have =  {name = "fashion_have",type = 1},	--累计激活永久装扮
	energyUse1 =  {name = "energyUse1",type = 1},	--累计烹饪次数
	energyUse2 =  {name = "energyUse2",type = 1},	--累计炼药次数
	energyUse3 =  {name = "energyUse3",type = 1},	--累计附魔次数
	worldAnswer_num =  {name = "worldAnswer_num",type = 1},	--累计世界答题次数
	worldAnswer_lucky =  {name = "worldAnswer_lucky",type = 1},	--累计世界答题幸运奖励次数
	vipCard_count1 =  {name = "vipCard_count1",type = 1},	--累计购买周卡次数
	vipCard_count2 =  {name = "vipCard_count2",type = 1},	--累计购买月卡次数
	building_speed =  {name = "building_speed",type = 1},	--累计使用家园卡次数
	house_plant =  {name = "house_plant",type = 1},	--累计种植农田次数
	house_animal =  {name = "house_animal",type = 1},	--累计牧场养殖次数
	house_tree =  {name = "house_tree",type = 1},	--累计家园祈愿次数
	fbdifu1 =  {name = "fbdifu1",type = 1},	--累计通关副本普通地府次数
	fbdifu2 =  {name = "fbdifu2",type = 1},	--累计通关副本精英地府次数
	active_point_150 =  {name = "active_point_150",type = 1,isrecord = true},	--累计每日活跃度达到150次数,每日只能达成一次
	battle_all_shengxiao =  {name = "battle_all_shengxiao",type = 1},	--这个手动特殊存,累计击败所有种类的十二生肖
	battle_id_all_shengxiao =  {name = "battle_id_all_shengxiao",type = 1,all={2003,2013,2023,2033,2043,2053,2063,2073,2083,2093,2103,2113}},	--这个手动特殊存,累计击败所有五星十二生肖
	battle_all_xingguan =  {name = "battle_all_xingguan",type = 1},	--这个手动特殊存,累计击败所有种类的星官
	battle_id_all_xingguan =  {name = "battle_id_all_xingguan",type = 1,all={2003,2013,2023,2033,2043,2053,2063,2073,2083,2093,2103,2113}},	--这个手动特殊存,累计击败所有五星星官
	mission_list =  {name = "mission_list",type = 1},	--累计师门任务次数
	mission_yabiao   =  {name = "mission_yabiao",type = 1},	--累计运镖任务次数
	mission_xuncheng =  {name = "mission_xuncheng",type = 1}, --累计巡城任务次数
	mission_xianyuan =  {name = "mission_xianyuan",type = 1}, --累计仙缘任务次数
	achieve_all_xianyuan =  {name = "achieve_all_xianyuan",type = 1,all={5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714}},	--这个手动特殊存,累计完成所有仙缘
	baotu_count =  {name = "baotu_count",type = 1}, --累计挖宝次数
	baotuxiaoyao_count =  {name = "baotuxiaoyao_count",type = 1}, --累计逍遥宝图挖宝次数
	baotu_item_low =  {name = "baotu_item_low",type = 1,all={1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547}},--累计挖到兽决
	baotu_item_high =  {name = "baotu_item_high",type = 1,all={1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597}},--累计挖到高级兽决
	roleaddexp_count =  {name = "roleaddexp_count",type = 1}, --累计人物经验书
}

成就按类型分组发送给客户端,也可以按组验证查询成就

local groupby = function(list)
	local achievelist = {}
    for _,v in pairs(list) do
		if not achievelist[v.groupID] then
			achievelist[v.groupID] = {}
		end
		if not achievelist[v.groupID][v.typeID] then
			achievelist[v.groupID][v.typeID] = {}
		end
		table.insert(achievelist[v.groupID][v.typeID],v)
	end
	return achievelist
end

function Achievement:onLoad()
	self.cache = self.player.cache.achievement
	self.cache.countdata = self.cache.countdata or {}
	self.cache.isrecord = self.cache.isrecord or {}
	self.ConfigList = groupby(server.configCenter.AchievementConfig)
end

--获取分组list
function Achievement:GetConfigList(groupID,typeID)	
	return self.ConfigList[groupID][typeID]
end

成就管理

成就事件

登陆注册事件,触发成就验证方法为onEventCheck,事件详情请看事件系统设计

function Achievement:onLogin()
	if not self.achievementEvent then
		self.achievementEvent = self.player:SubEvent(server.enEvent.PlayerEvnt.EVENTID_ACHIEVEMENT_CHECK,self.onEventCheck,self)
	end
	if not self.propChangeE then
		self.propChangeE = self.player:SubEvent(server.enEvent.PlayerEvnt.EVENTID_ENTITY_RPOP_CHANGE,self.onEntityPropChange,self)
	end
	if not self.TaskEvent then
		self.TaskEvent = self.player:SubEvent(server.enEvent.PlayerEvnt.EVENTID_ENTITY_SUBMIT_TASK,self.onTaskSubmit,self)
	end

	if not self.BattleEndEvent then
		self.BattleEndEvent = self.player:SubEvent(server.enEvent.PlayerEvnt.EVENTID_ENTITY_BATTLE_END,self.onBattleEnd,self)
	end
end

成就触发

1.写入方法内,以仙君抽奖为例,在仙君抽奖方法中触发抽奖统计和解锁仙君数量验证

    --触发仙君抽奖
	local args = {}
    args.myEntityID = self.player.entityID
    args.require  = AchievementConfig.CountType.partner_call.name
	args.countType =  AchievementConfig.CountType.partner_call.name
	args.groupdata =  AchievementConfig.Type.partner
	args.value = itemcfg.num
	args.EventID = server.enEvent.PlayerEvnt.EVENTID_ACHIEVEMENT_CHECK
	self.player:FireEvent(args.EventID,args)

--触发仙君增加
	local args = {}
	args.myEntityID = self.player.entityID
	args.require  = "partner_unlock"
	args.value  =   count
	args.groupdata =  AchievementConfig.Type.partner
	args.EventID = server.enEvent.PlayerEvnt.EVENTID_ACHIEVEMENT_CHECK
	self.player:FireEvent(args.EventID,args)

2.原有事件触发

--触发人物升级
function Achievement:onLevelUp()
	local args = {require = "level",value = self.player.cache.level,groupdata = AchievementConfig.Type.level}--对应finishRequire的 {"level",type,value=100}
	self:onEventCheck(args)
end

--任务提交判定成就
function Achievement:onTaskSubmit(args)
	local isachieve = false
	--正常主线是这样的
	local config =  server.configCenter.missionConfig[args.missionID]
	local tab = {require = "mission",id = args.missionID, value = 1}
	--主线
	if config.mType == "main_line" then
		tab.groupdata = AchievementConfig.Type.mission
		isachieve = true
		--封妖
	elseif args.missionID == 113 then
		tab.groupdata = AchievementConfig.Type.chumofengyao
		tab.countType =  AchievementConfig.CountType.fengyao.name
		isachieve = true
		--除魔
	elseif args.missionID == 112 then
		tab.groupdata = AchievementConfig.Type.chumofengyao
		tab.countType =  AchievementConfig.CountType.chumo.name
		isachieve = true
		--队长除魔触发带队除魔统计统计
		local team = server.teamMgr:getTeam(self.player.prop.teamid)
		if team and team.leader.dbid == self.player.dbid and #team.memlist >= 2 then
			local tab2 = {groupdata = AchievementConfig.Type.chumofengyao,require = AchievementConfig.CountType.chumo_leader.name,countType = AchievementConfig.CountType.chumo_leader.name}
			self:onEventCheck(tab2)
		end
		--帮派日常
	elseif args.missionID == 116 then
		tab.groupdata = AchievementConfig.Type.union
		tab.countType =  AchievementConfig.CountType.union_daytask.name
		isachieve = true
		--运镖日常
	elseif args.missionID == 114then
		tab.groupdata = AchievementConfig.Type.xuncheng
		tab.countType =  AchievementConfig.CountType.mission_yabiao.name
		isachieve = true
		--巡城日常
	elseif args.missionID == 115then
		tab.groupdata = AchievementConfig.Type.xuncheng
		tab.countType =  AchievementConfig.CountType.mission_xuncheng.name
		isachieve = true
		--师门任务累计
	elseif config.name == "师门任务" then
		local tab2 = {groupdata = AchievementConfig.Type.sect,require = AchievementConfig.CountType.mission_list.name,id = args.missionID,countType = AchievementConfig.CountType.mission_list.name}
		self:onEventCheck(tab2)
	--仙缘
	elseif config.mType == "xianyuan" then
		tab.groupdata = AchievementConfig.Type.xianyuan
		isachieve = true
		--完成累计仙缘次数
		local tab2 = {groupdata = AchievementConfig.Type.xianyuan,require = "mission",type = "xianyuan",countType = AchievementConfig.CountType.xianyuan.name}
		self:onEventCheck(tab2)
		--判定是仙缘id
		if lua_util.inArray(args.cfgId,AchievementConfig.CountType.achieve_all_xianyuan.all) then
			local idname = AchievementConfig.CountType.achieve_all_xianyuan.name
			self.cache.countdata[idname] = self.cache.countdata[idname] or {}
			if not self.cache.countdata[idname][args.cfgId] then
				self.cache.countdata[idname][args.cfgId] = true
				local tab2 = {require = "achieve_all",groupdata = AchievementConfig.Type.xianyuan,countType = AchievementConfig.CountType.achieve_all_xianyuan.name}
				self:onEventCheck(tab2)
			end
		end
	end
	--触发misson任务
	if isachieve then
		self:onEventCheck(tab)
	end
end

成就验证及统计

当触发成就验证事件时,如果有对应的countType则统计,并将value值改为最新的统计值
成就判定,判定成就条件,type,id,value值,配置若有则需要相同,后续兼容包含,战斗回合等相反数值验证

-- 任务条件检查
function Achievement:onEventCheck(args)
	local achievetype = args.groupdata
	if not achievetype then
		return
	end
	local configlist = self:GetConfigList(achievetype.groupID,achievetype.typeID)
	if not configlist then
		return
	end
	--需统计成就数据
	args.value = args.value or 1
	if args.countType then
		for _, v in pairs(AchievementConfig.CountType) do
			if args.countType == v.name then
				--是否限时计数
				if v.isrecord then
					if self.cache.isrecord[AchievementConfig.CountType.active_point_150.name] then
						return
					end
					self.cache.isrecord[AchievementConfig.CountType.active_point_150.name] = true
				end
				--type1累加统计
				if v.type == 1 then
					local count = self.cache.countdata[args.countType] or 0
					self.cache.countdata[args.countType] = count + args.value
					args.value = self.cache.countdata[args.countType]
					break
				elseif v.type == 2 then
					--type2超过历史统计则替换,不过返回
					local count = self.cache.countdata[args.countType] or 0
					if args.value > count then
						self.cache.countdata[args.countType] = args.value
						break
					end
					return
				end
			end
		end
	end

	for _,v in pairs(configlist) do
		--未获得成就,完成条件一致
		local require = v.finishRequire
		if not self.cache.achievements[v.id] and require and require[1] == args.require then
			local  issuccess = true
			--判定存在的完成条件
			if require.type and args.type ~= require.type  then
				issuccess = false
			end
			if require.id then
				if type(require.id) == "table" then
					if not lua_util.inArray(args.id,require.id) then
						issuccess = false
					end
				elseif args.id ~= require.id then
					issuccess = false
				end
			end
			if require.value then
				if args.require == "battle_speed" then
					if args.value > require.value then
						issuccess = false
					end
				else
					if args.value < require.value then
						issuccess = false
					end
				end
			end
			if issuccess then
				self:AchievementComplete(v.id,args.value)
			end
		end
	end
end

成就达成及领奖

-- 完成成就
function Achievement:AchievementComplete(achievementid,value)
    local achievementconfig = server.configCenter.AchievementConfig[achievementid]
    if not achievementconfig then
		lua_app.log_info("Achievement:achievementconfig not id ",  achievementid)
		return false
	end
	if self.cache.achievements[achievementid] then
		lua_app.log_info("Achievement:achievementconfig exist id ",  achievementid)
		return false
	end
	
	local achievementdata = {id = achievementid,time = lua_app.now(),groupID = achievementconfig.groupID,typeID = achievementconfig.typeID,value = value or 0,point = achievementconfig.point }
	--发送更新数据
	self:GetReward(achievementid)
	self.cache.point = self.cache.point + achievementconfig.point
	server.sendReq(self.player, "sc_achievement_update",  {achievementdata = achievementdata })
	achievementdata.value = nil
	self.cache.achievements[achievementid] = achievementdata
	--成就点奖励
	local pointcfg = server.configCenter.AchievementGiftConfig
	for _,cfg in pairs(pointcfg) do
		if self.cache.point > cfg.point and not lua_util.inArray(cfg.id,self.cache.pointReward) then
			local mailconfig = server.configCenter.MailMsgConfig[cfg.mail]
			server.mailCenter:SendMail(self.player.dbid, mailconfig.title, mailconfig.desc, mailconfig.item)
			table.insert(self.cache.pointReward,cfg.id)
		end	
	end
end

-- 领取奖励
function Achievement:GetReward(achievementid)
    local achievementconfig = server.configCenter.AchievementConfig[achievementid]
    if achievementconfig then
	if achievementconfig.drop then
		local rewards = server.dropCenter:DropGroup(achievementconfig.drop)
			if rewards then
				self.player:GiveItem(rewards, 1, 1,server.baseConfig.YuanbaoRecordType.Achievement)
			end
		end
	end	
	
	if achievementconfig.title then
		self.role.titleeffect:ActivatePart({id = achievementconfig.title,time = 0})
	end
	
	if achievementconfig.tipMsg1 then
		for _,v in pairs(achievementconfig.tipMsg1) do
			local dbid = self.player.dbid
			if server.configCenter.TipMsgConfig[v].target == "union" then
				dbid = self.player.prop.guildid
			end	
			if dbid ~= 0 then
			--超链接
			server.chatCenter:ChatLink(v,self.player,nil,achievementconfig.name,{server.ChatLinkType.achievement,self.player.entityID,achievementid,lua_app.now()})
			end	
		end
	end

	if achievementconfig.tipMsg2 then
		for _,v in pairs(achievementconfig.tipMsg2) do
			local dbid = self.player.dbid
			if server.configCenter.TipMsgConfig[v].target == "union" then
				dbid = self.player.prop.guildid
			end	
			if dbid ~= 0 then
			--server.chatCenter:sendTipMsg(v,dbid,self.player.cache.name,achievementconfig.name)	
			--超链接
			server.chatCenter:ChatLink(v,self.player,nil,self.player.cache.name,achievementconfig.name,{server.ChatLinkType.achievement,self.player.entityID,achievementid,lua_app.now()})
			end	
		end
	end
end

累计重置

--重置当天累计
function Achievement:onDayTimer()
	local isrecord = self.cache.isrecord
	if isrecord[AchievementConfig.CountType.active_point_150.name] then
		isrecord[AchievementConfig.CountType.active_point_150.name] = false
	end
	--经验书
	local countdata = self.cache.countdata
	countdata[AchievementConfig.CountType.roleaddexp_count.name] = 0
end

总结

成就的难点,在于多种复合条件的验证判定,也囊括各种任务,帮派,活动,战斗等事件,非自己做的模块需要多花费时间操作