| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_CrossDemonKing  | 
| #  | 
| # @todo:±¾·þ¡¢¿ç·þÑýÍõ  | 
| # @author hxp  | 
| # @date 2019-04-13  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ±¾·þ¡¢¿ç·þÑýÍõ  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2019-04-13 11:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import FBCommon  | 
| import GameWorld  | 
| import ItemCommon  | 
| import IPY_GameWorld  | 
| import IpyGameDataPY  | 
| import PlayerFairyDomain  | 
| import GameWorldProcess  | 
| import PlayerControl  | 
| import ShareDefine  | 
| import PyGameData  | 
| import NPCCommon  | 
| import ChConfig  | 
| import ChItem  | 
|   | 
| FBDict_IsOver = 'FBDict_IsOver' #ÊÇ·ñÒѽáËã, ½áËãʱµÄtick  | 
| FBDict_IsPlayerOver = 'IsPlayerOver_%s' #Íæ¼ÒÊÇ·ñÒѾ½áËãµôÂäµÄ£¬²ÎÊýplayerID  | 
|   | 
| g_ownerInfo = {} # ¹éÊôÕßÐÅÏ¢ {funcLineID:[ownerID, ownerName], }  | 
|   | 
| ## ÊÇ·ñÐèÒª×ö½øÈ븱±¾Í¨Óüì²éÌõ¼þÂß¼£¬Ä¬ÈÏÐèÒª¼ì²é  | 
| def OnNeedCheckCanEnterFBComm(curPlayer, mapID, lineID):  | 
|     curState = PlayerFairyDomain.GetFairyDomainFBEventState(curPlayer, mapID, lineID)  | 
|     return curState != PlayerFairyDomain.FDEventState_Visiting  | 
|   | 
| ## ÊÇ·ñÄܹ»Í¨¹ý»î¶¯²éѯ½øÈë  | 
| def OnEnterFBEvent(curPlayer, mapID, lineID, tick):  | 
|     curState = PlayerFairyDomain.GetFairyDomainFBEventState(curPlayer, mapID, lineID)  | 
|     return curState in [PlayerFairyDomain.FDEventState_CanVisit, PlayerFairyDomain.FDEventState_Visiting]  | 
|   | 
| ## ½øÈë¿ç·þ¸±±¾×¢²áÊý¾ÝǰÂß¼  | 
| ## @return: ÊÇ·ñ¿ÉÒÔ×¢²áǰÍù¿ç·þ¸±±¾£¬´Îº¯ÊýÖпÉÒÔдһЩ¿Û³ýÏûºÄÂß¼µÈ  | 
| def OnRegEnterCrossFB(curPlayer, mapID, lineID):  | 
|     curState = PlayerFairyDomain.GetFairyDomainFBEventState(curPlayer, mapID, lineID)  | 
|     if curState == PlayerFairyDomain.FDEventState_CanVisit:  | 
|         return PlayerFairyDomain.SetFairyDomainFBEventState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visiting)  | 
|       | 
|     if curState == PlayerFairyDomain.FDEventState_Visiting:  | 
|         return True  | 
|       | 
|     return False  | 
|   | 
| def GetCurFBLineBOSSID(mapID=-1, lineID=-1):  | 
|     #¸Ã·ÖÏßË¢µÄBOSSID  | 
|     if mapID == -1:  | 
|         mapID = ChConfig.Def_FBMapID_CrossDemonKing if GameWorld.IsCrossServer() else ChConfig.Def_FBMapID_DemonKing  | 
|     if lineID == -1:  | 
|         lineID = GetCurFBFuncLineID()  | 
|     if mapID == -1 or lineID == -1:  | 
|         return 0  | 
|     ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":lineID})  | 
|     if not ipyData:  | 
|         return 0  | 
|     bossID = ipyData.GetBossID()  | 
|     return bossID  | 
|   | 
| def GetCurFBFuncLineID():  | 
|     ## »ñÈ¡±¾Ïß·¹¦ÄÜÏß·ID  | 
|     if GameWorld.IsCrossServer():  | 
|         return FBCommon.GetCrossDynamicLineMapFuncLineID()  | 
|     return GameWorld.GetGameWorld().GetPropertyID() - 1  | 
|   | 
| def GetCurFBLineZoneID():  | 
|     ## »ñÈ¡±¾Ïß·ËùÊô¿ç·þ·ÖÇø  | 
|     if GameWorld.IsCrossServer():  | 
|         return FBCommon.GetCrossDynamicLineMapZoneID()  | 
|     return 0  | 
|   | 
| ## ½ø¸±±¾  | 
| def DoEnterFB(curPlayer, tick):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     zoneID = GetCurFBLineZoneID()  | 
|     funcLineID = GetCurFBFuncLineID()  | 
|     bossID = GetCurFBLineBOSSID(lineID=funcLineID)  | 
|     GameWorld.Log("DoEnterFB zoneID=%s,funcLineID=%s,bossID=%s" % (zoneID, funcLineID, bossID), playerID)  | 
|     PyGameData.g_fbPickUpItemDict.pop(playerID, 0)  | 
|     if not GameWorld.IsCrossServer():  | 
|         PlayerFairyDomain.SetFairyDomainFBEventState(curPlayer, ChConfig.Def_FBMapID_DemonKing, funcLineID, PlayerFairyDomain.FDEventState_Visiting)  | 
|           | 
|     gameFB = GameWorld.GetGameFB()  | 
|     ## ¸±±¾ÒѾ½áÊø£¬µ«ÊÇûÓнáËãµôÂäµÄÍæ¼ÒÖ±½Ó֪ͨ½áÊø  | 
|     if gameFB.GetGameFBDictByKey(FBDict_IsOver) and not gameFB.GetGameFBDictByKey(FBDict_IsPlayerOver % playerID):  | 
|         __NotifyFBOver(curPlayer, 0)  | 
|     return  | 
|   | 
| ## ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  | 
| def OnProcess(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)  | 
|     if overTick and tick - overTick >= ChConfig.Def_FBPickupItemTime:  | 
|         GameWorld.Log("Ç¿ÖÆÌß³öÍæ¼Ò¹Ø±Õ¸±±¾: overTick=%s,tick=%s" % (overTick, tick))  | 
|         FBCommon.DoLogic_FBKickAllPlayer()  | 
|         return  | 
|       | 
|     return  | 
|   | 
| ## ¹Ø±Õ¸±±¾  | 
| def OnCloseFB(tick):  | 
|     global g_ownerInfo  | 
|     funcLineID = GetCurFBFuncLineID()  | 
|     g_ownerInfo.pop(funcLineID, None)  | 
|     GameWorld.GetGameWorld().SetPropertyID(0)  | 
|     return  | 
|   | 
| ## Íæ¼ÒÍ˳ö¸±±¾  | 
| def DoExitFB(curPlayer, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     #×îºóÒ»ÈËÍ˳ö¸±±¾Ôò¹Ø±ÕµØÍ¼  | 
|     if overTick and gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:  | 
|         GameWorldProcess.CloseFB(tick)  | 
|           | 
|     return  | 
|   | 
| ##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| def DoPlayerLeaveFB(curPlayer, tick):  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     #×îºóÒ»ÈËÍ˳ö¸±±¾Ôò¹Ø±ÕµØÍ¼  | 
|     if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:  | 
|         GameWorldProcess.CloseFB(tick)  | 
|           | 
|     return  | 
|   | 
| ## ÊÇ·ñ¸±±¾¸´»î  | 
| def OnPlayerReborn():  | 
|     return True  | 
|   | 
| ## »ñµÃ¸±±¾°ïÖúÐÅÏ¢  | 
| def DoFBHelp(curPlayer, tick):  | 
|     return  | 
|   | 
| def DoFB_Npc_KillNPC(attacker, curNPC, tick):  | 
|     __FBNPCOnKilled(curNPC, tick)  | 
|     return  | 
| def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  | 
|     __FBNPCOnKilled(curNPC, tick)  | 
|     return  | 
|   | 
| ## Ö´Ðи±±¾É±¹ÖÂß¼  | 
| def __FBNPCOnKilled(curNPC, tick):  | 
|     global g_ownerInfo  | 
|       | 
|     bossID = curNPC.GetNPCID()  | 
|     funcLineID = GetCurFBFuncLineID()  | 
|     if bossID != GetCurFBLineBOSSID(lineID=funcLineID):  | 
|         return  | 
|       | 
|     zoneID = GetCurFBLineZoneID()  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(FBDict_IsOver, tick)  | 
|       | 
|     ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)  | 
|     ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID) if ownerType == ChConfig.Def_NPCHurtTypePlayer else 0  | 
|       | 
|     isCrossServer = GameWorld.IsCrossServer()  | 
|     mapID = ChConfig.Def_FBMapID_CrossDemonKing if isCrossServer else ChConfig.Def_FBMapID_DemonKing  | 
|     GameWorld.Log("»÷ɱÑýÍõ: zoneID=%s,mapID=%s,funcLineID=%s,ownerID=%s,bossID=%s" % (zoneID, mapID, funcLineID, ownerID, bossID))  | 
|     ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":funcLineID})  | 
|     if not ipyData:  | 
|         return  | 
|     eventID = ipyData.GetID()  | 
|     ownerName = ""  | 
|     dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()  | 
|       | 
|     serverGroupIDList = []  | 
|     msgInfo = {}  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for index in xrange(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer:  | 
|             continue  | 
|         playerID = curPlayer.GetPlayerID()  | 
|         gameFB.SetGameFBDict(FBDict_IsPlayerOver % playerID, 1)  | 
|         isOwner = playerID == ownerID  | 
|         if isOwner:  | 
|             ownerName = curPlayer.GetPlayerName()  | 
|         giveItemList = __GetDemonKingPrizeItemList(curPlayer, mapID, funcLineID, eventID, isOwner)  | 
|         GameWorld.Log("Íæ¼Ò½±Àø: %s" % giveItemList, playerID)  | 
|         ChItem.DoMapDropItem(curPlayer, giveItemList, bossID, dropPosX, dropPosY, isOnlySelfSee=True, isDropDisperse=True)  | 
|         #curPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)  | 
|         if not isCrossServer:  | 
|             PlayerFairyDomain.SetFairyDomainFBEventState(curPlayer, mapID, funcLineID, PlayerFairyDomain.FDEventState_Visited)  | 
|         else:  | 
|             serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)  | 
|             if serverGroupID not in serverGroupIDList:  | 
|                 serverGroupIDList.append(serverGroupID)  | 
|             msgInfo[playerID] = [serverGroupID, mapID, funcLineID]  | 
|               | 
|     g_ownerInfo[funcLineID] = [ownerID, ownerName]  | 
|       | 
|     if msgInfo:  | 
|         GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_FBEnd, msgInfo, serverGroupIDList)  | 
|           | 
|     return  | 
|   | 
| ## ½áÊø¿ç·þ¸±±¾  | 
| def OnEndCrossFB(curPlayer, mapID, lineID, exData):  | 
|     PlayerFairyDomain.SetFairyDomainFBEventState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visited)  | 
|     return  | 
|   | 
| def OnPickUpItem(curPlayer, curItem, tick):  | 
|     mapItemType = curItem.GetType()  | 
|     if mapItemType == ChConfig.Def_ItemType_Money:  | 
|         return  | 
|     playerID = curPlayer.GetID()  | 
|     isEquip = ItemCommon.CheckItemIsEquip(curItem)  | 
|     jsonItem = ItemCommon.GetJsonItem(curItem)  | 
|     if playerID in PyGameData.g_fbPickUpItemDict:  | 
|         if isEquip or jsonItem.get("IsAuctionItem"):  | 
|             PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)  | 
|         else:  | 
|             isIn = False  | 
|             for itemInfo in PyGameData.g_fbPickUpItemDict[playerID]:  | 
|                 if itemInfo["ItemID"] == jsonItem["ItemID"] and itemInfo.get("IsAuctionItem") == jsonItem.get("IsAuctionItem"):  | 
|                     itemInfo["Count"] = itemInfo.get("Count", 1) + jsonItem.get("Count", 1)  | 
|                     isIn = True  | 
|                     break  | 
|             if not isIn:  | 
|                 PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)  | 
|     else:  | 
|         PyGameData.g_fbPickUpItemDict[playerID] = [jsonItem]  | 
|       | 
|     playerItemCount = 0  | 
|     mapItemManager = GameWorld.GetMapItemManager()  | 
|     for index in xrange(mapItemManager.GetMapItemCount()):  | 
|         mapItem = mapItemManager.GetMapItemByIndex(index)  | 
|         if not mapItem or mapItem.IsEmpty():  | 
|             continue  | 
|           | 
|         # »¹ÓÐÊôÓÚ×Ô¼ºµÄ¶«Î÷û¼ñ²»Í¨Öª½áÊø  | 
|         if mapItem.GetOwnerID() == curPlayer.GetPlayerID():  | 
|             playerItemCount += 1  | 
|           | 
|     isItemAllPickUp = (playerItemCount <= 1)  | 
|     if not isItemAllPickUp:  | 
|         return  | 
|       | 
|     __NotifyFBOver(curPlayer, 1)  | 
|     return  | 
|   | 
| def __NotifyFBOver(curPlayer, isPass):  | 
|     global g_ownerInfo  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     mapID = ChConfig.Def_FBMapID_CrossDemonKing if GameWorld.IsCrossServer() else ChConfig.Def_FBMapID_DemonKing  | 
|     funcLineID = GetCurFBFuncLineID()  | 
|     leaveTick = FBCommon.GetFBLineStepTime(mapID, funcLineID) * 1000  | 
|     ownerID, ownerName = g_ownerInfo.get(funcLineID, [0, ""])  | 
|     jsonItemList = PyGameData.g_fbPickUpItemDict.pop(playerID, [])  | 
|     overDict = {FBCommon.Over_ownerID:ownerID, FBCommon.Over_ownerName:ownerName, FBCommon.Over_itemInfo:jsonItemList}  | 
|     FBCommon.NotifyFBOver(curPlayer, mapID, funcLineID, isPass, overDict)  | 
|     curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)  | 
|     return  | 
|   | 
| ## ¿Í»§¶Ë½øÈë×Ô¶¨Ò峡¾°  | 
| def OnEnterCustomScene(curPlayer, mapID, lineID):  | 
|     PlayerFairyDomain.SetFairyDomainFBEventState(curPlayer, mapID, lineID, PlayerFairyDomain.FDEventState_Visiting)  | 
|     return  | 
|   | 
| ## ×Ô¶¨Ò峡¾°¸±±¾»÷ɱNPC  | 
| def DoCustomScene_Player_KillNPC(curPlayer, curNPC, mapID, lineID):  | 
|       | 
|     bossID = curNPC.GetNPCID()  | 
|     funcLineID = lineID  | 
|     curBossID = GetCurFBLineBOSSID(lineID=funcLineID)  | 
|     curState = PlayerFairyDomain.GetFairyDomainFBEventState(curPlayer, mapID, lineID)  | 
|     GameWorld.DebugLog("×Ô¶¨Ò峡¾°»÷ɱNPC: mapID=%s,lineID=%s,bossID=%s,curBossID=%s,eventState=%s"   | 
|                        % (mapID, lineID, bossID, curBossID, curState))  | 
|     if bossID != curBossID:  | 
|         return  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":mapID, "LineID":funcLineID})  | 
|     if not ipyData:  | 
|         return  | 
|     eventID = ipyData.GetID()  | 
|     eventFBType = ipyData.GetEventFBType()  | 
|     if eventFBType != PlayerFairyDomain.FDEventFBType_Client:  | 
|         GameWorld.DebugLog("    ·Çǰ¶Ë±¾£¬²»ÄܵôÂ䣡", playerID)  | 
|         return  | 
|     if curState != PlayerFairyDomain.FDEventState_Visiting:  | 
|         GameWorld.DebugLog("    ·ÇѰ·ÃÖУ¬²»ÄܵôÂ䣡", playerID)  | 
|         return  | 
|     PlayerFairyDomain.SetFairyDomainFBEventState(curPlayer, mapID, funcLineID, PlayerFairyDomain.FDEventState_Visited)  | 
|     PlayerControl.SetCustomMap(curPlayer, 0, 0)  | 
|       | 
|     isOwner = True  | 
|     giveItemList = __GetDemonKingPrizeItemList(curPlayer, mapID, funcLineID, eventID, isOwner)  | 
|     NPCCommon.DoGiveItemByVirtualDrop(curPlayer, giveItemList, bossID)  | 
|       | 
|     isPass = 1  | 
|     overDict = {FBCommon.Over_ownerID:playerID, FBCommon.Over_ownerName:curPlayer.GetPlayerName(),   | 
|                 FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(giveItemList)}  | 
|     FBCommon.NotifyFBOver(curPlayer, mapID, lineID, isPass, overDict)  | 
|     return  | 
|   | 
| def __GetDemonKingPrizeItemList(curPlayer, mapID, lineID, eventID, isOwner):  | 
|     giveItemList = PlayerFairyDomain.GetFairyAppointAward(curPlayer, eventID)  | 
|     if giveItemList:  | 
|         return giveItemList  | 
|       | 
|     # Ã»Óж¨Öƽ±ÀøÔòÈ¡³£¹æ½±Àø  | 
|     # [[¹éÊôÕßËæ»ú´ÎÊý, ·Ç¹éÊôËæ»ú´ÎÊý, [[È¨ÖØ,[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·]], ...]], ...]  | 
|       | 
|     giveItemList = []  | 
|     awardList = FBCommon.GetFBLineReward(mapID, lineID)  | 
|     for awardInfo in awardList:  | 
|         ownerCount, otherCount, itemWeightList = awardInfo  | 
|         if isOwner:  | 
|             if not ownerCount:  | 
|                 continue  | 
|             randCount = ownerCount  | 
|         else:  | 
|             if not otherCount:  | 
|                 continue  | 
|             randCount = otherCount  | 
|         realWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(curPlayer, itemWeightList, 1)  | 
|         if not realWeightList:  | 
|             continue  | 
|           | 
|         for _ in xrange(randCount):  | 
|             itemInfo = GameWorld.GetResultByWeightList(realWeightList)  | 
|             itemID, itemCount, isAuctionItem = itemInfo  | 
|             if not itemID:  | 
|                 continue  | 
|             giveItemList.append([itemID, itemCount, isAuctionItem])  | 
|               | 
|     return giveItemList  | 
|   | 
|   |