9748 【BT7】跨服BOSS定时活动(跨服妖魔boss;增加跨服日常活动时间控制;Boss刷新增加支持关联跨服日常活动;优化跨服boss复活剩余时间计算使用跨服时间;)
# Conflicts:
# ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
# ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
| | |
| | | list RandMailKeyList; //指定上架随机邮件列表,有配置时上架的时候在线玩家会收到一封上架邮件提醒
|
| | | };
|
| | |
|
| | | //跨服日常活动表
|
| | |
|
| | | struct tagCrossDailyAction
|
| | | {
|
| | | DWORD _DailyID; //活动ID
|
| | | dict OpenTimeDict; //开启时间
|
| | | DWORD Duration; //持续时间, 0为不限制
|
| | | dict NotifyInfo; //广播提示信息
|
| | | };
|
| | |
|
| | | //日常活动表
|
| | |
|
| | | struct tagDailyAction
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 11 跨服妖魔boss玩家伤害信息 #tagGCCrossYaomoBossPlayerHurtInfo
|
| | |
|
| | | class tagGCCrossYaomoBossPlayerHurtInfo(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("HurtTotal", c_int), # 总伤害值,小于亿部分
|
| | | ("HurtTotalEx", c_int), # 总伤害值,整除亿部分
|
| | | ("AwardState", c_int), # 伤害目标值领奖状态,按奖励记录索引位运算判断是否已领取
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xC0
|
| | | self.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xC0
|
| | | self.SubCmd = 0x11
|
| | | self.HurtTotal = 0
|
| | | self.HurtTotalEx = 0
|
| | | self.AwardState = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagGCCrossYaomoBossPlayerHurtInfo)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C0 11 跨服妖魔boss玩家伤害信息 //tagGCCrossYaomoBossPlayerHurtInfo:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | HurtTotal:%d,
|
| | | HurtTotalEx:%d,
|
| | | AwardState:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.HurtTotal,
|
| | | self.HurtTotalEx,
|
| | | self.AwardState
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCCrossYaomoBossPlayerHurtInfo=tagGCCrossYaomoBossPlayerHurtInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossYaomoBossPlayerHurtInfo.Cmd,m_NAtagGCCrossYaomoBossPlayerHurtInfo.SubCmd))] = m_NAtagGCCrossYaomoBossPlayerHurtInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 14 幸运云购开奖记录 #tagGCLuckyCloudBuyLotteryRecInfo
|
| | |
|
| | | class tagGCLuckyCloudBuyLotteryRec(Structure):
|
| | |
| | |
|
| | | return
|
| | |
|
| | | ## ================================================================================================
|
| | |
|
| | | def __GetTodayCrossDailyActionInfo():
|
| | | # 获取本日待处理的日常活动信息
|
| | | key = "TodayCrossDailyActionInfo"
|
| | | curTime = int(time.time())
|
| | | curDateStr = GameWorld.ChangeTimeNumToStr(curTime, ChConfig.TYPE_Time_YmdFormat) # 当天日期
|
| | | loadSign = curDateStr
|
| | | TodayDailyActionInfo = IpyGameDataPY.GetConfigEx(key)
|
| | | if TodayDailyActionInfo and TodayDailyActionInfo[0] == loadSign:
|
| | | GameWorld.DebugLog("已经加载过本日跨服日常活动处理信息!loadSign=%s" % loadSign)
|
| | | return TodayDailyActionInfo[1]
|
| | | |
| | | todayActionInfo = []
|
| | | |
| | | dayTime = GameWorld.GetServerTime()
|
| | | weekDay = str(dayTime.weekday() + 1) # 格式为json, 当前星期几, 1代表星期1
|
| | | |
| | | GameWorld.Log("===== 加载今天跨服日常活动信息 =====")
|
| | | GameWorld.Log("当前星期%s" % weekDay)
|
| | | |
| | | dailyTimeInfoList = []
|
| | | |
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for i in xrange(ipyDataMgr.GetCrossDailyActionCount()):
|
| | | dailyIpyData = ipyDataMgr.GetCrossDailyActionByIndex(i)
|
| | | dailyID = dailyIpyData.GetDailyID()
|
| | | |
| | | openTimeDict = dailyIpyData.GetOpenTimeDict()
|
| | | # 没有时间控制的,代表永久开放
|
| | | if not openTimeDict:
|
| | | todayActionInfo.append([dailyID])
|
| | | GameWorld.Log(" 增加本日常开跨服日常活动信息: dailyID=%s" % dailyID)
|
| | | continue
|
| | | |
| | | #如果星期key中存在 "0" 代表每日都开启
|
| | | if "0" not in openTimeDict and weekDay not in openTimeDict:
|
| | | GameWorld.Log(" 不是跨服日常活动开启星期: dailyID=%s,openWeekLimit=%s" % (dailyID, openTimeDict.keys()))
|
| | | continue
|
| | | openTimeList = openTimeDict["0"] if "0" in openTimeDict else openTimeDict[weekDay]
|
| | | dailyTimeInfoList.append([openTimeList, dailyIpyData])
|
| | | |
| | | GameWorld.Log(" -----------------------")
|
| | | for openTimeList, ipyData in dailyTimeInfoList:
|
| | | dailyID = ipyData.GetDailyID()
|
| | | notifyInfoDict = ipyData.GetNotifyInfo()
|
| | | |
| | | openList = [] # [(时,分), ...]
|
| | | overList = [] # [(时,分), ...]
|
| | | goonStateDict = {} # {״̬:[(aDateTime, bDateTime)], ...}
|
| | | notifyDict = {} # {(时,分):[notifyKey, [参数]], ...}
|
| | | OpenState = 1 # 定义开启状态为1
|
| | | |
| | | for hour, minute in openTimeList: |
| | | openTimeStr = "%s %02d:%02d:%02d" % (curDateStr, hour, minute, 0)
|
| | | |
| | | # 精确开启时间
|
| | | openDateTime = datetime.datetime.strptime(openTimeStr, ChConfig.TYPE_Time_Format)
|
| | | openList.append((openDateTime.hour, openDateTime.minute))
|
| | | |
| | | # 精确关闭时间
|
| | | overDateTime = openDateTime + datetime.timedelta(minutes=ipyData.GetDuration())
|
| | | overList.append((overDateTime.hour, overDateTime.minute))
|
| | | |
| | | # goon 开启状态
|
| | | openStateTimeList = goonStateDict.get(OpenState, [])
|
| | | openStateTimeList.append((openDateTime, overDateTime))
|
| | | goonStateDict[OpenState] = openStateTimeList
|
| | | |
| | | # goon 其他状态,待扩展
|
| | | # ...
|
| | | |
| | | # 广播
|
| | | for notifyMinute, notifyInfo in notifyInfoDict.items():
|
| | | notifyDateTime = openDateTime + datetime.timedelta(minutes=notifyMinute)
|
| | | notifyDict[(notifyDateTime.hour, notifyDateTime.minute)] = notifyInfo
|
| | | |
| | | todayActionInfo.append([dailyID, openList, overList, goonStateDict, notifyDict])
|
| | | GameWorld.Log(" 增加本日跨服日常活动信息: dailyID=%s,openList=%s,overList=%s,goonStateDict=%s,notifyDict=%s" |
| | | % (dailyID, openList, overList, goonStateDict, notifyDict))
|
| | | |
| | | TodayDailyActionInfo = IpyGameDataPY.SetConfigEx(key, [loadSign, todayActionInfo])
|
| | | GameWorld.Log("本日跨服日常活动信息加载完毕! loadSign=%s" % loadSign)
|
| | | GameWorld.Log("=============================================================")
|
| | | return TodayDailyActionInfo[1]
|
| | |
|
| | | def Dispose_CrossDailyActionState():
|
| | | # 跨服日常活动状态变更检查处理
|
| | | |
| | | todayDailyActionInfo = __GetTodayCrossDailyActionInfo()
|
| | | if not todayDailyActionInfo:
|
| | | return
|
| | | |
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | dayTime = GameWorld.GetServerTime()
|
| | | curHourMinute = (dayTime.hour, dayTime.minute)
|
| | | |
| | | sysnCrossDailyActionStateDict = {}
|
| | | |
| | | for actionInfo in todayDailyActionInfo:
|
| | | dailyActionID = actionInfo[0]
|
| | | state = 0 # 默认关闭
|
| | | |
| | | # 长度为1的代表常开的活动
|
| | | if len(actionInfo) == 1:
|
| | | state = 1
|
| | | else:
|
| | | #openList = [] # [(时,分), ...]
|
| | | #overList = [] # [(时,分), ...]
|
| | | #goonStateDict = {} # {״̬:[(aDateTime, bDateTime)], ...}
|
| | | #notifyDict = {} # {(时,分):[notifyKey, [参数]], ...}
|
| | | openList, overList, goonStateDict, notifyDict = actionInfo[1:]
|
| | | |
| | | # 精确匹配开启
|
| | | if curHourMinute in openList:
|
| | | state = 1
|
| | | # 精确匹配关闭
|
| | | elif curHourMinute in overList:
|
| | | state = 0
|
| | | # goon ״̬
|
| | | else:
|
| | | for goonState, openStateTimeList in goonStateDict.items():
|
| | | for dateTimeInfo in openStateTimeList:
|
| | | if dateTimeInfo[0] < dayTime < dateTimeInfo[1]:
|
| | | state = goonState
|
| | | break
|
| | | |
| | | # 全服广播提示信息
|
| | | if curHourMinute in notifyDict:
|
| | | notifyKey, paramList = notifyDict[curHourMinute]
|
| | | serverGroupIDList = []
|
| | | PlayerControl.WorldNotifyCross(serverGroupIDList, 0, notifyKey, paramList)
|
| | | |
| | | dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID
|
| | | beforeState = gameWorld.GetDictByKey(dictName)
|
| | | if beforeState == state:
|
| | | #已经是这个状态了
|
| | | continue
|
| | | |
| | | if state:
|
| | | if dailyActionID == ShareDefine.CrossDailyActionID_YaomoBoss:
|
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ActionBossRebornSign % dailyActionID, int(time.time()))
|
| | | |
| | | sysnCrossDailyActionStateDict[dailyActionID] = state
|
| | | #通知Mapserver,设置字典
|
| | | GameWorld.SendMapServerMsgEx(dictName, state)
|
| | | #更新字典值
|
| | | gameWorld.SetDict(dictName, state)
|
| | | GameWorld.Log("跨服日常活动状态变更: dailyActionID=%s,state=%s,dictName=%s" % (dailyActionID, state, dictName))
|
| | | |
| | | # 同步子服务器
|
| | | if sysnCrossDailyActionStateDict:
|
| | | serverGroupIDList = []
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossDailyActionState, sysnCrossDailyActionStateDict, serverGroupIDList)
|
| | | |
| | | return
|
| | |
|
| | | def SendMapServerCrossDailyActionState():
|
| | | # 地图启动成功时通知本日进行中的日常活动状态
|
| | | |
| | | todayDailyActionInfo = __GetTodayCrossDailyActionInfo()
|
| | | if not todayDailyActionInfo:
|
| | | return
|
| | | |
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | for actionInfo in todayDailyActionInfo:
|
| | | dailyActionID = actionInfo[0]
|
| | | dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID |
| | | state = gameWorld.GetDictByKey(dictName)
|
| | | if state:
|
| | | GameWorld.SendMapServerMsgEx(dictName, state)
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_CrossDailyActionState(msgData):
|
| | | |
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | for dailyActionID, state in msgData.items():
|
| | | dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID
|
| | | #通知Mapserver,设置字典
|
| | | GameWorld.SendMapServerMsgEx(dictName, state)
|
| | | #更新字典值
|
| | | gameWorld.SetDict(dictName, state)
|
| | | GameWorld.Log("收到跨服日常活动状态变更: dailyActionID=%s,state=%s,dictName=%s" % (dailyActionID, state, dictName))
|
| | | |
| | | return
|
| | |
|
| | |
| | | self.__billboardDict[key] = billboardObj
|
| | | return billboardObj
|
| | |
|
| | | def RemoveBillboard(self, billboardType):
|
| | | ## 移除某个类型的榜单所有数据
|
| | | for key in self.__billboardDict.keys():
|
| | | if key[0] == billboardType:
|
| | | self.__billboardDict.pop(key)
|
| | | return
|
| | | |
| | | # 保存数据 存数据库和realtimebackup
|
| | | def GetSaveData(self):
|
| | | savaData = ""
|
| | |
| | | for billboardType, groupValue1, groupValue2 in groupList:
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | billboardObj.SaveDRData()
|
| | | return
|
| | |
|
| | | def CopyBillboard(fromBillboardType, toBillboardType):
|
| | | ## 将某个类型的榜单完全拷贝到其他榜单 - 一般用于备份、转移数据
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardMgr.RemoveBillboard(toBillboardType) # 默认清空目标榜单
|
| | | |
| | | groupList = billboardMgr.GetBillboardGroupList(fromBillboardType)
|
| | | for billboardType, groupValue1, groupValue2 in groupList:
|
| | | frbillboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | toBillboardObj = billboardMgr.GetCrossBillboard(toBillboardType, groupValue1, groupValue2)
|
| | | GameWorld.Log("CopyCrossBillboard: billboardType=%s,toBillboardType=%s,groupValue1=%s,groupValue2=%s" |
| | | % (billboardType, toBillboardType, groupValue1, groupValue2))
|
| | | for frbillboardData in frbillboardObj.GetBillboardDataList():
|
| | | tobillboardData = PyGameDataStruct.tagDBCrossBillboard()
|
| | | tobillboardData.GroupValue1 = groupValue1
|
| | | tobillboardData.GroupValue2 = groupValue2
|
| | | tobillboardData.BillboardType = toBillboardType
|
| | | tobillboardData.ID = frbillboardData.ID
|
| | | tobillboardData.ID2 = frbillboardData.ID2
|
| | | tobillboardData.Name1 = frbillboardData.Name1
|
| | | tobillboardData.Name2 = frbillboardData.Name2
|
| | | tobillboardData.Type2 = frbillboardData.Type2
|
| | | tobillboardData.Value1 = frbillboardData.Value1
|
| | | tobillboardData.Value2 = frbillboardData.Value2
|
| | | tobillboardData.CmpValue = frbillboardData.CmpValue
|
| | | tobillboardData.CmpValue2 = frbillboardData.CmpValue2
|
| | | tobillboardData.CmpValue3 = frbillboardData.CmpValue3
|
| | | toBillboardObj.AddBillboardData(tobillboardData)
|
| | | |
| | | return
|
| | |
|
| | | #// C0 04 查看跨服排行榜 #tagCGViewCrossBillboard
|
| | |
| | | return
|
| | |
|
| | | def UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue,
|
| | | cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True):
|
| | | cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True, noSortAndSync=False):
|
| | | ''' 更新跨服排行榜
|
| | | @param billboardType: 排行榜索引类型,同个榜单类型可以有多个分组榜单数据,独立排序
|
| | | @param groupValue1: 榜单分组1
|
| | |
| | | @param groupValue1: 榜单分组2
|
| | | @param id2: 扩展数据ID2
|
| | | @param autoSort: 是否排序,默认True
|
| | | @param noSortAndSync: 不排序及同步子服,默认False; 一般用于批量更新数据时设置为True,减少排序及同步频率,但是一定要在设置完数据或最后一条数据后手动调用一次排序SortData
|
| | | @return: 是否上榜更新榜单
|
| | | '''
|
| | | if not GameWorld.IsCrossServer():
|
| | |
| | | % (billboardType, groupValue1, groupValue2, dataID, isNewData, cmpValueChange,
|
| | | type2, value1, value2, cmpValue, cmpValue2, cmpValue3), dataID)
|
| | |
|
| | | if noSortAndSync:
|
| | | return True
|
| | | if autoSort and cmpValueChange:
|
| | | billboardObj.SortData()
|
| | | else:
|
| | |
| | | def Sync_CrossBossInfo(curPlayer=None, syncBOSSIDList=[]):
|
| | | ## 同步boss相关信息
|
| | |
|
| | | curTime = int(time.time())
|
| | | curTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCrossServerTimeStr())
|
| | |
|
| | | recTypeListData = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossBossInfo)
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossYaomoBoss
|
| | | #
|
| | | # @todo:跨服妖魔boss
|
| | | # @author hxp
|
| | | # @date 2022-11-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服妖魔boss
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2022-11-11 15:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ShareDefine
|
| | | import PyDataManager
|
| | | import CrossRealmMsg
|
| | | import IpyGameDataPY
|
| | | import CrossBillboard
|
| | | import ChPyNetSendPack
|
| | | import PlayerCompensation
|
| | | import CrossRealmPlayer
|
| | | import PlayerViewCache
|
| | | import NetPackCommon
|
| | | import PlayerControl
|
| | | import PyGameData
|
| | | import GameWorld
|
| | |
|
| | | Def_RecType_CrossYaomoBossHurtInfo = ShareDefine.Def_UniversalGameRecType_CrossYaomoBossHurtInfo
|
| | | '''
|
| | | 跨服妖魔boss伤血信息
|
| | | ShareDefine.Def_UniversalGameRecType_CrossYaomoBossHurtInfo
|
| | | value1:zoneID 分区ID
|
| | | value2:playerID 玩家ID
|
| | | value3:awardState 目标伤害领奖记录
|
| | | StrValue1:hurtTotal 今日总伤害
|
| | | '''
|
| | | def GetRecZoneID(recData): return recData.GetValue1()
|
| | | def SetRecZoneID(recData, zoneID): return recData.SetValue1(zoneID)
|
| | | def GetRecPlayerID(recData): return recData.GetValue2()
|
| | | def SetRecPlayerID(recData, playerID): return recData.SetValue2(playerID)
|
| | | def GetRecAwardState(recData): return recData.GetValue3()
|
| | | def SetRecAwardState(recData, awardState): return recData.SetValue3(awardState)
|
| | | def GetRecHurtTotal(recData): return GameWorld.ToIntDef(recData.GetStrValue1(), 0)
|
| | | def SetRecHurtTotal(recData, hurtTotal): return recData.SetStrValue1(str(hurtTotal))
|
| | |
|
| | | def DoOnDay():
|
| | | |
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | hurtValueAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossYaomoBoss", 3, {})
|
| | | hurtValueIntAwardDict = {int(k):v for k, v in hurtValueAwardDict.items()}
|
| | | |
| | | universalRecMgr = GameWorld.GetUniversalRecMgr()
|
| | | recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossYaomoBossHurtInfo)
|
| | | for index in xrange(recDataList.Count()):
|
| | | recData = recDataList.At(index)
|
| | | playerID = GetRecPlayerID(recData)
|
| | | awardState = GetRecAwardState(recData)
|
| | | hurtTotal = GetRecHurtTotal(recData)
|
| | | |
| | | for awardIndex, hurtValueInfo in hurtValueIntAwardDict.items():
|
| | | needHurtValue, awardItemList = hurtValueInfo
|
| | | if hurtTotal < needHurtValue:
|
| | | continue
|
| | | if awardState & pow(2, awardIndex):
|
| | | continue
|
| | | paramList = [needHurtValue]
|
| | | PlayerCompensation.SendMailByKey("CrossYaomoBossHurtValue", [playerID], awardItemList, paramList, crossMail=True)
|
| | | |
| | | universalRecMgr.Delete(Def_RecType_CrossYaomoBossHurtInfo)
|
| | | |
| | | # 广播子服重置伤害
|
| | | serverGroupIDList = []
|
| | | sendMsg = {"HurtReset":1}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossYaomoBossHurtInfo, sendMsg, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def ClientServerMsg_CrossYaomoBossHurtAward(serverGroupID, msgData):
|
| | | |
| | | playerID = msgData["playerID"]
|
| | | awardIndex = msgData["awardIndex"]
|
| | | |
| | | hurtValueAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossYaomoBoss", 3, {})
|
| | | if str(awardIndex) not in hurtValueAwardDict:
|
| | | return
|
| | | needHurtValue, awardItemList = hurtValueAwardDict[str(awardIndex)]
|
| | | |
| | | universalRecMgr = GameWorld.GetUniversalRecMgr()
|
| | | recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossYaomoBossHurtInfo)
|
| | | for index in xrange(recDataList.Count()):
|
| | | recData = recDataList.At(index)
|
| | | if playerID != GetRecPlayerID(recData):
|
| | | continue
|
| | | |
| | | awardState = GetRecAwardState(recData)
|
| | | hurtTotal = GetRecHurtTotal(recData)
|
| | | if hurtTotal < needHurtValue:
|
| | | GameWorld.ErrLog("跨服妖魔boss伤害不足,无法领奖! awardIndex=%s,needHurtValue=%s > %s" % (awardIndex, needHurtValue, hurtTotal), playerID)
|
| | | return
|
| | | |
| | | if awardState & pow(2, awardIndex):
|
| | | GameWorld.ErrLog("已经领取过该跨服妖魔boss伤害奖励! awardIndex=%s,awardState=%s" % (awardIndex, awardState), playerID)
|
| | | return
|
| | | awardState |= pow(2, awardIndex)
|
| | | SetRecAwardState(recData, awardState)
|
| | | GameWorld.Log("领取跨服妖魔boss伤害奖励! awardIndex=%s,awardState=%s,awardItemList=%s" % (awardIndex, awardState, awardItemList), playerID)
|
| | | |
| | | serverGroupIDList = [serverGroupID]
|
| | | syncPlayerHurtInfo = {playerID:{"hurtTotal":hurtTotal, "awardState":awardState, "awardIndex":awardIndex, "awardItemList":awardItemList}}
|
| | | sendMsg = {"syncPlayerHurtInfo":syncPlayerHurtInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossYaomoBossHurtInfo, sendMsg, serverGroupIDList)
|
| | | return
|
| | | |
| | | return
|
| | |
|
| | | def Sync_CrossYaomoBossDataToClientServer(serverGroupID=0):
|
| | | ''' 同步跨服数据到子服务器
|
| | | @param serverGroupID: 为0时同步所有子服
|
| | | '''
|
| | | GameWorld.Log("同步给子服跨服妖魔Boss数据: syncServerGroupID=%s" % (serverGroupID))
|
| | | |
| | | syncPlayerHurtInfo = {}
|
| | | universalRecMgr = GameWorld.GetUniversalRecMgr()
|
| | | recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossYaomoBossHurtInfo)
|
| | | for index in xrange(recDataList.Count()):
|
| | | recData = recDataList.At(index)
|
| | | playerID = GetRecPlayerID(recData)
|
| | | awardState = GetRecAwardState(recData)
|
| | | hurtTotal = GetRecHurtTotal(recData)
|
| | | syncPlayerHurtInfo[playerID] = {"hurtTotal":hurtTotal, "awardState":awardState}
|
| | | |
| | | # 广播子服重置伤害
|
| | | if syncPlayerHurtInfo:
|
| | | serverGroupIDList = []
|
| | | sendMsg = {"syncPlayerHurtInfo":syncPlayerHurtInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossYaomoBossHurtInfo, sendMsg, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def MapServer_CrossYaomoBossHurtInfo(msgList):
|
| | | |
| | | zoneID, npcID, playerHurtList = msgList
|
| | | GameWorld.Log("地图跨服妖魔boss伤害结算信息: zoneID=%s,npcID=%s,hurtPlayerCount=%s" % (zoneID, npcID, len(playerHurtList)))
|
| | | |
| | | rankAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossYaomoBoss", 2, {})
|
| | | rankIntAwardDict = {int(k):v for k, v in rankAwardDict.items()}
|
| | | |
| | | universalRecMgr = GameWorld.GetUniversalRecMgr()
|
| | | recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossYaomoBossHurtInfo)
|
| | | hurtRecDict = {}
|
| | | for index in xrange(recDataList.Count()):
|
| | | recData = recDataList.At(index)
|
| | | hurtRecDict[(GetRecZoneID(recData), GetRecPlayerID(recData))] = recData
|
| | | |
| | | groupValue1 = zoneID
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_YaomoBossHurt, groupValue1)
|
| | | billboardObj.ClearData()
|
| | | |
| | | syncPlayerHurtInfo = {}
|
| | | for rank, hurtInfo in enumerate(playerHurtList, 1):
|
| | | playerID, hurtValue, hurtName = hurtInfo
|
| | | |
| | | job, realmLV, accID = 1, 1, ""
|
| | | curCache = PlayerViewCache.FindViewCache(playerID)
|
| | | if curCache:
|
| | | cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)
|
| | | job = cacheDict.get("Job", job)
|
| | | realmLV = cacheDict.get("RealmLV", realmLV)
|
| | | accID = cacheDict.get("AccID", accID)
|
| | | |
| | | # 更新最新一次伤害排名榜单
|
| | | dataID, name1, name2 = playerID, hurtName, ""
|
| | | type2, value1, value2 = job, realmLV, 0
|
| | | cmpValue = hurtValue / ShareDefine.Def_PerPointValue
|
| | | cmpValue2 = hurtValue % ShareDefine.Def_PerPointValue
|
| | | noSortAndSync = False if rank == len(playerHurtList) else True
|
| | | CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_YaomoBossHurt, groupValue1, dataID, name1, name2,
|
| | | type2, value1, value2, cmpValue, cmpValue2, noSortAndSync=noSortAndSync)
|
| | | |
| | | # 名次奖励直接发放
|
| | | awardItemList = GameWorld.GetOrderValueByDict(rankIntAwardDict, rank, False)
|
| | | if awardItemList:
|
| | | paramList = [rank]
|
| | | PlayerCompensation.SendMailByKey("CrossYaomoBossHurtRank", [playerID], awardItemList, paramList, crossMail=True)
|
| | | |
| | | key = (zoneID, playerID)
|
| | | if key not in hurtRecDict:
|
| | | recData = recDataList.AddRec()
|
| | | SetRecZoneID(recData, zoneID)
|
| | | SetRecPlayerID(recData, playerID)
|
| | | hurtTotal = hurtValue
|
| | | else:
|
| | | recData = hurtRecDict[key]
|
| | | hurtTotal = GetRecHurtTotal(recData) + hurtValue
|
| | | SetRecHurtTotal(recData, hurtTotal)
|
| | | syncPlayerHurtInfo[playerID] = {"hurtTotal":hurtTotal, "awardState":GetRecAwardState(recData)}
|
| | | GameWorld.Log(" rank=%s,playerID=%s,hurtValue=%s,hurtTotal=%s,accID=%s" % (rank, playerID, hurtValue, hurtTotal, accID))
|
| | | |
| | | # 通知子服更新玩家总伤害
|
| | | if syncPlayerHurtInfo:
|
| | | serverGroupIDList = []
|
| | | sendMsg = {"syncPlayerHurtInfo":syncPlayerHurtInfo}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossYaomoBossHurtInfo, sendMsg, serverGroupIDList)
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_CrossYaomoBossHurtInfo(msgData):
|
| | | |
| | | playerMgr = GameWorld.GetPlayerManager()
|
| | | |
| | | if "HurtReset" in msgData:
|
| | | # 重置伤害
|
| | | syncPlayerIDList = PyGameData.g_crossYaomoBossHurtInfo.keys()
|
| | | PyGameData.g_crossYaomoBossHurtInfo = {}
|
| | | for playerID in syncPlayerIDList:
|
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if not curPlayer or not curPlayer.GetInitOK():
|
| | | continue
|
| | | Sync_CrossYaomoBossPlayerHurtInfo(curPlayer)
|
| | | |
| | | return
|
| | | |
| | | #zoneID = msgData["zoneID"]
|
| | | #npcID = msgData["npcID"]
|
| | | syncPlayerHurtInfo = msgData["syncPlayerHurtInfo"]
|
| | | |
| | | for playerID, hurtInfo in syncPlayerHurtInfo.items():
|
| | | if not PlayerControl.GetDBPlayerAccIDByID(playerID):
|
| | | continue
|
| | | awardIndex = hurtInfo.pop("awardIndex", None)
|
| | | awardItemList = hurtInfo.pop("awardItemList", None)
|
| | | |
| | | PyGameData.g_crossYaomoBossHurtInfo[playerID] = hurtInfo
|
| | | |
| | | curPlayer = playerMgr.FindPlayerByID(playerID)
|
| | | if not curPlayer or not curPlayer.GetInitOK():
|
| | | continue
|
| | | Sync_CrossYaomoBossPlayerHurtInfo(curPlayer)
|
| | | |
| | | if awardIndex == None:
|
| | | continue
|
| | | |
| | | # 通知地图发放奖励
|
| | | msgInfo = ["HurtValueAward", [awardIndex, awardItemList]]
|
| | | CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossYaomoBoss", msgInfo)
|
| | | return
|
| | |
|
| | | def OnPlayerLogin(curPlayer):
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID not in PyGameData.g_crossYaomoBossHurtInfo:
|
| | | return
|
| | | |
| | | Sync_CrossYaomoBossPlayerHurtInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def Sync_CrossYaomoBossPlayerHurtInfo(curPlayer):
|
| | | hurtInfo = PyGameData.g_crossYaomoBossHurtInfo.get(curPlayer.GetPlayerID(), {})
|
| | | hurtTotal = hurtInfo.get("hurtTotal", 0)
|
| | | awardState = hurtInfo.get("awardState", 0)
|
| | | clientPack = ChPyNetSendPack.tagGCCrossYaomoBossPlayerHurtInfo()
|
| | | clientPack.HurtTotal = hurtTotal % ShareDefine.Def_PerPointValue
|
| | | clientPack.HurtTotalEx = hurtTotal / ShareDefine.Def_PerPointValue
|
| | | clientPack.AwardState = awardState
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | |
| | | def Dispose_DailyActionState():
|
| | | # 日常活动状态变更检查处理
|
| | |
|
| | | if GameWorld.IsCrossServer():
|
| | | CrossActionControl.Dispose_CrossDailyActionState()
|
| | | return
|
| | | |
| | | todayDailyActionInfo = __GetTodayDailyActionInfo()
|
| | | if not todayDailyActionInfo:
|
| | | return
|
| | |
| | | def SendMapServerDailyActionState():
|
| | | # 地图启动成功时通知本日进行中的日常活动状态
|
| | |
|
| | | if GameWorld.IsCrossServer():
|
| | | CrossActionControl.SendMapServerCrossDailyActionState()
|
| | | return
|
| | | |
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | for dailyActionID in ShareDefine.CrossDailyActionIDList:
|
| | | dictName = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % dailyActionID |
| | | state = gameWorld.GetDictByKey(dictName)
|
| | | if state:
|
| | | GameWorld.SendMapServerMsgEx(dictName, state)
|
| | | |
| | | todayDailyActionInfo = __GetTodayDailyActionInfo()
|
| | | if not todayDailyActionInfo:
|
| | | return
|
| | |
|
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | for actionInfo in todayDailyActionInfo:
|
| | | dailyActionID = actionInfo[0]
|
| | | dictName = ShareDefine.Def_Notify_WorldKey_DailyActionState % dailyActionID
|
| | |
| | | ("list", "RandMailKeyList", 0),
|
| | | ),
|
| | |
|
| | | "CrossDailyAction":(
|
| | | ("DWORD", "DailyID", 1),
|
| | | ("dict", "OpenTimeDict", 0),
|
| | | ("DWORD", "Duration", 0),
|
| | | ("dict", "NotifyInfo", 0),
|
| | | ),
|
| | |
|
| | | "DailyAction":(
|
| | | ("DWORD", "DailyID", 1),
|
| | | ("dict", "OpenTimeDict", 0),
|
| | |
| | | def GetItemCountWeightList(self): return self.ItemCountWeightList # 指定上架随机件数权重列表, [[权重, 件数], ...]
|
| | | def GetAuctionItemWeightList(self): return self.AuctionItemWeightList # 指定上架物品随机权重, [[权重, 物品ID],[权重, [阶,颜色,部位集合,是否套装,星级]] ...]
|
| | | def GetRandMailKeyList(self): return self.RandMailKeyList # 指定上架随机邮件列表,有配置时上架的时候在线玩家会收到一封上架邮件提醒 |
| | | |
| | | # 跨服日常活动表 |
| | | class IPY_CrossDailyAction(): |
| | | |
| | | def __init__(self): |
| | | self.DailyID = 0
|
| | | self.OpenTimeDict = {}
|
| | | self.Duration = 0
|
| | | self.NotifyInfo = {} |
| | | return |
| | | |
| | | def GetDailyID(self): return self.DailyID # 活动ID
|
| | | def GetOpenTimeDict(self): return self.OpenTimeDict # 开启时间
|
| | | def GetDuration(self): return self.Duration # 持续时间, 0为不限制
|
| | | def GetNotifyInfo(self): return self.NotifyInfo # 广播提示信息 |
| | | |
| | | # 日常活动表 |
| | | class IPY_DailyAction(): |
| | |
| | | self.ipyAuctionItemLen = len(self.ipyAuctionItemCache)
|
| | | self.ipyAuctionSystemItemCache = self.__LoadFileData("AuctionSystemItem", IPY_AuctionSystemItem)
|
| | | self.ipyAuctionSystemItemLen = len(self.ipyAuctionSystemItemCache)
|
| | | self.ipyCrossDailyActionCache = self.__LoadFileData("CrossDailyAction", IPY_CrossDailyAction)
|
| | | self.ipyCrossDailyActionLen = len(self.ipyCrossDailyActionCache)
|
| | | self.ipyDailyActionCache = self.__LoadFileData("DailyAction", IPY_DailyAction)
|
| | | self.ipyDailyActionLen = len(self.ipyDailyActionCache)
|
| | | self.ipyDailyActionCustomCache = self.__LoadFileData("DailyActionCustom", IPY_DailyActionCustom)
|
| | |
| | | def GetAuctionItemByIndex(self, index): return self.ipyAuctionItemCache[index]
|
| | | def GetAuctionSystemItemCount(self): return self.ipyAuctionSystemItemLen
|
| | | def GetAuctionSystemItemByIndex(self, index): return self.ipyAuctionSystemItemCache[index]
|
| | | def GetCrossDailyActionCount(self): return self.ipyCrossDailyActionLen
|
| | | def GetCrossDailyActionByIndex(self, index): return self.ipyCrossDailyActionCache[index]
|
| | | def GetDailyActionCount(self): return self.ipyDailyActionLen
|
| | | def GetDailyActionByIndex(self, index): return self.ipyDailyActionCache[index]
|
| | | def GetDailyActionCustomCount(self): return self.ipyDailyActionCustomLen
|
| | |
| | | import PlayerCharm
|
| | | import CrossBattlefield
|
| | | import CrossChampionship
|
| | | import CrossYaomoBoss
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | PlayerFamily.FamilyOnDay(tick)
|
| | | #跨服排位
|
| | | CrossChampionship.DoOnDay()
|
| | | #跨服妖魔boss
|
| | | CrossYaomoBoss.DoOnDay()
|
| | |
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | |
| | | import PyGameData
|
| | | import PlayerTalk
|
| | | import PlayerStore
|
| | | import CrossYaomoBoss
|
| | | import CrossRealmPlayer
|
| | | import CrossRealmMsg
|
| | | import CrossRealmPK
|
| | |
| | | CrossBattlefield.MapServer_CrossBattlefieldOver(eval(resultName))
|
| | | return
|
| | |
|
| | | # 跨服妖魔boss伤害结算
|
| | | if callName =="CrossYaomoBossHurtInfo":
|
| | | CrossYaomoBoss.MapServer_CrossYaomoBossHurtInfo(eval(resultName))
|
| | | return
|
| | | |
| | | # 跨服全民充值
|
| | | if callName == "CrossActAllRecharge":
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
|
| | |
| | | g_championshipMgr = None # 跨服排位争霸赛管理
|
| | |
|
| | | g_crossActAllRechargeInfo = {} # 跨服全民充值信息,本服用 {zoneID:{playerID:总充值, ...}, ...}
|
| | | g_crossYaomoBossHurtInfo = {} # 跨服妖魔boss伤害信息,本服用 {playerID:hurtTotal, ...}
|
| | |
|
| | | g_familyTalkCache = {} #{familyID:[[time,content,extras],..]}
|
| | | g_worldTalkCache = [] #[[time,name, playerID, content,extras],..]
|
| | |
| | | Def_CBT_BattlefieldWJoin, # 跨服战场每周参与榜 151
|
| | | Def_CBT_BattlefieldWCall, # 跨服战场每周召集榜 152
|
| | | Def_CBT_BattlefieldWScore, # 跨服战场每周积分榜 153
|
| | | ) = range(150, 153 + 1)
|
| | | Def_CBT_BattlefieldWScoreLastWeek, # 跨服战场上周积分榜 154
|
| | | Def_CBT_YaomoBossHurt, # 跨服妖魔boss最新一次伤血排名 155
|
| | | ) = range(150, 155 + 1)
|
| | |
|
| | | #职业对应战力排行榜类型
|
| | | JobFightPowerBillboardDict = {
|
| | |
| | | Def_UniversalGameRecType_CrossChampionshipOfficial, # 跨服排位争霸赛最终排名官职信息 35
|
| | | Def_UniversalGameRecType_CrossChampionshipOffChallenge, # 跨服排位争霸赛官职挑战信息 36
|
| | | Def_UniversalGameRecType_CrossActAllRecharge, # 跨服全服充值活动信息 37
|
| | | Def_UniversalGameRecType_38,
|
| | | Def_UniversalGameRecType_39,
|
| | | Def_UniversalGameRecType_CrossBattleChampionGroup, # 跨服战场冠军赛分组信息 38
|
| | | Def_UniversalGameRecType_CrossYaomoBossHurtInfo, # 跨服妖魔boss伤血信息 39
|
| | | Def_UniversalGameRecType_40,
|
| | | Def_UniversalGameRecType_RedPacketRecord, # 红包产出结果记录41
|
| | | Def_UniversalGameRecType_42,
|
| | |
| | | CrossServerMsg_ChampionshipOfficial = "ChampionshipOfficial" # 跨服排位争霸赛官职信息
|
| | | CrossServerMsg_ChampionshipDailyOfficial = "ChampionshipDailyOfficial" # 跨服排位争霸赛每日官职信息
|
| | | CrossServerMsg_ActAllRechargeInfo = "ActAllRechargeInfo"# 跨服全民充值信息
|
| | | CrossServerMsg_CrossDailyActionState = "CrossDailyActionState" # 跨服日常任务状态信息
|
| | | CrossServerMsg_CrossYaomoBossHurtInfo = "CrossYaomoBossHurtInfo" # 跨服妖魔boss玩家伤害信息
|
| | |
|
| | | # 子服发送跨服信息定义
|
| | | ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功
|
| | |
| | | ClientServerMsg_ChampionshipGuess = "ChampionshipGuess" # 跨服排位竞猜
|
| | | ClientServerMsg_ChampionshipWorship = "ChampionshipWorship" # 跨服排位膜拜
|
| | | ClientServerMsg_ActAllRechargeValue = "ActAllRechargeValue" # 跨服全民充值额度
|
| | | ClientServerMsg_CrossYaomoBossHurtAward = "CrossYaomoBossHurtAward" # 跨服妖魔boss玩家伤害领奖
|
| | |
|
| | | #跨服广播类型定义
|
| | | CrossNotify_CrossAct = "CrossAct"
|
| | |
| | | DailyActionID_CrossBattlefield, # 跨服战场 35
|
| | | ) = range(1, 35 + 1)
|
| | |
|
| | | # 跨服每日活动编号定义, 从150开始
|
| | | CrossDailyActionIDList = (
|
| | | CrossDailyActionID_YaomoBoss, # 妖魔boss 150
|
| | | ) = range(150, 150 + 1)
|
| | |
|
| | | # 成就类型定义
|
| | | SuccessTypeList = (
|
| | |
| | |
|
| | | if GetIsNewGuy(tagPlayer):
|
| | | return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_NotAttackNewGuy
|
| | | |
| | | |
| | | #和平光环
|
| | | if GetPeaceBuff(curPlayer) or GetPeaceBuff(tagPlayer):
|
| | | return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_None
|
| | | |
| | | #恶意攻击的玩家默认都是敌人, 无论什么模式
|
| | | if IsMaliciousAttackPlayer(curPlayer, tagPlayer):
|
| | | return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
|
| | |
| | | #敌人关系,可PK,可加减益buff
|
| | | return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
|
| | |
|
| | | def GetPeaceBuff(curPlayer):
|
| | | return SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_Peace)[0]
|
| | |
|
| | | ## 获取玩家和镖车的关系
|
| | | # @param curPlayer: 攻击方实例
|
| | | # @param curTagTruck: 镖车实例
|
| | |
| | | Def_AreaType_SkillID_FamilyPK = 20012 # 家族区
|
| | | Def_AreaType_SkillID_Boss = 20008 # Boss区域
|
| | | Def_SkillID_SitArea = 20009 # 打坐区域buff
|
| | |
|
| | | Def_SkillID_Peace = 23048 # 玩家间和平buff
|
| | | #----------------------------------------------------------------------
|
| | | #战斗类型
|
| | | Def_ChanceDefRate = 2000 # 抵御伤害概率, 目前固定20%概率
|
| | |
| | | 1000 * 10, # 跨服战场
|
| | | 1000 * 10, # 幸运云购
|
| | | 1000 * 10, # 跨服排位
|
| | | 1000 * 10, # 跨服妖魔boss
|
| | | ]
|
| | | TYPE_Player_Tick_Count = len(TYPE_Player_Tick_Time)
|
| | |
|
| | |
| | | TYPE_Player_Tick_Battlefield, #跨服战场
|
| | | TYPE_Player_Tick_LuckyCloudBuy, #幸运云购
|
| | | TYPE_Player_Tick_Championship, #跨服排位
|
| | | TYPE_Player_Tick_CrossYaomoBoss, #跨服妖魔boss
|
| | | ) = range(0, TYPE_Player_Tick_Count)
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | Def_RewardType_ShediaoRedpacket, #射雕红包奖励 50
|
| | | Def_RewardType_ShediaoEquip, #射雕装备奖励 51
|
| | | Def_RewardType_CAAllRecharge, #跨服全民充值奖励 52
|
| | | )= range(53)
|
| | | Def_RewardType_CrossYaomoBossHurt, #跨服妖魔boss伤害奖励 53
|
| | | )= range(54)
|
| | |
|
| | |
|
| | | #boss复活相关活动定义
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 11 跨服妖魔boss玩家伤害信息 #tagGCCrossYaomoBossPlayerHurtInfo
|
| | |
|
| | | class tagGCCrossYaomoBossPlayerHurtInfo(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("HurtTotal", c_int), # 总伤害值,小于亿部分
|
| | | ("HurtTotalEx", c_int), # 总伤害值,整除亿部分
|
| | | ("AwardState", c_int), # 伤害目标值领奖状态,按奖励记录索引位运算判断是否已领取
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xC0
|
| | | self.SubCmd = 0x11
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xC0
|
| | | self.SubCmd = 0x11
|
| | | self.HurtTotal = 0
|
| | | self.HurtTotalEx = 0
|
| | | self.AwardState = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagGCCrossYaomoBossPlayerHurtInfo)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C0 11 跨服妖魔boss玩家伤害信息 //tagGCCrossYaomoBossPlayerHurtInfo:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | HurtTotal:%d,
|
| | | HurtTotalEx:%d,
|
| | | AwardState:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.HurtTotal,
|
| | | self.HurtTotalEx,
|
| | | self.AwardState
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCCrossYaomoBossPlayerHurtInfo=tagGCCrossYaomoBossPlayerHurtInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossYaomoBossPlayerHurtInfo.Cmd,m_NAtagGCCrossYaomoBossPlayerHurtInfo.SubCmd))] = m_NAtagGCCrossYaomoBossPlayerHurtInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 14 幸运云购开奖记录 #tagGCLuckyCloudBuyLotteryRecInfo
|
| | |
|
| | | class tagGCLuckyCloudBuyLotteryRec(Structure):
|
| | |
| | | import FormulaControl
|
| | | import PlayerBossReborn
|
| | | import PlayerFairyCeremony
|
| | | import PlayerCrossYaomoBoss
|
| | | import PlayerActCollectWords
|
| | | import PlayerNewFairyCeremony
|
| | | import GameLogic_CrossGrassland
|
| | |
| | | FamilyRobBoss.ClearFamilyOwnerBossHurt(curNPC)
|
| | | ChNPC.OnNPCSetDead(curNPC)
|
| | |
|
| | | |
| | | if npcid == IpyGameDataPY.GetFuncCfg("CrossYaomoBoss", 1):
|
| | | PlayerCrossYaomoBoss.OnCrossYaomoBossDead(curNPC)
|
| | | |
| | | # 清除队伍成员伤血列表
|
| | | AttackCommon.ClearTeamPlayerHurtValue(curNPC)
|
| | | # 清除自定义伤血列表
|
| | |
| | | def NPCRefresh_218(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_219(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_220(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_221(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_222(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_223(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_224(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_225(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_226(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_227(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_228(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_229(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | | def NPCRefresh_230(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
|
| | |
|
| | | ## 世界boss刷怪
|
| | | # @param npcRefresh 刷新实例
|
| | |
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | realMapID = GameWorld.GetGameWorld().GetRealMapID()
|
| | | copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
|
| | | relatedType, relatedID = 0, ""
|
| | |
|
| | | if mapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
| | | bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID()
|
| | |
| | |
|
| | | stoneNPCID = bossIpyData.GetStoneNPCID()
|
| | | bossID = bossIpyData.GetNPCID()
|
| | |
|
| | | relatedType = bossIpyData.GetRelatedType()
|
| | | relatedID = bossIpyData.GetRelatedID()
|
| | | |
| | | if mapID not in ChConfig.Def_CrossZoneMapTableName:
|
| | | return
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[mapID]
|
| | |
| | | return
|
| | |
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID)
|
| | | rebornBossState = GameWorld.GetGameWorld().GetGameWorldDictByKey(bosskey)
|
| | | gameWorldMgr = GameWorld.GetGameWorld()
|
| | | forceReborn = False # 强制重生
|
| | | actBossRebornSign = 0
|
| | | mapActBossRebornSign = 0
|
| | | |
| | | # 关联日常活动
|
| | | if relatedType == 1:
|
| | | relatedID = int(relatedID)
|
| | | actionKey = ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % relatedID
|
| | | rebornBossState = 1 if gameWorldMgr.GetGameWorldDictByKey(actionKey) else 0
|
| | | |
| | | # 关联运营活动,待扩展
|
| | | elif relatedType == 2:
|
| | | pass
|
| | | |
| | | else:
|
| | | bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID)
|
| | | rebornBossState = GameWorld.GetGameWorld().GetGameWorldDictByKey(bosskey)
|
| | | |
| | | # 关联活动boss
|
| | | if relatedType:
|
| | | # 关联活动boss只要复活标记与上次不同,则强制重生
|
| | | actBossRebornSign = gameWorldMgr.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ActionBossRebornSign % relatedID)
|
| | | mapActBossRebornSign = gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_ActBossLastRebornSign % refreshMark)
|
| | | rebornBossState = rebornBossState and actBossRebornSign
|
| | | if rebornBossState and actBossRebornSign != mapActBossRebornSign:
|
| | | forceReborn = True
|
| | | |
| | | curNPC = None
|
| | | if npcRefresh.GetCount() > 0:
|
| | | curNPC = npcRefresh.GetAt(0)
|
| | |
| | | # 复活状态
|
| | | if rebornBossState:
|
| | | if curNPC:
|
| | | if curNPC.GetNPCID() == bossID:
|
| | | if not forceReborn and curNPC.GetNPCID() == bossID:
|
| | | return
|
| | | #去掉非bossNPC
|
| | | NPCCommon.SetDeadEx(curNPC)
|
| | |
|
| | | if mapActBossRebornSign and actBossRebornSign == mapActBossRebornSign:
|
| | | #GameWorld.DebugLog("活动线已经刷过不再刷活动boss: lineID=%s,refreshMark=%s,bossID=%s,actBossRebornSign=%s" |
| | | # % (lineID, refreshMark, bossID, actBossRebornSign))
|
| | | return
|
| | | |
| | | # 死亡状态
|
| | | else:
|
| | | if curNPC:
|
| | |
| | | __InitNewBornNPC(npcRefresh, tick)
|
| | | gameFB.SetGameFBDict(rebornTickKey, tick)
|
| | |
|
| | | if actBossRebornSign and rebornBossState:
|
| | | gameFB.SetGameFBDict(ChConfig.Map_NPC_ActBossLastRebornSign % refreshMark, actBossRebornSign)
|
| | | |
| | | GameWorld.DebugLog("CrossBossRefresh mapID=%s,realMapID=%s,copyMapID=%s,refreshMark=%s,rebornNPCID=%s,OK!"
|
| | | % (mapID, realMapID, copyMapID, refreshMark, rebornNPCID), lineID)
|
| | | return
|
| | |
| | | #GameWorld.DebugLog(" hurtID=%s,hurtType=%s,updValue=%s (%s + %s), playerID=%s,updHurtPlayerValue=%s"
|
| | | # % (hurtID, hurtType, updValue, befValue, addValue, playerID, updHurtPlayerValue), self.npcID, self.lineID)
|
| | | if isNewHurt:
|
| | | self.__Sort()
|
| | | self.Sort()
|
| | |
|
| | | return isNewHurt
|
| | |
|
| | |
| | | return 0
|
| | | return -1
|
| | |
|
| | | def __Sort(self):
|
| | | def Sort(self):
|
| | | ## 伤血排序
|
| | | self.__hurtSortList = sorted(self.__hurtDict.values(), cmp=self.__CmpHurtValue, reverse=True)
|
| | | return
|
| | |
| | | hurtValueObj.HurtValue = hurtValue % ShareDefine.Def_PerPointValue
|
| | | hurtValueObj.HurtValueEx = hurtValue / ShareDefine.Def_PerPointValue
|
| | | hurtValueList.append(hurtValueObj)
|
| | | if len(hurtValueList) > 250:
|
| | | break
|
| | |
|
| | | if not syncPlayerIDList:
|
| | | return
|
| | |
| | | self.checkHurtValidFunc()
|
| | |
|
| | | # 2. 排序
|
| | | self.__Sort()
|
| | | self.Sort()
|
| | |
|
| | | # 3. 同步前端
|
| | | self.__SyncHurtList()
|
| | |
| | | import PlayerFairyCeremony
|
| | | import PlayerNewFairyCeremony
|
| | | import GY_Query_BossFirstKill
|
| | | import PlayerCrossYaomoBoss
|
| | | import PlayerFeastRedPacket
|
| | | import PlayerLuckyCloudBuy
|
| | | import PlayerLuckyTreasure
|
| | |
| | | # 跨服全民充值奖励
|
| | | elif rewardType == ChConfig.Def_RewardType_CAAllRecharge:
|
| | | CrossActAllRecharge.GetCrossActAllRechargeAward(curPlayer, dataEx)
|
| | | # 跨服妖魔boss伤害奖励
|
| | | elif rewardType == ChConfig.Def_RewardType_CrossYaomoBossHurt:
|
| | | PlayerCrossYaomoBoss.GetCrossYaomoBossHurtAward(curPlayer, dataEx, tick)
|
| | | #缥缈奇遇领取
|
| | | elif rewardType == ChConfig.Def_RewardType_FairyAdventuresAward:
|
| | | PlayerFairyDomain.GetFairyAdventuresAward(curPlayer, dataEx, dataExStr)
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerCrossYaomoBoss
|
| | | #
|
| | | # @todo:跨服妖魔boss
|
| | | # @author hxp
|
| | | # @date 2022-11-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服妖魔boss
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2022-11-11 15:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import NPCHurtMgr
|
| | | import PlayerControl
|
| | | import IpyGameDataPY
|
| | | import ItemControler
|
| | | import IPY_GameWorld
|
| | | import ShareDefine
|
| | | import ItemCommon
|
| | | import ChConfig
|
| | |
|
| | | def OnYaomoBossStateChange(state, tick):
|
| | | ## 活动状态变更
|
| | | if state:
|
| | | # 开始的不需要处理
|
| | | return
|
| | | return
|
| | |
|
| | | def OnCrossYaomoBossDead(curNPC):
|
| | | |
| | | objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | mapID = GameWorld.GetGameWorld().GetMapID()
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | realMapID = GameWorld.GetGameWorld().GetRealMapID()
|
| | | copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
|
| | | |
| | | zoneID = 0
|
| | | zoneTypeName = ChConfig.Def_CrossZoneMapTableName.get(mapID)
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | if zoneTypeName and hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):
|
| | | for index in range(getattr(ipyDataMgr, "Get%sCount" % zoneTypeName)()):
|
| | | ipyData = getattr(ipyDataMgr, "Get%sByIndex" % zoneTypeName)(index)
|
| | | if realMapID == ipyData.GetMapID() and copyMapID == ipyData.GetCopyMapID():
|
| | | zoneID = ipyData.GetZoneID()
|
| | | break
|
| | | |
| | | npcHurtList = NPCHurtMgr.GetPlayerHurtList(curNPC)
|
| | | if not npcHurtList or not npcHurtList.GetHurtCount():
|
| | | GameWorld.ErrLog("跨服妖魔boss结算无伤害列表: mapID=%s,lineID=%s,realMapID=%s,copyMapID=%s,zoneID=%s,npcID=%s,objID=%s" |
| | | % (mapID, lineID, realMapID, copyMapID, zoneID, npcID, objID))
|
| | | return
|
| | | |
| | | GameWorld.Log("跨服妖魔boss伤害结算: mapID=%s,lineID=%s,realMapID=%s,copyMapID=%s,zoneID=%s,npcID=%s,objID=%s" |
| | | % (mapID, lineID, realMapID, copyMapID, zoneID, npcID, objID))
|
| | | npcHurtList.Sort() #sort以后伤血列表从大到小排序
|
| | | |
| | | rank = 0
|
| | | playerHurtList = []
|
| | | for index in xrange(npcHurtList.GetHurtCount()):
|
| | | #获得伤血对象
|
| | | hurtObj = npcHurtList.GetHurtAt(index)
|
| | | hurtType = hurtObj.GetValueType()
|
| | | hurtID = hurtObj.GetValueID()
|
| | | hurtValue = hurtObj.GetHurtValue()
|
| | | hurtName = hurtObj.GetHurtName()
|
| | | if hurtType != ChConfig.Def_NPCHurtTypePlayer or not hurtID:
|
| | | continue
|
| | | rank += 1
|
| | | playerID = hurtID
|
| | | GameWorld.Log(" zoneID=%s,rank=%s,playerID=%s,hurtValue=%s" % (zoneID, rank, playerID, hurtValue))
|
| | | playerHurtList.append([playerID, hurtValue, hurtName])
|
| | | |
| | | msgInfo = str([zoneID, npcID, playerHurtList])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossYaomoBossHurtInfo", msgInfo, len(msgInfo))
|
| | | return
|
| | |
|
| | | def GetCrossYaomoBossHurtAward(curPlayer, awardIndex, tick):
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem, True):
|
| | | return
|
| | | |
| | | if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_CrossYaomoBoss, tick):
|
| | | PlayerControl.NotifyCode(curPlayer, "RequestLater")
|
| | | return
|
| | | |
| | | # 发送跨服服务器
|
| | | dataMsg = {"playerID":playerID, "awardIndex":awardIndex}
|
| | | GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_CrossYaomoBossHurtAward, dataMsg)
|
| | | return
|
| | |
|
| | | def GameServer_CrossYaomoBoss_DoResult(curPlayer, msgData):
|
| | | msgType, dataMsg = msgData[:2]
|
| | | #ret = msgData[2] if len(msgData) > 2 else None
|
| | | |
| | | ## 伤害目标奖励 |
| | | if msgType == "HurtValueAward":
|
| | | __DoGiveCrossYaomoBossHurtAward(curPlayer, dataMsg)
|
| | | |
| | | return
|
| | |
|
| | | def __DoGiveCrossYaomoBossHurtAward(curPlayer, dataMsg):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | awardIndex, awardItemList = dataMsg
|
| | | GameWorld.Log("给玩家跨服妖魔boss伤害目标奖励: awardIndex=%s,awardItemList=%s" % (awardIndex, awardItemList), playerID)
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["CrossYaomoBoss", False, {}])
|
| | | return
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.RemoteQuery.GY_Query_CrossYaomoBoss
|
| | | #
|
| | | # @todo:跨服妖魔Boss
|
| | | # @author hxp
|
| | | # @date 2022-11-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服妖魔Boss
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2022-11-11 15:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ChConfig
|
| | | import GameWorld
|
| | | import PlayerCrossYaomoBoss
|
| | |
|
| | | #------------------------------------------------------------------------------ |
| | | ## 执行逻辑
|
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 请求的玩家ID
|
| | | # @param packCMDList 发包命令
|
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | # @remarks 函数详细说明.
|
| | | def DoLogic(query_Type, query_ID, packCMDList, tick):
|
| | | return
|
| | |
|
| | | #------------------------------------------------------------------------------ |
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_CrossYaomoBoss, 0)
|
| | | msgData = eval(funResult)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.Log("GY_Query_CrossYaomoBoss msgData=%s" % (msgData), playerID)
|
| | | PlayerCrossYaomoBoss.GameServer_CrossYaomoBoss_DoResult(curPlayer, msgData)
|
| | | return
|
| | |
|
| | |
| | | Def_CBT_BattlefieldWJoin, # 跨服战场每周参与榜 151
|
| | | Def_CBT_BattlefieldWCall, # 跨服战场每周召集榜 152
|
| | | Def_CBT_BattlefieldWScore, # 跨服战场每周积分榜 153
|
| | | ) = range(150, 153 + 1)
|
| | | Def_CBT_BattlefieldWScoreLastWeek, # 跨服战场上周积分榜 154
|
| | | Def_CBT_YaomoBossHurt, # 跨服妖魔boss最新一次伤血排名 155
|
| | | ) = range(150, 155 + 1)
|
| | |
|
| | | #职业对应战力排行榜类型
|
| | | JobFightPowerBillboardDict = {
|
| | |
| | | Def_UniversalGameRecType_CrossChampionshipOfficial, # 跨服排位争霸赛最终排名官职信息 35
|
| | | Def_UniversalGameRecType_CrossChampionshipOffChallenge, # 跨服排位争霸赛官职挑战信息 36
|
| | | Def_UniversalGameRecType_CrossActAllRecharge, # 跨服全服充值活动信息 37
|
| | | Def_UniversalGameRecType_38,
|
| | | Def_UniversalGameRecType_39,
|
| | | Def_UniversalGameRecType_CrossBattleChampionGroup, # 跨服战场冠军赛分组信息 38
|
| | | Def_UniversalGameRecType_CrossYaomoBossHurtInfo, # 跨服妖魔boss伤血信息 39
|
| | | Def_UniversalGameRecType_40,
|
| | | Def_UniversalGameRecType_RedPacketRecord, # 红包产出结果记录41
|
| | | Def_UniversalGameRecType_42,
|
| | |
| | | CrossServerMsg_ChampionshipOfficial = "ChampionshipOfficial" # 跨服排位争霸赛官职信息
|
| | | CrossServerMsg_ChampionshipDailyOfficial = "ChampionshipDailyOfficial" # 跨服排位争霸赛每日官职信息
|
| | | CrossServerMsg_ActAllRechargeInfo = "ActAllRechargeInfo"# 跨服全民充值信息
|
| | | CrossServerMsg_CrossDailyActionState = "CrossDailyActionState" # 跨服日常任务状态信息
|
| | | CrossServerMsg_CrossYaomoBossHurtInfo = "CrossYaomoBossHurtInfo" # 跨服妖魔boss玩家伤害信息
|
| | |
|
| | | # 子服发送跨服信息定义
|
| | | ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功
|
| | |
| | | ClientServerMsg_ChampionshipGuess = "ChampionshipGuess" # 跨服排位竞猜
|
| | | ClientServerMsg_ChampionshipWorship = "ChampionshipWorship" # 跨服排位膜拜
|
| | | ClientServerMsg_ActAllRechargeValue = "ActAllRechargeValue" # 跨服全民充值额度
|
| | | ClientServerMsg_CrossYaomoBossHurtAward = "CrossYaomoBossHurtAward" # 跨服妖魔boss玩家伤害领奖
|
| | |
|
| | | #跨服广播类型定义
|
| | | CrossNotify_CrossAct = "CrossAct"
|
| | |
| | | DailyActionID_CrossBattlefield, # 跨服战场 35
|
| | | ) = range(1, 35 + 1)
|
| | |
|
| | | # 跨服每日活动编号定义, 从150开始
|
| | | CrossDailyActionIDList = (
|
| | | CrossDailyActionID_YaomoBoss, # 妖魔boss 150
|
| | | ) = range(150, 150 + 1)
|
| | |
|
| | | # 成就类型定义
|
| | | SuccessTypeList = (
|
| | |
| | | return True
|
| | |
|
| | | buffSkill = curObjBuff.GetSkill()
|
| | | |
| | | if buffType == IPY_GameWorld.bfAura:
|
| | | if buffSkill.GetSkillLV() >= curSkillLV:
|
| | | #GameWorld.DebugLog("光环技能只添加更高级的效果!")
|
| | | return
|
| | | |
| | | #buff根据情况可以叠加低级,或者低级覆盖高级
|
| | | # buffSkillLV = buffSkill.GetSkillLV()
|
| | | #
|