#!/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  
 | 
  
 | 
  
 |