From 9f13daf65e0f6acc43ffab6462b737a70879f5cc Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期三, 29 八月 2018 20:17:08 +0800 Subject: [PATCH] Add: 2961 【后端】仙盟抢Boss活动; --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py | 108 +++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 333 ++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py | 6 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py | 108 +++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py | 44 + ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py | 333 ++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 9 PySysDB/PySysDBPY.h | 3 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py | 5 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py | 4 ServerPython/CoreServerGroup/GameServer/PyNetPack.ini | 6 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 5 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py | 5 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FamilyRobBoss.py | 555 +++++++++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py | 73 ++ ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py | 44 + ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py | 65 + ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py | 10 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py | 12 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py | 10 ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py | 2 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini | 12 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py | 31 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 78 ++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py | 7 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 9 26 files changed, 1,824 insertions(+), 53 deletions(-) diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h index 968047e..9cdb9c2 100644 --- a/PySysDB/PySysDBPY.h +++ b/PySysDB/PySysDBPY.h @@ -848,6 +848,9 @@ DWORD _NPCID; //ID DWORD MapID; //地图ID BYTE RefreshMark; //刷新标识点 + BYTE IsNeedShunt; //是否需要分流 + BYTE RelatedType; //刷怪关联类型 + WORD RelatedID; //关联ID DWORD StoneNPCID; //墓碑NPCID }; diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini index fdc6620..6b0a4e7 100644 --- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini +++ b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini @@ -319,12 +319,16 @@ Writer = xdh Releaser = xdh RegType = 0 -RegisterPackCount = 1 +RegisterPackCount = 2 PacketCMD_1=0xA9 PacketSubCMD_1=0x03 PacketCallFunc_1=OnAttentionBoss +PacketCMD_2=0xAC +PacketSubCMD_2=0x04 +PacketCallFunc_2=OnQueryAllFamilyBossHurt + [PlayerXMZZ] ScriptName = Player\PlayerXMZZ.py Writer = xdh diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py index d3818c6..80a331a 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py @@ -1485,6 +1485,54 @@ #------------------------------------------------------ +# AC 04 查询仙盟抢Boss所有Boss当前进度 #tagCGQueryAllFamilyBossHurt + +class tagCGQueryAllFamilyBossHurt(Structure): + _pack_ = 1 + _fields_ = [ + ("Cmd", c_ubyte), + ("SubCmd", c_ubyte), + ] + + def __init__(self): + self.Clear() + self.Cmd = 0xAC + self.SubCmd = 0x04 + 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 = 0xAC + self.SubCmd = 0x04 + return + + def GetLength(self): + return sizeof(tagCGQueryAllFamilyBossHurt) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AC 04 查询仙盟抢Boss所有Boss当前进度 //tagCGQueryAllFamilyBossHurt: + Cmd:%s, + SubCmd:%s + '''\ + %( + self.Cmd, + self.SubCmd + ) + return DumpString + + +m_NAtagCGQueryAllFamilyBossHurt=tagCGQueryAllFamilyBossHurt() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryAllFamilyBossHurt.Cmd,m_NAtagCGQueryAllFamilyBossHurt.SubCmd))] = m_NAtagCGQueryAllFamilyBossHurt + + +#------------------------------------------------------ # AC 03 仙魔之争信息查询 #tagCGXMZZInfoQuery class tagCGXMZZInfoQuery(Structure): @@ -4012,6 +4060,66 @@ #------------------------------------------------------ +# A2 28 查询仙盟抢Boss伤血列表 #tagCMQueryFamilyBossHurt + +class tagCMQueryFamilyBossHurt(Structure): + _pack_ = 1 + _fields_ = [ + ("Cmd", c_ubyte), + ("SubCmd", c_ubyte), + ("ObjID", c_int), + ("NPCID", c_int), + ("QueryType", c_ubyte), # 0-实时仙盟伤血,1-历史仙盟伤血,2-实时玩家伤血,3-历史玩家伤血 + ] + + def __init__(self): + self.Clear() + self.Cmd = 0xA2 + self.SubCmd = 0x28 + 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 = 0xA2 + self.SubCmd = 0x28 + self.ObjID = 0 + self.NPCID = 0 + self.QueryType = 0 + return + + def GetLength(self): + return sizeof(tagCMQueryFamilyBossHurt) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// A2 28 查询仙盟抢Boss伤血列表 //tagCMQueryFamilyBossHurt: + Cmd:%s, + SubCmd:%s, + ObjID:%d, + NPCID:%d, + QueryType:%d + '''\ + %( + self.Cmd, + self.SubCmd, + self.ObjID, + self.NPCID, + self.QueryType + ) + return DumpString + + +m_NAtagCMQueryFamilyBossHurt=tagCMQueryFamilyBossHurt() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMQueryFamilyBossHurt.Cmd,m_NAtagCMQueryFamilyBossHurt.SubCmd))] = m_NAtagCMQueryFamilyBossHurt + + +#------------------------------------------------------ # A2 27 查询地图NPC数量信息 #tagCMQueryNPCCntInfo class tagCMQueryNPCCntInfo(Structure): diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py index 610934e..d989dba 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py @@ -4237,6 +4237,162 @@ #------------------------------------------------------ +# AC 10 仙盟抢Boss所有Boss伤血进度信息 #tagGCAllFamilyBossHurtInfoList + +class tagGCFamilyBossHurtInfo(Structure): + NPCID = 0 #(DWORD NPCID) + CurHP = 0 #(DWORD CurHP) + CurHPEx = 0 #(DWORD CurHPEx) + MaxHP = 0 #(DWORD MaxHP) + MaxHPEx = 0 #(DWORD MaxHPEx) + FamilyID = 0 #(DWORD FamilyID)// 最大实时伤血仙盟 + NameLen = 0 #(BYTE NameLen) + FamilyName = "" #(String FamilyName) + data = None + + def __init__(self): + self.Clear() + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + self.NPCID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.CurHP,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.CurHPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.MaxHP,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.MaxHPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.FamilyName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen) + return _pos + + def Clear(self): + self.NPCID = 0 + self.CurHP = 0 + self.CurHPEx = 0 + self.MaxHP = 0 + self.MaxHPEx = 0 + self.FamilyID = 0 + self.NameLen = 0 + self.FamilyName = "" + return + + def GetLength(self): + length = 0 + length += 4 + length += 4 + length += 4 + length += 4 + length += 4 + length += 4 + length += 1 + length += len(self.FamilyName) + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteDWORD(data, self.NPCID) + data = CommFunc.WriteDWORD(data, self.CurHP) + data = CommFunc.WriteDWORD(data, self.CurHPEx) + data = CommFunc.WriteDWORD(data, self.MaxHP) + data = CommFunc.WriteDWORD(data, self.MaxHPEx) + data = CommFunc.WriteDWORD(data, self.FamilyID) + data = CommFunc.WriteBYTE(data, self.NameLen) + data = CommFunc.WriteString(data, self.NameLen, self.FamilyName) + return data + + def OutputString(self): + DumpString = ''' + NPCID:%d, + CurHP:%d, + CurHPEx:%d, + MaxHP:%d, + MaxHPEx:%d, + FamilyID:%d, + NameLen:%d, + FamilyName:%s + '''\ + %( + self.NPCID, + self.CurHP, + self.CurHPEx, + self.MaxHP, + self.MaxHPEx, + self.FamilyID, + self.NameLen, + self.FamilyName + ) + return DumpString + + +class tagGCAllFamilyBossHurtInfoList(Structure): + Head = tagHead() + NPCCount = 0 #(BYTE NPCCount)// 个数 + NPCHurtInfo = list() #(vector<tagGCFamilyBossHurtInfo> NPCHurtInfo)// NPC伤血信息列表 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xAC + self.Head.SubCmd = 0x10 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.NPCCount,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.NPCCount): + temNPCHurtInfo = tagGCFamilyBossHurtInfo() + _pos = temNPCHurtInfo.ReadData(_lpData, _pos) + self.NPCHurtInfo.append(temNPCHurtInfo) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xAC + self.Head.SubCmd = 0x10 + self.NPCCount = 0 + self.NPCHurtInfo = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 1 + for i in range(self.NPCCount): + length += self.NPCHurtInfo[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteBYTE(data, self.NPCCount) + for i in range(self.NPCCount): + data = CommFunc.WriteString(data, self.NPCHurtInfo[i].GetLength(), self.NPCHurtInfo[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + NPCCount:%d, + NPCHurtInfo:%s + '''\ + %( + self.Head.OutputString(), + self.NPCCount, + "..." + ) + return DumpString + + +m_NAtagGCAllFamilyBossHurtInfoList=tagGCAllFamilyBossHurtInfoList() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCAllFamilyBossHurtInfoList.Head.Cmd,m_NAtagGCAllFamilyBossHurtInfoList.Head.SubCmd))] = m_NAtagGCAllFamilyBossHurtInfoList + + +#------------------------------------------------------ # AC 08 boss复活点数通知 #tagGCBossRebornPoint class tagGCBossRebornPoint(Structure): @@ -16349,6 +16505,183 @@ #------------------------------------------------------ +# A7 15 通知仙盟抢Boss伤血信息 #tagMCFamilyBossHurtList + +class tagMCFamilyBossHurt(Structure): + FamilyID = 0 #(DWORD FamilyID)// 所属仙盟ID + HurtID = 0 #(DWORD HurtID)// 伤血的ID, 根据伤血类型表示不同的ID, 如仙盟ID或玩家ID + NameLen = 0 #(BYTE NameLen) + HurtName = "" #(String HurtName) + HurtValue = 0 #(DWORD HurtValue)// 累计伤血,求余1亿的值 + HurtValueEx = 0 #(DWORD HurtValueEx)// 累计伤血,整除1亿的值 + InitTick = 0 #(DWORD InitTick)// 伤血初始tick,用于排序,先按伤血倒序排,再按tick正序排 + data = None + + def __init__(self): + self.Clear() + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.HurtID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.HurtName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen) + self.HurtValue,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.HurtValueEx,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.InitTick,_pos = CommFunc.ReadDWORD(_lpData, _pos) + return _pos + + def Clear(self): + self.FamilyID = 0 + self.HurtID = 0 + self.NameLen = 0 + self.HurtName = "" + self.HurtValue = 0 + self.HurtValueEx = 0 + self.InitTick = 0 + return + + def GetLength(self): + length = 0 + length += 4 + length += 4 + length += 1 + length += len(self.HurtName) + length += 4 + length += 4 + length += 4 + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteDWORD(data, self.FamilyID) + data = CommFunc.WriteDWORD(data, self.HurtID) + data = CommFunc.WriteBYTE(data, self.NameLen) + data = CommFunc.WriteString(data, self.NameLen, self.HurtName) + data = CommFunc.WriteDWORD(data, self.HurtValue) + data = CommFunc.WriteDWORD(data, self.HurtValueEx) + data = CommFunc.WriteDWORD(data, self.InitTick) + return data + + def OutputString(self): + DumpString = ''' + FamilyID:%d, + HurtID:%d, + NameLen:%d, + HurtName:%s, + HurtValue:%d, + HurtValueEx:%d, + InitTick:%d + '''\ + %( + self.FamilyID, + self.HurtID, + self.NameLen, + self.HurtName, + self.HurtValue, + self.HurtValueEx, + self.InitTick + ) + return DumpString + + +class tagMCFamilyBossHurtList(Structure): + Head = tagHead() + ObjID = 0 #(DWORD ObjID) + NPCID = 0 #(DWORD NPCID) + HurtType = 0 #(BYTE HurtType)// 0-实时仙盟伤血,1-历史仙盟伤血,2-实时玩家伤血,3-历史玩家伤血 + IsSort = 0 #(BYTE IsSort)// 是否排序过的,一般boss被击杀后会统一同步一次排序过的最终结果,其他情况下客户端自己排序 + HurtCount = 0 #(WORD HurtCount)// 伤血个数 + HurtList = list() #(vector<tagMCFamilyBossHurt> HurtList)// 伤血列表 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xA7 + self.Head.SubCmd = 0x15 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.ObjID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.NPCID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.HurtType,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.IsSort,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.HurtCount,_pos = CommFunc.ReadWORD(_lpData, _pos) + for i in range(self.HurtCount): + temHurtList = tagMCFamilyBossHurt() + _pos = temHurtList.ReadData(_lpData, _pos) + self.HurtList.append(temHurtList) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xA7 + self.Head.SubCmd = 0x15 + self.ObjID = 0 + self.NPCID = 0 + self.HurtType = 0 + self.IsSort = 0 + self.HurtCount = 0 + self.HurtList = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 4 + length += 4 + length += 1 + length += 1 + length += 2 + for i in range(self.HurtCount): + length += self.HurtList[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteDWORD(data, self.ObjID) + data = CommFunc.WriteDWORD(data, self.NPCID) + data = CommFunc.WriteBYTE(data, self.HurtType) + data = CommFunc.WriteBYTE(data, self.IsSort) + data = CommFunc.WriteWORD(data, self.HurtCount) + for i in range(self.HurtCount): + data = CommFunc.WriteString(data, self.HurtList[i].GetLength(), self.HurtList[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + ObjID:%d, + NPCID:%d, + HurtType:%d, + IsSort:%d, + HurtCount:%d, + HurtList:%s + '''\ + %( + self.Head.OutputString(), + self.ObjID, + self.NPCID, + self.HurtType, + self.IsSort, + self.HurtCount, + "..." + ) + return DumpString + + +m_NAtagMCFamilyBossHurtList=tagMCFamilyBossHurtList() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFamilyBossHurtList.Head.Cmd,m_NAtagMCFamilyBossHurtList.Head.SubCmd))] = m_NAtagMCFamilyBossHurtList + + +#------------------------------------------------------ # A7 03 通知进入副本时间 #tagMCFBEnterTickList class tagMCFBEnterTick(Structure): diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py index aea34b5..dd7e024 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldBoss.py @@ -176,6 +176,10 @@ __SetIsAlive(bossID, isAlive) # 全服广播世界boss变更信息 Sync_BossInfo(None, [bossID]) + + # 仙盟归属boss的重置 + if bossID in PyGameData.g_familyOwnerBossInfo: + PyGameData.g_familyOwnerBossInfo.pop(bossID) return @@ -1036,4 +1040,42 @@ if PlayerControl.GetIsTJG(curPlayer): return NetPackCommon.SendFakePack(curPlayer, packData) - return \ No newline at end of file + return + +def MapServer_FamilyOwnerBossInfo(msgInfo): + ## 地图同步仙盟归属boss信息 + + #GameWorld.DebugLog("地图同步仙盟归属boss信息: %s" % msgInfo) + if not isinstance(msgInfo, dict): + return + + PyGameData.g_familyOwnerBossInfo.update(msgInfo) + return + +#// AC 04 查询仙盟抢Boss所有Boss当前进度 #tagCGQueryAllFamilyBossHurt +# +#struct tagCGQueryAllFamilyBossHurt +#{ +# tagHead Head; +#}; +def OnQueryAllFamilyBossHurt(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + + hurtPack = ChPyNetSendPack.tagGCAllFamilyBossHurtInfoList() + hurtPack.NPCHurtInfo = [] + for npcID, hurtInfo in PyGameData.g_familyOwnerBossInfo.items(): + curHP, maxHP, firstFamilyID, firstFamilyName = hurtInfo + hurtInfo = ChPyNetSendPack.tagGCFamilyBossHurtInfo() + hurtInfo.NPCID = npcID + hurtInfo.CurHP = curHP%ShareDefine.Def_PerPointValue + hurtInfo.CurHPEx = curHP/ShareDefine.Def_PerPointValue + hurtInfo.MaxHP = maxHP%ShareDefine.Def_PerPointValue + hurtInfo.MaxHPEx = maxHP/ShareDefine.Def_PerPointValue + hurtInfo.FamilyID = firstFamilyID + hurtInfo.FamilyName = firstFamilyName + hurtInfo.NameLen = len(hurtInfo.FamilyName) + hurtPack.NPCHurtInfo.append(hurtInfo) + hurtPack.NPCCount = len(hurtPack.NPCHurtInfo) + NetPackCommon.SendFakePack(curPlayer, hurtPack) + return + diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py index c2db78e..fe9b667 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamily.py @@ -39,6 +39,7 @@ import PlayerFamilyParty import PlayerFamilySWRH import PlayerViewCache +import GameWorldBoss import PlayerTalk import copy @@ -1363,6 +1364,10 @@ PlayerControl.NotifyCode(curPlayer, "DungeonGuardSkyText2") return + if GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss): + PlayerControl.NotifyCode(curPlayer, "FairyGrabBossExitError") + return + tagPlayerName = curTagMember.GetName() # 被踢玩家名 tagPlayerID = curTagMember.GetPlayerID() # 被踢玩家ID tagFamilyLV = curTagMember.GetFamilyLV() # 被踢玩家职位 @@ -1437,6 +1442,11 @@ if PlayerFamilySWRH.IsInFamilySWRH(): PlayerControl.NotifyCode(curPlayer, "DungeonGuardSkyText1") return + + if GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_FamilyRobBoss): + PlayerControl.NotifyCode(curPlayer, "FairyGrabBossExitError") + return + #XW_JZ_LeaveFamily <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n> 25 - - NotifyAllFamilyMemberMsg(curFamily, curPlayer, "XW_JZ_LeaveFamily", [curPlayer.GetName()]) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py index d777f7e..bcf2381 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py @@ -621,6 +621,11 @@ GameWorldBoss.DoGameWorldBossOnReborn(eval(resultName), tick) return + # 仙盟归属boss信息同步 + if callName =="FamilyOwnerBossInfo": + GameWorldBoss.MapServer_FamilyOwnerBossInfo(eval(resultName)) + return + # 全局掉落CD if callName =="GlobalDropCD": GameWorldProcess.UpdGlobalDropCD(eval(resultName)) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py index 36b4bf3..f800d86 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py @@ -62,6 +62,8 @@ g_bossShuntDeadLine = {} # boss分流线路boss已死亡的线路 {bossID:[lineID, ...], ...} g_bossShuntDeadLineChangeBoss = [] # boss分流已死亡线路有变更的boss列表 +g_familyOwnerBossInfo = {} # 地图同步上来的仙盟归属boss信息 + g_todayPlayerLVDict = {} #今日玩家等级字典 {playerID:lv,..} g_yesterdayPlayerLVDict = {} #昨日玩家等级字典{playerID:lv,..} diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py index e538065..0e3b58b 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py @@ -1466,9 +1466,10 @@ DailyActionID_XXX12, # 废弃12 DailyActionID_Tower, # 符印塔 DailyActionID_MagicWeapon, # 法宝集魂 -DailyActionID_FBHelp, # 助战副本 +DailyActionID_FBHelp, # 助战副本 15 DailyActionID_BOSSHome, # BOSS之家 -) = range(1, 16 + 1) +DailyActionID_FamilyRobBoss, # 仙盟抢boss +) = range(1, 17 + 1) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini index 1cfb104..7a8b725 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini @@ -1245,6 +1245,18 @@ PacketSubCMD_1=0x03 PacketCallFunc_1=OnActiveAllEquipAttr +;仙盟抢boss +[FamilyRobBoss] +ScriptName = GameWorldLogic\FamilyRobBoss.py +Writer = hxp +Releaser = hxp +RegType = 0 +RegisterPackCount = 1 + +PacketCMD_1=0xA2 +PacketSubCMD_1=0x28 +PacketCallFunc_1=OnQueryFamilyBossHurt + ;神兽 [PlayerDogz] ScriptName = Player\PlayerDogz.py diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py index 22d3208..b07fa6b 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py @@ -41,7 +41,7 @@ import PlayerTruck #import PlayerPrestigeSys import PlayerFamily -import BossHurtMng +#import BossHurtMng import PassiveBuffEffMng import PlayerSuccess import GameFuncComm @@ -56,6 +56,7 @@ import PlayerState import ChPyNetSendPack import NetPackCommon +import FamilyRobBoss import FBCommon import datetime @@ -610,7 +611,7 @@ # @remarks 获得curPlayer是否是新手 def GetIsNewGuy(curPlayer): - if curPlayer.GetLV() < ReadChConfig.GetEvalChConfig("MinPKLV"): + if curPlayer.GetLV() < IpyGameDataPY.GetFuncCfg("PKConfig", 5): return True return False @@ -679,7 +680,8 @@ defNPCHurtList = curTagObj.GetPlayerHurtList() curObjType = curObj.GetGameObjType() if curObjType == IPY_GameWorld.gotPlayer: - BossHurtMng.BossAddPlayerInHurtList(curObj, curTagObj, hurtHP) + #BossHurtMng.BossAddPlayerInHurtList(curObj, curTagObj, hurtHP) + FamilyRobBoss.OnPlayerHurtFamilyOwnerBoss(curObj, curTagObj, hurtHP) if curTagObj.GetGameObjType() == IPY_GameWorld.gotNPC: FBLogic.DoFB_Player_HurtNPC(curObj, curTagObj, hurtHP) if GameObj.GetHP(curTagObj) == 0: @@ -748,6 +750,10 @@ if not CheckKillNPCByCnt(attacker, defender): return False + #仙盟归属NPC判断 + if not CheckCanAttackFamilyOwnerNPC(attacker, defender): + return False + # NPC打玩家,反过来判断 elif atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer: ##攻击次数判断 @@ -758,12 +764,19 @@ if not CheckKillNPCByCnt(defender, attacker, False): return False + #仙盟归属NPC判断 + if not CheckCanAttackFamilyOwnerNPC(defender, attacker, False): + return False # NPC打NPC elif atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotNPC: if PetControl.IsPet(attacker) or attacker.GetGameNPCObjType()== IPY_GameWorld.gnotSummon: #击杀次数判断 if not CheckKillNPCByCnt(attacker, defender, False): + return False + + #仙盟归属NPC判断 + if not CheckCanAttackFamilyOwnerNPC(attacker, defender, False): return False #攻击NPC等级限制 @@ -817,6 +830,34 @@ return False +def CheckCanAttackFamilyOwnerNPC(attacker, defender, isNotify=True): + ''' 判断可否攻击仙盟归属的NPC ''' + if defender.GetGameObjType() != IPY_GameWorld.gotNPC: + #GameWorld.DebugLog("只判断被攻击的是NPC的情况") + return True + + if NPCCommon.GetDropOwnerType(defender) != ChConfig.DropOwnerType_Family: + return True + + atkPlayer, npcObjType = GetAttackPlayer(attacker) + # 攻击者非玩家不限制 + if not atkPlayer: + #GameWorld.DebugLog("攻击者非玩家不限制") + return True + + atkLimitNotifyMark = "" + if GetIsNewGuy(atkPlayer): + atkLimitNotifyMark = "FairyGrabBossNotAtk" + elif not atkPlayer.GetFamilyID(): + atkLimitNotifyMark = "FairyGrabBossNoFairy" + + if atkLimitNotifyMark: + if npcObjType is None and isNotify: + PlayerControl.NotifyCode(atkPlayer, atkLimitNotifyMark) + return False + + return True + def CheckKillNPCByCnt(attacker, defender, isNotify=True): ''' 判断当日击杀该NPC次数是否已满 ''' if defender.GetGameObjType() != IPY_GameWorld.gotNPC: @@ -853,9 +894,9 @@ if hasKillCnt >= limitCnt + itemAddKillCnt: - if BossHurtMng.GetPlayerBossHurt(atkPlayer, defender): - GameWorld.DebugLog("攻击过该boss可继续攻击") - return True + #if BossHurtMng.GetPlayerBossHurt(atkPlayer, defender): + # GameWorld.DebugLog("攻击过该boss可继续攻击") + # return True #次数不足 # 实际攻击者类型None则需要提示玩家 if npcObjType is None: @@ -888,9 +929,9 @@ hasAttackCnt = atkPlayer.NomalDictGetProperty(ChConfig.Def_PDict_WorldBoss_HurtCnt, 0) if hasAttackCnt >= limitCnt: - if BossHurtMng.GetPlayerBossHurt(atkPlayer, defender): - GameWorld.DebugLog("攻击过该boss可继续攻击") - return True + #if BossHurtMng.GetPlayerBossHurt(atkPlayer, defender): + # GameWorld.DebugLog("攻击过该boss可继续攻击") + # return True #次数不足 # 实际攻击者类型None则需要提示玩家 if npcObjType is None: @@ -2210,6 +2251,12 @@ if tagPlayer.GetPlayerAction() == IPY_GameWorld.paSit: return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_SitNotPK + if GetIsNewGuy(curPlayer): + return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_NewGuy + + if GetIsNewGuy(tagPlayer): + return ChConfig.Type_Relation_None, ChConfig.Def_PASysMessage_NotAttackNewGuy + #攻守双方同一队伍,不可PK,可加增益buff #if curPlayerAreaType not in [ShareDefine.gatManor] and CanAlikeTeam(curPlayer, tagPlayer): # #副本队友特殊判断 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py index a6ae002..211280b 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py @@ -1028,13 +1028,13 @@ ) = range( 0, Def_PA_MaxReason ) #提示原因及对应的提示mark组成的字典 -Def_MessageDic = {Def_PASysMessage_NewGuy:"XW_RY_CancelWay01", #攻击新手 +Def_MessageDic = {Def_PASysMessage_NewGuy:"FairyGrabBossNewPlayer", #攻击新手 Def_PASysMessage_IsSafeArea: "CannotAtk01", #安全区域 Def_PASysMessage_AttackMode:"AtkModeErr", #攻击模式 Def_PASysMessage_CountrySafe:"PlayerPK_Error_GoalLvLow",#国家保护 Def_PASysMessage_IsSafeArea_Country:"Cadres_PK_Lost", #国家安全区保护 Def_PASysMessage_NewGuyNotPK:"PK_lhs_0", #新手不能PK - Def_PASysMessage_NotAttackNewGuy:"PK_lhs_31379", #不能攻击新手 + Def_PASysMessage_NotAttackNewGuy:"FairyGrabBossNewPlayer", #不能攻击新手 Def_PASysMessage_NotAttackFamily:"Old_andyshao_161795", #不能攻击同家族成员 Def_PASysMessage_NotAttackTeam:"PK_lhs_861048", #不能攻击队友 Def_PASysMessage_AttackNotPK:"PK_lhs_202580", #攻击方PK值过大,不能PK @@ -1913,6 +1913,7 @@ Map_Player_AreaReward_GetCnt = "AreaAward_GetCnt%s" # 玩家战场区域福利-累计获得次数 #---地图NPC--- +Map_NPC_ActivityBossRebornCount = 'ActivityBossRebornCount_%s' # 活动boss已刷新只数,参数(标识点) Map_NPC_WorldBossLastReBornTick = 'WorldBossLastReBornTick_%s' # 世界boss上次重生时间 Map_NPC_WorldBossDeadTick = 'WorldBossDeadTick_%s' # 世界boss死亡时间 Map_NPC_RandomMapNPCID = 'RandMapNPCID_%s' # 当前地图随机NPCID, 参数为标识点mark @@ -2035,6 +2036,7 @@ Def_NPCHurtTypeAll = 4 #所有玩家 Def_NPCHurtTypeFaction= 5 #阵营 Def_NPCHurtTypeSpecial= 6 #特殊, 指定某些玩家, 玩家ID取ShareDefine.Def_MapItemInfo_SpecOwner +Def_NPCHurtTypeFamily = 7 #仙盟 7 #掉落归属类型-NPC表的定义 DropOwnerType = ( @@ -2045,7 +2047,8 @@ DropOwnerType_MaxHurtPlayer, # 最大伤血玩家, 伤血不会被重置, 仅限玩家 4 DropOwnerType_Faction, # 阵营 5 DropOwnerType_Special, # 特殊 6 -) = range(7) +DropOwnerType_Family, # 仙盟 7 +) = range(8) #------------------------------------------------ #技能类型 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py index d3818c6..80a331a 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py @@ -1485,6 +1485,54 @@ #------------------------------------------------------ +# AC 04 查询仙盟抢Boss所有Boss当前进度 #tagCGQueryAllFamilyBossHurt + +class tagCGQueryAllFamilyBossHurt(Structure): + _pack_ = 1 + _fields_ = [ + ("Cmd", c_ubyte), + ("SubCmd", c_ubyte), + ] + + def __init__(self): + self.Clear() + self.Cmd = 0xAC + self.SubCmd = 0x04 + 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 = 0xAC + self.SubCmd = 0x04 + return + + def GetLength(self): + return sizeof(tagCGQueryAllFamilyBossHurt) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// AC 04 查询仙盟抢Boss所有Boss当前进度 //tagCGQueryAllFamilyBossHurt: + Cmd:%s, + SubCmd:%s + '''\ + %( + self.Cmd, + self.SubCmd + ) + return DumpString + + +m_NAtagCGQueryAllFamilyBossHurt=tagCGQueryAllFamilyBossHurt() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryAllFamilyBossHurt.Cmd,m_NAtagCGQueryAllFamilyBossHurt.SubCmd))] = m_NAtagCGQueryAllFamilyBossHurt + + +#------------------------------------------------------ # AC 03 仙魔之争信息查询 #tagCGXMZZInfoQuery class tagCGXMZZInfoQuery(Structure): @@ -4012,6 +4060,66 @@ #------------------------------------------------------ +# A2 28 查询仙盟抢Boss伤血列表 #tagCMQueryFamilyBossHurt + +class tagCMQueryFamilyBossHurt(Structure): + _pack_ = 1 + _fields_ = [ + ("Cmd", c_ubyte), + ("SubCmd", c_ubyte), + ("ObjID", c_int), + ("NPCID", c_int), + ("QueryType", c_ubyte), # 0-实时仙盟伤血,1-历史仙盟伤血,2-实时玩家伤血,3-历史玩家伤血 + ] + + def __init__(self): + self.Clear() + self.Cmd = 0xA2 + self.SubCmd = 0x28 + 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 = 0xA2 + self.SubCmd = 0x28 + self.ObjID = 0 + self.NPCID = 0 + self.QueryType = 0 + return + + def GetLength(self): + return sizeof(tagCMQueryFamilyBossHurt) + + def GetBuffer(self): + return string_at(addressof(self), self.GetLength()) + + def OutputString(self): + DumpString = '''// A2 28 查询仙盟抢Boss伤血列表 //tagCMQueryFamilyBossHurt: + Cmd:%s, + SubCmd:%s, + ObjID:%d, + NPCID:%d, + QueryType:%d + '''\ + %( + self.Cmd, + self.SubCmd, + self.ObjID, + self.NPCID, + self.QueryType + ) + return DumpString + + +m_NAtagCMQueryFamilyBossHurt=tagCMQueryFamilyBossHurt() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMQueryFamilyBossHurt.Cmd,m_NAtagCMQueryFamilyBossHurt.SubCmd))] = m_NAtagCMQueryFamilyBossHurt + + +#------------------------------------------------------ # A2 27 查询地图NPC数量信息 #tagCMQueryNPCCntInfo class tagCMQueryNPCCntInfo(Structure): diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py index 610934e..d989dba 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py @@ -4237,6 +4237,162 @@ #------------------------------------------------------ +# AC 10 仙盟抢Boss所有Boss伤血进度信息 #tagGCAllFamilyBossHurtInfoList + +class tagGCFamilyBossHurtInfo(Structure): + NPCID = 0 #(DWORD NPCID) + CurHP = 0 #(DWORD CurHP) + CurHPEx = 0 #(DWORD CurHPEx) + MaxHP = 0 #(DWORD MaxHP) + MaxHPEx = 0 #(DWORD MaxHPEx) + FamilyID = 0 #(DWORD FamilyID)// 最大实时伤血仙盟 + NameLen = 0 #(BYTE NameLen) + FamilyName = "" #(String FamilyName) + data = None + + def __init__(self): + self.Clear() + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + self.NPCID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.CurHP,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.CurHPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.MaxHP,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.MaxHPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.FamilyName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen) + return _pos + + def Clear(self): + self.NPCID = 0 + self.CurHP = 0 + self.CurHPEx = 0 + self.MaxHP = 0 + self.MaxHPEx = 0 + self.FamilyID = 0 + self.NameLen = 0 + self.FamilyName = "" + return + + def GetLength(self): + length = 0 + length += 4 + length += 4 + length += 4 + length += 4 + length += 4 + length += 4 + length += 1 + length += len(self.FamilyName) + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteDWORD(data, self.NPCID) + data = CommFunc.WriteDWORD(data, self.CurHP) + data = CommFunc.WriteDWORD(data, self.CurHPEx) + data = CommFunc.WriteDWORD(data, self.MaxHP) + data = CommFunc.WriteDWORD(data, self.MaxHPEx) + data = CommFunc.WriteDWORD(data, self.FamilyID) + data = CommFunc.WriteBYTE(data, self.NameLen) + data = CommFunc.WriteString(data, self.NameLen, self.FamilyName) + return data + + def OutputString(self): + DumpString = ''' + NPCID:%d, + CurHP:%d, + CurHPEx:%d, + MaxHP:%d, + MaxHPEx:%d, + FamilyID:%d, + NameLen:%d, + FamilyName:%s + '''\ + %( + self.NPCID, + self.CurHP, + self.CurHPEx, + self.MaxHP, + self.MaxHPEx, + self.FamilyID, + self.NameLen, + self.FamilyName + ) + return DumpString + + +class tagGCAllFamilyBossHurtInfoList(Structure): + Head = tagHead() + NPCCount = 0 #(BYTE NPCCount)// 个数 + NPCHurtInfo = list() #(vector<tagGCFamilyBossHurtInfo> NPCHurtInfo)// NPC伤血信息列表 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xAC + self.Head.SubCmd = 0x10 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.NPCCount,_pos = CommFunc.ReadBYTE(_lpData, _pos) + for i in range(self.NPCCount): + temNPCHurtInfo = tagGCFamilyBossHurtInfo() + _pos = temNPCHurtInfo.ReadData(_lpData, _pos) + self.NPCHurtInfo.append(temNPCHurtInfo) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xAC + self.Head.SubCmd = 0x10 + self.NPCCount = 0 + self.NPCHurtInfo = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 1 + for i in range(self.NPCCount): + length += self.NPCHurtInfo[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteBYTE(data, self.NPCCount) + for i in range(self.NPCCount): + data = CommFunc.WriteString(data, self.NPCHurtInfo[i].GetLength(), self.NPCHurtInfo[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + NPCCount:%d, + NPCHurtInfo:%s + '''\ + %( + self.Head.OutputString(), + self.NPCCount, + "..." + ) + return DumpString + + +m_NAtagGCAllFamilyBossHurtInfoList=tagGCAllFamilyBossHurtInfoList() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCAllFamilyBossHurtInfoList.Head.Cmd,m_NAtagGCAllFamilyBossHurtInfoList.Head.SubCmd))] = m_NAtagGCAllFamilyBossHurtInfoList + + +#------------------------------------------------------ # AC 08 boss复活点数通知 #tagGCBossRebornPoint class tagGCBossRebornPoint(Structure): @@ -16349,6 +16505,183 @@ #------------------------------------------------------ +# A7 15 通知仙盟抢Boss伤血信息 #tagMCFamilyBossHurtList + +class tagMCFamilyBossHurt(Structure): + FamilyID = 0 #(DWORD FamilyID)// 所属仙盟ID + HurtID = 0 #(DWORD HurtID)// 伤血的ID, 根据伤血类型表示不同的ID, 如仙盟ID或玩家ID + NameLen = 0 #(BYTE NameLen) + HurtName = "" #(String HurtName) + HurtValue = 0 #(DWORD HurtValue)// 累计伤血,求余1亿的值 + HurtValueEx = 0 #(DWORD HurtValueEx)// 累计伤血,整除1亿的值 + InitTick = 0 #(DWORD InitTick)// 伤血初始tick,用于排序,先按伤血倒序排,再按tick正序排 + data = None + + def __init__(self): + self.Clear() + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.HurtID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.HurtName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen) + self.HurtValue,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.HurtValueEx,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.InitTick,_pos = CommFunc.ReadDWORD(_lpData, _pos) + return _pos + + def Clear(self): + self.FamilyID = 0 + self.HurtID = 0 + self.NameLen = 0 + self.HurtName = "" + self.HurtValue = 0 + self.HurtValueEx = 0 + self.InitTick = 0 + return + + def GetLength(self): + length = 0 + length += 4 + length += 4 + length += 1 + length += len(self.HurtName) + length += 4 + length += 4 + length += 4 + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteDWORD(data, self.FamilyID) + data = CommFunc.WriteDWORD(data, self.HurtID) + data = CommFunc.WriteBYTE(data, self.NameLen) + data = CommFunc.WriteString(data, self.NameLen, self.HurtName) + data = CommFunc.WriteDWORD(data, self.HurtValue) + data = CommFunc.WriteDWORD(data, self.HurtValueEx) + data = CommFunc.WriteDWORD(data, self.InitTick) + return data + + def OutputString(self): + DumpString = ''' + FamilyID:%d, + HurtID:%d, + NameLen:%d, + HurtName:%s, + HurtValue:%d, + HurtValueEx:%d, + InitTick:%d + '''\ + %( + self.FamilyID, + self.HurtID, + self.NameLen, + self.HurtName, + self.HurtValue, + self.HurtValueEx, + self.InitTick + ) + return DumpString + + +class tagMCFamilyBossHurtList(Structure): + Head = tagHead() + ObjID = 0 #(DWORD ObjID) + NPCID = 0 #(DWORD NPCID) + HurtType = 0 #(BYTE HurtType)// 0-实时仙盟伤血,1-历史仙盟伤血,2-实时玩家伤血,3-历史玩家伤血 + IsSort = 0 #(BYTE IsSort)// 是否排序过的,一般boss被击杀后会统一同步一次排序过的最终结果,其他情况下客户端自己排序 + HurtCount = 0 #(WORD HurtCount)// 伤血个数 + HurtList = list() #(vector<tagMCFamilyBossHurt> HurtList)// 伤血列表 + data = None + + def __init__(self): + self.Clear() + self.Head.Cmd = 0xA7 + self.Head.SubCmd = 0x15 + return + + def ReadData(self, _lpData, _pos=0, _Len=0): + self.Clear() + _pos = self.Head.ReadData(_lpData, _pos) + self.ObjID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.NPCID,_pos = CommFunc.ReadDWORD(_lpData, _pos) + self.HurtType,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.IsSort,_pos = CommFunc.ReadBYTE(_lpData, _pos) + self.HurtCount,_pos = CommFunc.ReadWORD(_lpData, _pos) + for i in range(self.HurtCount): + temHurtList = tagMCFamilyBossHurt() + _pos = temHurtList.ReadData(_lpData, _pos) + self.HurtList.append(temHurtList) + return _pos + + def Clear(self): + self.Head = tagHead() + self.Head.Clear() + self.Head.Cmd = 0xA7 + self.Head.SubCmd = 0x15 + self.ObjID = 0 + self.NPCID = 0 + self.HurtType = 0 + self.IsSort = 0 + self.HurtCount = 0 + self.HurtList = list() + return + + def GetLength(self): + length = 0 + length += self.Head.GetLength() + length += 4 + length += 4 + length += 1 + length += 1 + length += 2 + for i in range(self.HurtCount): + length += self.HurtList[i].GetLength() + + return length + + def GetBuffer(self): + data = '' + data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer()) + data = CommFunc.WriteDWORD(data, self.ObjID) + data = CommFunc.WriteDWORD(data, self.NPCID) + data = CommFunc.WriteBYTE(data, self.HurtType) + data = CommFunc.WriteBYTE(data, self.IsSort) + data = CommFunc.WriteWORD(data, self.HurtCount) + for i in range(self.HurtCount): + data = CommFunc.WriteString(data, self.HurtList[i].GetLength(), self.HurtList[i].GetBuffer()) + return data + + def OutputString(self): + DumpString = ''' + Head:%s, + ObjID:%d, + NPCID:%d, + HurtType:%d, + IsSort:%d, + HurtCount:%d, + HurtList:%s + '''\ + %( + self.Head.OutputString(), + self.ObjID, + self.NPCID, + self.HurtType, + self.IsSort, + self.HurtCount, + "..." + ) + return DumpString + + +m_NAtagMCFamilyBossHurtList=tagMCFamilyBossHurtList() +ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFamilyBossHurtList.Head.Cmd,m_NAtagMCFamilyBossHurtList.Head.SubCmd))] = m_NAtagMCFamilyBossHurtList + + +#------------------------------------------------------ # A7 03 通知进入副本时间 #tagMCFBEnterTickList class tagMCFBEnterTick(Structure): diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py index 4be72f3..e9213c6 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Boss.py @@ -40,21 +40,22 @@ mapID = GameWorld.GetMap().GetMapID() dataList = IpyGameDataPY.GetIpyGameDataByCondition('BOSSInfo', {"MapID":mapID}, returnList=True) - if not dataList: - return - for ipyData in dataList: - bossID = ipyData.GetNPCID() - if not bossID: - continue - - key = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID - GameWorld.GetGameWorld().SetGameWorldDict(key, 1) - - bossKey = ChConfig.Map_NPC_WorldBossLastReBornTick % bossID - GameWorld.GetGameFB().SetGameFBDict(bossKey, 0) - - bossKey = ChConfig.Map_NPC_WorldBossLastReBornTick % ipyData.GetStoneNPCID() - GameWorld.GetGameFB().SetGameFBDict(bossKey, 0) + if dataList: + for ipyData in dataList: + bossID = ipyData.GetNPCID() + if not bossID: + continue + + key = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID + GameWorld.GetGameWorld().SetGameWorldDict(key, 1) + + bossKey = ChConfig.Map_NPC_WorldBossLastReBornTick % bossID + GameWorld.GetGameFB().SetGameFBDict(bossKey, 0) + + bossKey = ChConfig.Map_NPC_WorldBossLastReBornTick % ipyData.GetStoneNPCID() + GameWorld.GetGameFB().SetGameFBDict(bossKey, 0) + + GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_ActivityBossRebornCount % ipyData.GetRefreshMark(), 0) gameNPCManager = GameWorld.GetNPCManager() tick = GameWorld.GetGameWorld().GetTick() diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py index 1d9e8f3..3675312 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py @@ -88,11 +88,13 @@ return curHP = GameObj.GetHP(curNPC) - if curPlayer.GetTeamID() > 0: - AttackCommon.AddHurtValue(curNPC, curPlayer.GetTeamID(), ChConfig.Def_NPCHurtTypeTeam, curHP) - AttackCommon.AddTeamPlayerHurtValue(curNPC, curPlayer.GetTeamID(), curPlayer.GetPlayerID(), curHP) - else: - AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, curHP) + AttackCommon.NPCAddObjInHurtList(curPlayer, curNPC, curHP, curHP) + + #if curPlayer.GetTeamID() > 0: + # AttackCommon.AddHurtValue(curNPC, curPlayer.GetTeamID(), ChConfig.Def_NPCHurtTypeTeam, curHP) + # AttackCommon.AddTeamPlayerHurtValue(curNPC, curPlayer.GetTeamID(), curPlayer.GetPlayerID(), curHP) + #else: + # AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, curHP) #统一调用攻击结束动作 GameObj.SetHP(curNPC, 0) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py index ba34515..fb307e5 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py @@ -16,6 +16,8 @@ #------------------------------------------------------------------------------- import GameWorld import IPY_GameWorld +import FamilyRobBoss +import NPCCommon import ChConfig ##查看点选的NPC仇恨列表 @@ -36,7 +38,13 @@ GameWorld.DebugAnswer(curPlayer, "objID(%s) 错误 找不到对应NPC" % objID) return - GameWorld.DebugAnswer(curPlayer, "-------------------------------") + GameWorld.DebugAnswer(curPlayer, "---%s,ID=%s,team=%s,family=%s" + % (GameWorld.GetGameWorld().GetTick()%1000, curPlayer.GetPlayerID(), curPlayer.GetTeamID(), curPlayer.GetFamilyID())) + + # 归属仙盟的,取仙盟伤血统计 + if NPCCommon.GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: + FamilyRobBoss.OnGMPrintFamilyOwnerBossHurt(curPlayer, curNPC) + return npcHurtList = curNPC.GetPlayerHurtList() if isSort: diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FamilyRobBoss.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FamilyRobBoss.py new file mode 100644 index 0000000..63e03d9 --- /dev/null +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FamilyRobBoss.py @@ -0,0 +1,555 @@ +#!/usr/bin/python +# -*- coding: GBK -*- +#------------------------------------------------------------------------------- +# +##@package GameWorldLogic.FamilyRobBoss +# +# @todo:仙盟抢boss +# @author hxp +# @date 2018-08-29 +# @version 1.0 +# +# 详细描述: 仙盟抢boss +# +#------------------------------------------------------------------------------- +#"""Version = 2018-08-29 20:00""" +#------------------------------------------------------------------------------- + +import GameWorld +import ShareDefine +import IPY_GameWorld +import NetPackCommon +import ChPyNetSendPack +import PlayerControl +import IpyGameDataPY +import NPCCommon +import ChConfig +import GameObj + +FamilyHurtObjType_Family = 1 +FamilyHurtObjType_Player = 2 + +## 伤血对象类 +class FamilyHurtObj(): + + def __init__(self, familyID, objType, objID, name): + self.familyID = familyID + self.objType = objType + self.objID = objID + self.name = name + self.hurtValue = 0 + self.initTick = GameWorld.GetGameWorld().GetTick() + self.startProtectTick = 0 # 伤血开始保护tick, 默认0为不需要保护 + return + +## 伤血信息类 +class FamilyOwnerBossHurt(): + + def __init__(self): + # key = (lineID, objID, npcID) + + self.familyNowHurtSort = {} # 仙盟当前伤血,排完序的, 伤血类型是仙盟 {key:[FamilyHurtObj, ...], ...} + self.familyNowHurtDict = {} # 仙盟当前伤血,伤血可能清除 {key:{familyID:FamilyHurtObj, ...}, ...} + + self.familyHisHurtDict = {} # 仙盟历史伤血,伤血不会清除 {key:{familyID:FamilyHurtObj, ...}, ...} + self.playerHisHurtDict = {} # 玩家历史伤血,伤血不会清除 {key:{playerID:FamilyHurtObj, ...}, ...} + + self.familyPlayerIDDict = {} # 仙盟成员ID列表字典,{key:{familyID:[playerID, ...], ...}, ...} + + self.bossHPInfo = {} # boss当前血量信息,{key:[curHP, maxHP], ...},用于同步GameServer + + self.lastSortTick = 0 + GameWorld.DebugLog("FamilyBossHurtMgr __init__") + return + + def ClearNPCHurt(self, key): + self.familyNowHurtSort.pop(key, 0) + self.familyNowHurtDict.pop(key, 0) + self.familyHisHurtDict.pop(key, 0) + self.playerHisHurtDict.pop(key, 0) + self.familyPlayerIDDict.pop(key, 0) + self.bossHPInfo = {} + return + + def GetPlayerHisHurtDict(self): + return + +g_familyOwnerBossHurt = None +def GetFamilyHurtMgr(): + global g_familyOwnerBossHurt + if not g_familyOwnerBossHurt: + g_familyOwnerBossHurt = FamilyOwnerBossHurt() + return g_familyOwnerBossHurt + +def OnGMPrintFamilyOwnerBossHurt(curPlayer, curNPC): + ## GM显示仙盟归属boss伤血信息 + + lineID = GameWorld.GetGameWorld().GetLineID() + objID = curNPC.GetID() + bossID = curNPC.GetNPCID() + key = (lineID, objID, bossID) + + GameWorld.DebugAnswer(curPlayer, "NPCID(%s,%s), HP: %s/%s" % (objID, bossID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC))) + + hurtMgr = GetFamilyHurtMgr() + npcFamilyNowHurtDict = hurtMgr.familyNowHurtDict.get(key, {}) + npcFamilyHisHurtDict = hurtMgr.familyHisHurtDict.get(key, {}) + npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {}) + + npcNowHurtFamilyList = npcFamilyNowHurtDict.values() + npcNowHurtFamilyList.sort(cmp=CmpFamilyOwnerBossHurtSort) + + npcHisHurtFamilyList = npcFamilyHisHurtDict.values() + npcHisHurtFamilyList.sort(cmp=CmpFamilyOwnerBossHurtSort) + + npcHisHurtPlayerList = npcPlayerHisHurtDict.values() + npcHisHurtPlayerList.sort(cmp=CmpFamilyOwnerBossHurtSort) + + GameWorld.DebugAnswer(curPlayer, "实时伤血仙盟数: %s" % len(npcNowHurtFamilyList)) + for i, hurtObj in enumerate(npcNowHurtFamilyList, 1): + GameWorld.DebugAnswer(curPlayer, "%s,仙盟ID=%s,伤血=%s" % (i, hurtObj.objID, hurtObj.hurtValue)) + + GameWorld.DebugAnswer(curPlayer, "历史伤血仙盟数: %s" % (len(npcHisHurtFamilyList))) + for i, hurtObj in enumerate(npcHisHurtFamilyList, 1): + GameWorld.DebugAnswer(curPlayer, "%s,仙盟ID=%s,伤血=%s" % (i, hurtObj.objID, hurtObj.hurtValue)) + + GameWorld.DebugAnswer(curPlayer, "历史伤血玩家数: %s" % (len(npcHisHurtPlayerList))) + for i, hurtObj in enumerate(npcHisHurtPlayerList, 1): + GameWorld.DebugAnswer(curPlayer, "%s,玩家ID=%s,伤血=%s,仙盟ID=%s" % (i, hurtObj.objID, hurtObj.hurtValue, hurtObj.familyID)) + + return + +def OnPlayerHurtFamilyOwnerBoss(curPlayer, curBoss, hurtValue): + ## 仙盟玩家对仙盟归属boss造成伤害 + + GameWorld.DebugLog("OnPlayerHurtFamilyOwnerBoss hurtValue=%s" % hurtValue) + if hurtValue <= 0: + return + + if not curPlayer or not curBoss: + return + + curObjType = curPlayer.GetGameObjType() + if curObjType != IPY_GameWorld.gotPlayer: + return + + curBossType = curBoss.GetGameObjType() + if curBossType != IPY_GameWorld.gotNPC: + return + + if NPCCommon.GetDropOwnerType(curBoss) != ChConfig.DropOwnerType_Family: + return + + lineID = GameWorld.GetGameWorld().GetLineID() + objID = curBoss.GetID() + bossID = curBoss.GetNPCID() + + playerID = curPlayer.GetPlayerID() + familyID = curPlayer.GetFamilyID() + GameWorld.DebugLog("仙盟抢Boss增加伤血: lineID=%s,objID=%s,bossID=%s,familyID=%s,hurtValue=%s" + % (lineID, objID, bossID, familyID, hurtValue), playerID) + + key = (lineID, objID, bossID) + hurtMgr = GetFamilyHurtMgr() + + AddPlayerHurtFamilyOwnerBoss(curPlayer, curBoss, hurtMgr, key, hurtValue) + return + +def AddPlayerHurtFamilyOwnerBoss(curPlayer, curBoss, hurtMgr, key, hurtValue): + ## 添加仙盟成员伤血 + + if hurtValue < 0: + return + + playerID = curPlayer.GetPlayerID() + familyID = curPlayer.GetFamilyID() + playerName = curPlayer.GetPlayerName() + familyName = curPlayer.GetFamilyName() + + addHurtDict = {"FamilyNowHurt":[hurtMgr.familyNowHurtDict, FamilyHurtObjType_Family], + "FamilyHisHurt":[hurtMgr.familyHisHurtDict, FamilyHurtObjType_Family], + "PlayerHisHurt":[hurtMgr.playerHisHurtDict, FamilyHurtObjType_Player], + } + + for mark, hurtInfo in addHurtDict.items(): + hurtDict, hurtType = hurtInfo + if key not in hurtDict: + hurtDict[key] = {} + objHurtDict = hurtDict[key] + hurtID = familyID if hurtType == FamilyHurtObjType_Family else playerID + if hurtID not in objHurtDict: + hurtName = familyName if hurtType == FamilyHurtObjType_Family else playerName + objHurtDict[hurtID] = FamilyHurtObj(familyID, hurtType, hurtID, hurtName) + hurtObj = objHurtDict[hurtID] + hurtObj.hurtValue += hurtValue + GameWorld.DebugLog(" 更新伤血%s: hurtType=%s,hurtID=%s,hurtValue=%s" + % (mark, hurtType, hurtID, hurtObj.hurtValue), playerID) + + # 加入关联的仙盟成员ID列表 + npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {}) + npcFamilyPlayerIDList = npcFamilyPlayerIDDict.get(familyID, []) + if playerID not in npcFamilyPlayerIDList: + npcFamilyPlayerIDList.append(playerID) + npcFamilyPlayerIDDict[familyID] = npcFamilyPlayerIDList + hurtMgr.familyPlayerIDDict[key] = npcFamilyPlayerIDDict + + # 更新boss当前血量信息 + npcHP = GameObj.GetHP(curBoss) + npcMaxHP = GameObj.GetMaxHP(curBoss) + hurtMgr.bossHPInfo[key] = [npcHP, npcMaxHP] + + # 血量百分比广播 + npcHPPerNotifyList = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBoss", 4) + hpPerLogicMark = curBoss.GetDictByKey(ChConfig.Def_NPC_Dict_HPPerLogicMark) + logicHPPerList = npcHPPerNotifyList[hpPerLogicMark:] + if logicHPPerList: + npcHPPer = int(npcHP * 100.0 / npcMaxHP) + notifyPer, notifyKey = logicHPPerList[0] + if npcHPPer <= notifyPer: + curBoss.SetDict(ChConfig.Def_NPC_Dict_HPPerLogicMark, hpPerLogicMark + 1) + PlayerControl.WorldNotify(0, notifyKey, [curBoss.GetNPCID()]) + + return + +def FamilyOwnerBossOnReborn(curBoss): + ## 仙盟归属boss重生 + lineID = GameWorld.GetGameWorld().GetLineID() + objID = curBoss.GetID() + bossID = curBoss.GetNPCID() + key = (lineID, objID, bossID) + + hurtMgr = GetFamilyHurtMgr() + hurtMgr.ClearNPCHurt(key) + hurtMgr.bossHPInfo[key] = [GameObj.GetHP(curBoss), GameObj.GetMaxHP(curBoss)] + return + +def FamilyOwnerBossOnKilled(curBoss, ownerFamilyID): + '''仙盟归属boss被击杀 + 归属ID由外层归属算好传入,不由伤血决定,防止归属逻辑修改时改到逻辑 + 因为有伤血保护,如果伤血第一不算归属的话,逻辑就需要修改 + ''' + + lineID = GameWorld.GetGameWorld().GetLineID() + objID = curBoss.GetID() + bossID = curBoss.GetNPCID() + key = (lineID, objID, bossID) + maxHP = GameObj.GetMaxHP(curBoss) + + GameWorld.Log("FamilyOwnerBossOnKilled lineID=%s,objID=%s,bossID=%s,maxHP=%s,ownerFamilyID=%s" + % (lineID, objID, bossID, maxHP, ownerFamilyID)) + + hurtMgr = GetFamilyHurtMgr() + + npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {}) + npcFamilyHisHurtDict = hurtMgr.familyHisHurtDict.get(key, {}) + npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {}) + + if ownerFamilyID in npcFamilyHisHurtDict: + ownerFamilyHisHurt = npcFamilyHisHurtDict[ownerFamilyID] + PlayerControl.WorldNotify(0, "FairyGrabBossDead", [ownerFamilyHisHurt.name, bossID]) + + # 击杀结算前强制排序历史玩家伤血 + npcHisHurtPlayerList = npcPlayerHisHurtDict.values() + npcHisHurtPlayerList.sort(cmp=CmpFamilyOwnerBossHurtSort) + + # 归属仙盟前x名玩家额外奖励,算历史伤血 + batchPlayerIDList, batchAddItemList, batchParamList = [], [], [] + ownerFamilyPlayerOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBoss", 1, {}) + curNPCPlayerOrderAwardDict = ownerFamilyPlayerOrderAwardDict.get(bossID, {}) + maxOrder = max(curNPCPlayerOrderAwardDict) if curNPCPlayerOrderAwardDict else 0 + curOrder = 0 + #orderPlayerNameList = [] + for hurtPlayer in npcHisHurtPlayerList: + # 只算归属仙盟的 + if hurtPlayer.familyID != ownerFamilyID: + continue + curOrder += 1 + awardItemList = GameWorld.GetDictValueByRangeKey(curNPCPlayerOrderAwardDict, curOrder, []) + batchPlayerIDList.append([hurtPlayer.objID]) + batchAddItemList.append(awardItemList) + batchParamList.append([bossID, curOrder]) + #orderPlayerNameList.append(hurtPlayer.name) + GameWorld.Log(" 归属仙盟第%s名额外奖励: %s" % (curOrder, awardItemList)) + if curOrder >= maxOrder: + break + if batchPlayerIDList: + PlayerControl.SendMailBatch("FairyGrabBoss2", batchPlayerIDList, batchAddItemList, batchParamList) + #PlayerControl.WorldNotify(0, "FairyGrabBossRank", orderPlayerNameList + [bossID]) + + # 参与仙盟历史伤血奖励, 算历史伤血 + joinAwardNeedHurtHPPer = IpyGameDataPY.GetFuncCfg("FairyGrabBoss", 2) + joinFamilyAwardDict = IpyGameDataPY.GetFuncEvalCfg("FairyGrabBoss", 3, {}) + curNPCJoinFamilyAwardList = joinFamilyAwardDict.get(bossID, []) + joinAwardPlayerIDList = [] + GameWorld.Log(" 参与奖需求伤血比例: %s%%, 参与奖励:%s" % (joinAwardNeedHurtHPPer, curNPCJoinFamilyAwardList)) + for familyID, hurtFamily in npcFamilyHisHurtDict.items(): + familyHisHurt = hurtFamily.hurtValue + hurtPer = int(familyHisHurt * 100.0 / maxHP) + familyPlayerIDList = npcFamilyPlayerIDDict.get(familyID, []) + GameWorld.Log(" 仙盟ID=%s, 历史伤血=%s, 伤血比例: %s%%, 参与玩家ID=%s" % (familyID, familyHisHurt, hurtPer, familyPlayerIDList)) + if hurtPer < joinAwardNeedHurtHPPer: + continue + joinAwardPlayerIDList += familyPlayerIDList + if joinAwardPlayerIDList: + PlayerControl.SendMailByKey("FairyGrabBoss1", joinAwardPlayerIDList, curNPCJoinFamilyAwardList, [bossID, joinAwardNeedHurtHPPer]) + + # 同步最终结果给所有参与过的玩家 + hurtPack = __GetFamilyOwnerBossHurtPack(hurtMgr, key, objID, bossID, 0) + copyPlayerMng = GameWorld.GetMapCopyPlayerManager() + npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {}) + for playerIDList in npcFamilyPlayerIDDict.values(): + for playerID in playerIDList: + curPlayer = copyPlayerMng.FindPlayerByID(playerID) + if curPlayer: + NetPackCommon.SendFakePack(curPlayer, hurtPack) + + # 伤血在NPCCommon统一清 + return + +def RefreshFamilyOwnerNPCHurt(npcControl, curNPC, tick, refreshInterval): + ## 仙盟归属boss刷新伤血列表 + + lineID = GameWorld.GetGameWorld().GetLineID() + objID = curNPC.GetID() + bossID = curNPC.GetNPCID() + key = (lineID, objID, bossID) + + hurtMgr = GetFamilyHurtMgr() + refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) + + # refreshInterval 0时立即刷新 + if tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < refreshInterval: + return GetFamilyOwnerAtkObj(npcControl, refreshPoint, hurtMgr, key) + curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick) + + npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {}) # 玩家历史伤血,伤血不会清除 {key:{playerID:FamilyHurtObj, ...}, ...} + + # 1. 把NPC视野中没有造成伤害的玩家初始化伤血 + seePlayerCount = curNPC.GetInSightObjCount() + for i in xrange(seePlayerCount): + seeObj = curNPC.GetInSightObjByIndex(i) + if seeObj == None : + continue + + if not seeObj.GetVisible(): + continue + + seeObjType = seeObj.GetGameObjType() + if seeObjType != IPY_GameWorld.gotPlayer: + continue + seePlayer = GameWorld.GetObj(seeObj.GetID(), seeObjType) + + if seePlayer.GetPlayerID() not in npcPlayerHisHurtDict: + GameWorld.DebugLog("仙盟归属Boss看到玩家,加入伤血!lineID=%s, objID=%s, bossID=%s,playerID=%s" + % (lineID, objID, bossID, seePlayer.GetPlayerID())) + AddPlayerHurtFamilyOwnerBoss(seePlayer, curNPC, hurtMgr, key, 0) + + npcFamilyNowHurtDict = hurtMgr.familyNowHurtDict.get(key, {}) # 仙盟当前伤血,伤血可能清除 {key:{familyID:FamilyHurtObj, ...}, ...} + npcPlayerHisHurtDict = hurtMgr.playerHisHurtDict.get(key, {}) # 玩家历史伤血,伤血不会清除 {key:{playerID:FamilyHurtObj, ...}, ...} + + npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict.get(key, {}) # 仙盟成员ID列表字典,{key:{familyID:[playerID, ...], ...}, ...} + + clearHurtFamilyIDList = [] # 要清除伤血的仙盟ID列表 + + for familyID in npcFamilyNowHurtDict.keys(): + + if familyID not in npcFamilyPlayerIDDict: + continue + + isInProtect = False + + familyPlayerIDList = npcFamilyPlayerIDDict[familyID] + for playerID in familyPlayerIDList: + + if playerID not in npcPlayerHisHurtDict: + continue + + playerHurtObj = npcPlayerHisHurtDict[playerID] + hurtPlayer = GameWorld.GetObj(playerID, IPY_GameWorld.gotPlayer) + + # 玩家在该boss范围内 + if hurtPlayer and npcControl.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint): + isInProtect = True + playerHurtObj.startProtectTick = 0 # 重置保护tick + #GameWorld.DebugLog("有成员在boss范围内,保护中!familyID=%s,playerID=%s" % (familyID, playerID)) + break + + startProtectTick = playerHurtObj.startProtectTick + # 此boss与世界boss保护逻辑不一样,该boss只要是不在范围内的均视为开始保护 + if not startProtectTick: + #说明: 这里为了减少循环次数,有满足保护条件的就直接break了,所以理论上最大保护延迟为所有成员都不满足条件后才激活保护tick判断 + playerHurtObj.startProtectTick = tick # 激活开始保护tick + #GameWorld.DebugLog("激活成员开始保护tick!familyID=%s,playerID=%s,startProtectTick=%s" % (familyID, playerID, tick)) + isInProtect = True + break + + elif tick - startProtectTick < IpyGameDataPY.GetFuncCfg("BossHurtValue", 1) * 1000: + isInProtect = True + #GameWorld.DebugLog("有成员在保护时间内,保护中!familyID=%s,playerID=%s,startProtectTick=%s,%s" + # % (familyID, playerID, startProtectTick, tick - startProtectTick)) + break + + if not isInProtect: + clearHurtFamilyIDList.append(familyID) + + for clearHurtFamilyID in clearHurtFamilyIDList: + npcFamilyNowHurtDict.pop(clearHurtFamilyID, 0) + npcFamilyPlayerIDDict.pop(clearHurtFamilyID, 0) + GameWorld.Log("清除仙盟伤血: lineID=%s,objID=%s,bossID=%s" % (lineID, objID, bossID)) + + # 排序 + npcNowHurtFamilyList = npcFamilyNowHurtDict.values() + npcNowHurtFamilyList.sort(cmp=CmpFamilyOwnerBossHurtSort) + hurtMgr.familyNowHurtSort[key] = npcNowHurtFamilyList # 注意伤血第一名不一定是归属, 因为有伤血保护 + + return GetFamilyOwnerAtkObj(npcControl, refreshPoint, hurtMgr, key) + +def CmpFamilyOwnerBossHurtSort(hurtObj1, hurtObj2): + + # 伤血倒序 + ret = cmp(hurtObj2.hurtValue, hurtObj1.hurtValue) + if ret != 0: + return ret + + # 创建时间正序 + ret = cmp(hurtObj1.initTick, hurtObj2.initTick) + if ret != 0: + return ret + + return 0 + +def GetFamilyOwnerAtkObj(npcControl, refreshPoint, hurtMgr, key): + '''获取仙盟归属boss攻击目标, 攻击在boss范围内的归属仙盟成员,至于打谁,随便 + ''' + + if key not in hurtMgr.familyNowHurtSort or key not in hurtMgr.familyPlayerIDDict: + return + + npcFamilyNowHurtSortList = hurtMgr.familyNowHurtSort[key] + npcFamilyPlayerIDDict = hurtMgr.familyPlayerIDDict[key] + ownerFamilyID = 0 + + for i, hurtFamily in enumerate(npcFamilyNowHurtSortList): + familyID = hurtFamily.familyID + if i == 0: + ownerFamilyID = familyID # 策划伤血第一就是归属仙盟ID + + if familyID not in npcFamilyPlayerIDDict: + continue + familyPlayerIDList = npcFamilyPlayerIDDict[familyID] + for playerID in familyPlayerIDList: + hurtPlayer = GameWorld.GetObj(playerID, IPY_GameWorld.gotPlayer) + if hurtPlayer and npcControl.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint): + return hurtPlayer, ownerFamilyID + return + +def OnFamilyOwnerBossProcess(tick): + ''' 仙盟归属boss伤血定时处理,同步GameServer + ''' + + hurtMgr = GetFamilyHurtMgr() + # 没有boss血量信息,不需要处理排序 + if not hurtMgr.bossHPInfo: + return + + if not hurtMgr.lastSortTick: + hurtMgr.lastSortTick = tick + return + + # 10秒同步一次, 排序间隔由NPCAI决定 + if tick - hurtMgr.lastSortTick < 10000: + return + hurtMgr.lastSortTick = tick + + syncMsg = {} + for key, bossHPInfo in hurtMgr.bossHPInfo.items(): + lineID, objID, bossID = key + curHP, maxHP = bossHPInfo + + firstFamilyID = 0 + firstFamilyName = "" + + nowHurtList = hurtMgr.familyNowHurtSort.get(key, []) + if nowHurtList: + firstFamilyHurtObj = nowHurtList[0] + firstFamilyID = firstFamilyHurtObj.familyID + firstFamilyName = firstFamilyHurtObj.name + + syncMsg[bossID] = [curHP, maxHP, firstFamilyID, firstFamilyName] + + #GameWorld.DebugLog("同步GameServer仙盟归属boss汇总信息: %s" % syncMsg, GameWorld.GetGameWorld().GetLineID()) + syncMsg = str(syncMsg) + GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "FamilyOwnerBossInfo", syncMsg, len(syncMsg)) + return + +def ClearFamilyOwnerBossHurt(curBoss): + ## 清除对应objID伤血 + + lineID = GameWorld.GetGameWorld().GetLineID() + objID = curBoss.GetID() + bossID = curBoss.GetNPCID() + + key = (lineID, objID, bossID) + hurtMgr = GetFamilyHurtMgr() + hurtMgr.ClearNPCHurt(key) + + GameWorld.DebugLog("ClearFamilyOwnerBossHurt lineID=%s, objID=%s, bossID=%s" % (lineID, objID, bossID)) + return + +#// A2 28 查询仙盟抢Boss伤血列表 #tagCMQueryFamilyBossHurt +# +#struct tagCMQueryFamilyBossHurt +#{ +# tagHead Head; +# DWORD ObjID; +# DWORD NPCID; +# BYTE QueryType; // 0-实时仙盟伤血,1-历史仙盟伤血,2-实时玩家伤血,3-历史玩家伤血 +#}; +def OnQueryFamilyBossHurt(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + + lineID = GameWorld.GetGameWorld().GetLineID() + objID = clientData.ObjID + npcID = clientData.NPCID + queryType = clientData.QueryType + + key = (lineID, objID, npcID) + hurtMgr = GetFamilyHurtMgr() + + hurtPack = __GetFamilyOwnerBossHurtPack(hurtMgr, key, objID, npcID, queryType) + if hurtPack: + NetPackCommon.SendFakePack(curPlayer, hurtPack) + return + +def __GetFamilyOwnerBossHurtPack(hurtMgr, key, objID, npcID, queryType=0): + ## @param queryType: 0-实时仙盟伤血,1-历史仙盟伤血,2-实时玩家伤血,3-历史玩家伤血 + isSort = 0 + if queryType == 0: + hurtObjList = hurtMgr.familyNowHurtSort.get(key, []) + isSort = 1 + else: + # 赶时间,暂不支持 + return + + hurtPack = ChPyNetSendPack.tagMCFamilyBossHurtList() + hurtPack.Clear() + hurtPack.ObjID = objID + hurtPack.NPCID = npcID + hurtPack.HurtType = queryType + hurtPack.IsSort = isSort + hurtPack.HurtList = [] + for hurtObj in hurtObjList: + hurtInfo = ChPyNetSendPack.tagMCFamilyBossHurt() + hurtInfo.FamilyID = hurtObj.familyID + hurtInfo.HurtID = hurtObj.objID + hurtInfo.HurtName = hurtObj.name + hurtInfo.NameLen = len(hurtInfo.HurtName) + hurtInfo.InitTick = hurtObj.initTick + hurtInfo.HurtValue = hurtObj.hurtValue%ShareDefine.Def_PerPointValue + hurtInfo.HurtValueEx = hurtObj.hurtValue/ShareDefine.Def_PerPointValue + hurtPack.HurtList.append(hurtInfo) + hurtPack.HurtCount = len(hurtPack.HurtList) + return hurtPack + + + diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py index e3ddad5..ae3e662 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py @@ -39,6 +39,7 @@ import GameWorld import ChConfig import PlayerControl +import FamilyRobBoss import EventShell import FBLogic import FBCommon @@ -501,6 +502,9 @@ __RefreshOnFiveMinute(tick) #定时检测关闭超时文件 EventReport.OnTimeCloseScribeTxt() + + #仙盟归属boss定时处理 + FamilyRobBoss.OnFamilyOwnerBossProcess(tick) return ## 通知RouteServer 消息 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py index e2e3052..a3e0660 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py @@ -697,6 +697,9 @@ ("DWORD", "NPCID", 1), ("DWORD", "MapID", 0), ("BYTE", "RefreshMark", 0), + ("BYTE", "IsNeedShunt", 0), + ("BYTE", "RelatedType", 0), + ("WORD", "RelatedID", 0), ("DWORD", "StoneNPCID", 0), ), @@ -2348,12 +2351,18 @@ self.NPCID = 0 self.MapID = 0 self.RefreshMark = 0 + self.IsNeedShunt = 0 + self.RelatedType = 0 + self.RelatedID = 0 self.StoneNPCID = 0 return def GetNPCID(self): return self.NPCID # ID def GetMapID(self): return self.MapID # 地图ID def GetRefreshMark(self): return self.RefreshMark # 刷新标识点 + def GetIsNeedShunt(self): return self.IsNeedShunt # 是否需要分流 + def GetRelatedType(self): return self.RelatedType # 刷怪关联类型 + def GetRelatedID(self): return self.RelatedID # 关联ID def GetStoneNPCID(self): return self.StoneNPCID # 墓碑NPCID # 古神禁地表 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py index 7e9c809..a17cfa3 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py @@ -1225,6 +1225,12 @@ if curPlayer.GetPlayerID() not in ownerIDList: #GameWorld.Log("该物品不属于你,不能拾取6! ownerIDList=%s" % ownerIDList, curPlayer.GetPlayerID()) return False + #仙盟归属 + elif itemOwnerType == ChConfig.Def_NPCHurtTypeFamily: + if mapItem.GetOwnerID() != curPlayer.GetFamilyID(): + #GameWorld.Log("该物品不属于你仙盟的,不能拾取7! ownerFamilyID=%s,curFamilyID=%s" + # % (mapItem.GetOwnerID(), curPlayer.GetFamilyID()), curPlayer.GetPlayerID()) + return False return True diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py index a460007..271e488 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py @@ -31,6 +31,7 @@ import NPCCommon import AICommon import IPY_GameWorld +import FamilyRobBoss import AttackCommon import GameWorld import BaseAttack @@ -110,6 +111,12 @@ elif ownerType == ChConfig.Def_NPCHurtTypePlayer: tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) + elif dropOwnerType == ChConfig.DropOwnerType_Family: + ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(npcControl, curNPC, tick, refreshInterval) + if ownerInfo: + tagObj, ownerFamilyID = ownerInfo + ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID + # 没有攻击目标,则刷新仇恨,支持主动怪 if not tagObj: angryObjType, maxAngryObj = None, None @@ -122,7 +129,7 @@ maxAngryObj = GameWorld.GetObj(angryID, angryObjType) tagObj = maxAngryObj - if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj: + if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType: teamID = maxAngryObj.GetTeamID() if teamID: ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, teamID @@ -149,7 +156,7 @@ def __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType=0, ownerID=0, isDead=False): npcID = curNPC.GetNPCID() dropOwnerType = NPCCommon.GetDropOwnerType(curNPC) - if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry]: + if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family]: #GameWorld.DebugLog("不需要展示掉落归属的NPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType)) return @@ -202,12 +209,35 @@ if isOk: GameWorld.DebugLog("删除归属队员buff: teamID=%s,playerID=%s" % (ownerID, curTeamPlayer.GetPlayerID())) + elif ownerType == ChConfig.Def_NPCHurtTypeFamily: + + hurtType, hurtID = ChConfig.Def_NPCHurtTypeFamily, ownerID + refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) + copyPlayerMgr = GameWorld.GetMapCopyPlayerManager() + for index in xrange(copyPlayerMgr.GetPlayerCount()): + player = copyPlayerMgr.GetPlayerByIndex(index) + if not player: + continue + + # 归属仙盟 且 在boss区域内 + if player.GetFamilyID() == ownerID and npcControl.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint): + __AddBossDropOwnerPlayerBuff(player, tick, curNPC) + + else: + isOk = BuffSkill.DelBuffBySkillID(player, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC) + if isOk: + GameWorld.DebugLog("删除非归属仙盟成员buff: teamID=%s,playerID=%s" % (ownerID, player.GetPlayerID())) + if isDead: key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID) teamID = curTeam.GetTeamID() if curTeam else 0 if killerDict: PyGameData.g_npcKillerInfo[key] = killerDict, curTeam, hurtType, hurtID - GameWorld.Log("Boss被击杀: npcID=%s,key=%s,playerIDList=%s,teamID=%s" % (npcID, key, killerDict.keys(), teamID)) + elif ownerType == ChConfig.Def_NPCHurtTypeFamily: + PyGameData.g_npcKillerInfo[key] = {}, None, hurtType, hurtID + + GameWorld.Log("Boss被击杀: npcID=%s,key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s" + % (npcID, key, killerDict.keys(), teamID, hurtType, hurtID)) return def __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC): @@ -259,6 +289,14 @@ if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0: continue __SetBossDropOwnerBuffDisappearTime(curTeamPlayer, curNPC) + elif ownerType == ChConfig.Def_NPCHurtTypeFamily: + copyPlayerMgr = GameWorld.GetMapCopyPlayerManager() + for index in xrange(copyPlayerMgr.GetPlayerCount()): + player = copyPlayerMgr.GetPlayerByIndex(index) + if not player: + continue + __SetBossDropOwnerBuffDisappearTime(player, curNPC) + return def __SetBossDropOwnerBuffDisappearTime(curPlayer, curNPC): diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py index 7224177..4ce8874 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -52,6 +52,7 @@ import PlayerMagicWeapon import PlayerBossReborn import PlayerFairyCeremony +import FamilyRobBoss import IpyGameDataPY import PyGameData import PlayerTeam @@ -1946,11 +1947,14 @@ #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典 GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick()) + if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: + FamilyRobBoss.ClearFamilyOwnerBossHurt(curNPC) + # 清除队伍成员伤血列表 AttackCommon.ClearTeamPlayerHurtValue(curNPC) # 清除自定义伤血列表 - BossHurtMng.ClearHurtValueList(curNPC) + #BossHurtMng.ClearHurtValueList(curNPC) # C++设置npc死亡 curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason), @@ -1984,6 +1988,9 @@ self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致 self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者 self.__FeelPlayerList = [] # 所有摸怪玩家列表,处理任务及某些逻辑用 + + self.__OwnerHurtType = 0 + self.__OwnerHurtID = 0 return #--------------------------------------------------------------------- ## 移动到某一个点的附近点 @@ -3359,6 +3366,9 @@ GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', '%s' % (msgList), len(str(msgList))) + if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: + FamilyRobBoss.FamilyOwnerBossOnReborn(curNPC) + # 检查是否有光环, 在重生时处理,不然可能导致有些无战斗逻辑的怪物无法套上光环buff skillManager = curNPC.GetSkillManager() for index in xrange(skillManager.GetSkillCount()): @@ -3736,7 +3746,7 @@ #===================================================================================================== #boss伤血排行榜击杀逻辑 - BossHurtMng.BossOnKilled(curNPC) + #BossHurtMng.BossOnKilled(curNPC) #掉落需要用到摸怪,所以在处理掉落奖励之前设置 self.__SetFeelNPCPlayerList() @@ -3752,6 +3762,8 @@ # 记录boss击杀信息的NPC bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID) if bossIpyData: + if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: + killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID) #KillerJob = 0 if not self.__Killer else self.__Killer.GetJob() GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0) #=========================================================================================== @@ -4197,7 +4209,8 @@ self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家 self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo() - + self.__OwnerHurtType, self.__OwnerHurtID = hurtType, hurtID + #最后一击处理 self.__DoLastTimeHurtLogic() @@ -4227,6 +4240,10 @@ elif curTeam != None: self.__KilledByTeamSetPrize(curTeam, hurtType, hurtID) + #被仙盟杀死 + elif hurtType == ChConfig.Def_NPCHurtTypeFamily: + self.__KilledByFamilySetPrize(hurtType, hurtID) + else: GameWorld.ErrLog("NPC归属异常:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID)) @@ -4621,7 +4638,60 @@ self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList) #GameWorld.Log("队伍杀死怪物奖励,逻辑成功结束") return - + + def __KilledByFamilySetPrize(self, hurtType, hurtID): + ## 仙盟杀死NPC奖励逻辑 + curNPC = self.__Instance + + maxLV = 0 + dropPlayer = None + ownerPlayerList = [] + refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) + copyPlayerMgr = GameWorld.GetMapCopyPlayerManager() + for index in xrange(copyPlayerMgr.GetPlayerCount()): + player = copyPlayerMgr.GetPlayerByIndex(index) + if not player: + continue + + if player.GetFamilyID() != hurtID or not self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint): + continue + + curPlayerLV = player.GetLV() + if maxLV < curPlayerLV: + maxLV = curPlayerLV + dropPlayer = player + ownerPlayerList.append(player) + + if not ownerPlayerList: + GameWorld.Log("奖励归属仙盟,但是不存在可获得该奖励的成员!npcID=%s,hurtType=%s,hurtID=%s" + % (curNPC.GetNPCID(), hurtType, hurtID)) + + # 因为仙盟归属boss归属伤血第一的仙盟,仙盟伤血有保护,可能存在伤血第一仙盟在boss死亡的时候都不在 + # 此时掉落计算玩家算最后一击玩家,归属还是算伤血第一仙盟的 + if not dropPlayer: + dropPlayer = self.__LastHurtPlayer + + if not dropPlayer: + GameWorld.ErrLog("奖励归属仙盟,找不到掉落玩家!npcID=%s,hurtType=%s,hurtID=%s" + % (curNPC.GetNPCID(), hurtType, hurtID)) + return + + # 赶时间,先简单处理直接取最大等级的,之后可按实际情况来 + if not self.__LastHurtPlayer: + self.__LastHurtPlayer = dropPlayer + if not self.__MaxHurtPlayer: + self.__MaxHurtPlayer = dropPlayer + if not self.__Killer: + self.__Killer = dropPlayer + maxHurtID = dropPlayer.GetPlayerID() + + for curPlayer in ownerPlayerList: + self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, False) + + #调用物品掉落 + self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList) + return + ## 队伍或自己击杀NPC扩展功能 # @param curPlayer # @return None diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py index 92db14a..6d5e05c 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py @@ -17,6 +17,7 @@ import ShareDefine import ReadChConfig import GameLogic_SealDemon +import PlayerControl import IPY_GameWorld import IpyGameDataPY import GameWorld @@ -337,6 +338,18 @@ def NPCRefresh_100(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick) +def ResetActivityBossRefreshCount(): + ## 重置活动boss刷怪个数 + gameFB = GameWorld.GetGameFB() + gameNPC = GameWorld.GetNPCManager() + for i in xrange(gameNPC.GetCustomNPCRefreshCount()): + npcRefresh = gameNPC.GetCustomNPCRefreshAt(i) + refreshMark = npcRefresh.GetRefreshMark() + if gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark): + gameFB.SetGameFBDict(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark, 0) + GameWorld.DebugLog("重置活动boss刷怪点刷怪个数: refreshMark=%s" % refreshMark) + return + ## 世界boss刷怪 # @param npcRefresh 刷新实例 # @param tick 当前时间 @@ -363,9 +376,42 @@ gameFB = GameWorld.GetGameFB() gameWorldMgr = GameWorld.GetGameWorld() - bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID - rebornBossState = gameWorldMgr.GetGameWorldDictByKey(bosskey) - isNeedShunt = NPCCommon.IsMapNeedBossShunt(mapID) + relatedType = ipyData.GetRelatedType() + relatedID = ipyData.GetRelatedID() + isActivityBoss = False + # 关联日常活动 + if relatedType == 1: + actionKey = ShareDefine.Def_Notify_WorldKey_DailyActionState % relatedID + rebornBossState = 1 if gameWorldMgr.GetGameWorldDictByKey(actionKey) else 0 + isActivityBoss = True + # 关联运营活动,待扩展 + elif relatedType == 2: + pass + else: + bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID + rebornBossState = gameWorldMgr.GetGameWorldDictByKey(bosskey) + + rebornLineID = 0 + activityLineID = 0 # 活动线, 默认1线 + activityMapLineDict = IpyGameDataPY.GetFuncEvalCfg("MapLine", 2, {}) + if mapID in activityMapLineDict: + activityLineID = max(0, activityMapLineDict[mapID] - 1) + + # 活动boss只在活动线路刷 + if isActivityBoss: + activityBossRebornCount = gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark) + rebornLineID = activityLineID # 活动boss只刷在活动线 + # 不是活动线 + if rebornBossState and lineID != rebornLineID: + rebornBossState = 0 + + # 非活动boss活动线不刷, 1线除外 + else: + if activityLineID and lineID == activityLineID: + rebornBossState = 0 + stoneNPCID = 0 # 活动线暂不刷墓碑 + + isNeedShunt = NPCCommon.IsMapNeedBossShunt(mapID) and ipyData.GetIsNeedShunt() curNPC = None if npcRefresh.GetCount() > 0: @@ -379,8 +425,13 @@ #去掉非bossNPC NPCCommon.SetDeadEx(curNPC) - # 非一线 且 不需要分流的地图 且 不是封魔坛 不允许复活 - if lineID != 0 and not isNeedShunt and mapID != ChConfig.Def_FBMapID_SealDemon: + # 非复活线 且 不需要分流的地图 且 不是封魔坛 不允许复活 + if lineID != rebornLineID and not isNeedShunt and mapID != ChConfig.Def_FBMapID_SealDemon: + return + + if isActivityBoss and activityBossRebornCount > 0: + #GameWorld.DebugLog("活动线已经刷过不再刷活动boss: lineID=%s,rebornLineID=%s,refreshMark=%s,bossID=%s,activityBossRebornCount=%s" + # % (lineID, rebornLineID, refreshMark, bossID, activityBossRebornCount)) return # 死亡状态 @@ -391,6 +442,11 @@ return if curNPC.GetNPCID() == stoneNPCID: return + # 活动的boss + if curNPC.GetNPCID() == bossID and isActivityBoss: + GameWorld.Log("活动boss,活动结束,系统设置boss死亡!bossID=%s" % bossID) + PlayerControl.FBNotify("FairyGrabBossNoDead", [bossID]) + #去掉非墓碑NPC NPCCommon.SetDeadEx(curNPC) @@ -415,7 +471,12 @@ #初始化NPC __InitNewBornNPC(npcRefresh, tick) gameFB.SetGameFBDict(key, tick) - GameWorld.DebugLog("BossRefresh mapID=%s,refreshMark=%s,rebornNPCID=%s,isNeedShunt=%s,OK!" % (mapID, refreshMark, rebornNPCID, isNeedShunt), lineID) + + if isActivityBoss and rebornBossState: + gameFB.SetGameFBDict(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark, activityBossRebornCount + 1) + + GameWorld.DebugLog("BossRefresh mapID=%s,rebornLineID=%s,refreshMark=%s,rebornNPCID=%s,isNeedShunt=%s,OK!" + % (mapID, rebornLineID, refreshMark, rebornNPCID, isNeedShunt), lineID) return def IsShuntBossNeedProcess(curNPC): diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py index e79c69e..973b23a 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py @@ -1354,7 +1354,12 @@ if curPlayer.GetID() == 0: continue PlayerWorldAverageLv.UpdatePlayerWorldAverageLv(curPlayer) - + + # 日常活动 + elif key.startswith(ShareDefine.Def_Notify_WorldKey_DailyActionState[:-2]): + if value and gameWorldMgr.GetGameWorldDictByKey(key) != value: + NPCCustomRefresh.ResetActivityBossRefreshCount() + #通用设置 gameWorldMgr.SetGameWorldDict(key, value) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py index e538065..0e3b58b 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py @@ -1466,9 +1466,10 @@ DailyActionID_XXX12, # 废弃12 DailyActionID_Tower, # 符印塔 DailyActionID_MagicWeapon, # 法宝集魂 -DailyActionID_FBHelp, # 助战副本 +DailyActionID_FBHelp, # 助战副本 15 DailyActionID_BOSSHome, # BOSS之家 -) = range(1, 16 + 1) +DailyActionID_FamilyRobBoss, # 仙盟抢boss +) = range(1, 17 + 1) -- Gitblit v1.8.0