#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#---------------------------------------------------------------------
|
#
|
#---------------------------------------------------------------------
|
##@package PlayerFB
|
# @todo: Íæ¼Ò¸±±¾
|
#
|
# @author: hxp
|
# @date 2013-08-23
|
# @version 1.5
|
#
|
# @note
|
# @change: "2014-04-16 18:00" hxp Ôö¼Ó¼Ò×åboss¸±±¾½øÈëÅжÏ
|
# @change: "2015-01-09 10:30" hxp ¸ÄΪGetRouteServerIndex
|
# @change: "2015-03-20 15:00" hxp Ìõ¼þÅжÏÐÞ¸Ä
|
# @change: "2015-10-22 23:00" hxp Ôö¼Ó¿ç·þPK
|
# @change: "2017-01-04 12:00" hxp Ôö¼ÓÒì½çÈëÇÖ
|
#---------------------------------------------------------------------
|
#"""Version = 2017-01-04 12:00"""
|
#---------------------------------------------------------------------
|
import GameWorldBoss
|
import PlayerFamilyBoss
|
import PlayerHorsePetBoss
|
import GameWorldFamilyWar
|
import PlayerControl
|
import PyGameData
|
import IpyGameDataPY
|
import PlayerDBGSEvent
|
import PlayerTeam
|
import GameWorld
|
import ChConfig
|
import CrossRealmPlayer
|
import CrossRealmMsg
|
import ShareDefine
|
import CrossBoss
|
|
import random
|
#---------------------------------------------------------------------
|
|
#---------------------------------------------------------------------
|
def GetFBLineIpyData(mapID, lineID, isDefaultLine=True):
|
mapID = GetRecordMapID(mapID)
|
fbLineIpyData = IpyGameDataPY.GetIpyGameDataNotLog("FBLine", mapID, lineID)
|
if not fbLineIpyData and isDefaultLine:
|
#GameWorld.DebugLog("ûÓÐÖ¸¶¨¹¦ÄÜÏß·µÄÔòĬÈÏÈ¡0£¬ÔÙûÓеϰ¾ÍÊDz»ÐèÒªµÄmapID=%s, lineID=%s" % (mapID, lineID))
|
fbLineIpyData = IpyGameDataPY.GetIpyGameDataNotLog("FBLine", mapID, 0)
|
return fbLineIpyData
|
|
## »ñÈ¡¼Ç¼ֵµÄmapID
|
# @param mapID ËùÒª²éµÄmapID
|
# @return
|
# @remarks Ò»°ãÓÃÓÚ¼¸ÕŵØÍ¼¹«ÓÃÒ»·Ý´æ´¢¼Ç¼£¬Èç×é¶Ó¸±±¾½øÈë´ÎÊý£¬CDʱ¼äµÈÊý¾ÝÐè¹²Ïí
|
def GetRecordMapID(mapID):
|
DataMapIDDict = IpyGameDataPY.GetConfigEx("DataMapIDDict")
|
if not DataMapIDDict:
|
dMapIDDict = {}
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
for i in xrange(ipyDataMgr.GetFBLineCount()):
|
ipyData = ipyDataMgr.GetFBLineByIndex(i)
|
dMapID = ipyData.GetDataMapID()
|
mID = ipyData.GetMapID()
|
dMapIDList= dMapIDDict.get(dMapID, [])
|
if mID not in dMapIDList:
|
dMapIDList.append(mID)
|
dMapIDDict[dMapID] = dMapIDList
|
|
for dMapID in dMapIDDict.keys():
|
if len(dMapIDDict[dMapID]) == 1:
|
dMapIDDict.pop(dMapID)
|
DataMapIDDict = IpyGameDataPY.SetConfigEx("DataMapIDDict", dMapIDDict)
|
#GameWorld.Log("¼ÓÔØDataMapIDDict=%s" % DataMapIDDict)
|
|
for dataMapID, mapIDList in DataMapIDDict.items():
|
if mapID in mapIDList:
|
return dataMapID
|
return mapID
|
|
def ClientServerMsg_EnterFB(serverGroupID, msgData):
|
## ÊÕµ½×Ó·þÇëÇó½øÈ붯̬·ÖÅäµÄ¿ç·þ¸±±¾
|
playerID = msgData["PlayerID"]
|
dataMapID = msgData["DataMapID"]
|
funcLineID = msgData["FuncLineID"]
|
|
if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID)
|
if not zoneIpyData:
|
return
|
zoneID = zoneIpyData.GetZoneID()
|
bossID = msgData["BossID"]
|
if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID):
|
GameWorld.DebugLog("µ±Ç°¿ç·þÑýÍõËÀÍö״̬£¬²»¿É½øÈë! serverGroupID=%s,funcLineID=%s,zoneID=%s,bossID=%s" % (serverGroupID, funcLineID, zoneID, bossID))
|
return
|
|
mapCopyLineInfo = __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID)
|
if not mapCopyLineInfo:
|
return
|
mapID, copyMapID, isOpenNew = mapCopyLineInfo
|
|
# Èç¹ûÊǵȴýÏß·Æô¶¯ÖеÄÖ±½Ó·µ»Ø£¬µÈÆô¶¯ºÃºóÔÙ֪ͨ¿É½øÈë
|
if __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID):
|
return
|
else:
|
return
|
|
playerIDList = [playerID]
|
retInfo = [playerIDList, dataMapID, mapID, copyMapID]
|
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
|
return
|
|
def CrossServerMsg_EnterFBRet(msgData, tick):
|
## ÊÕµ½¿ç·þ·þÎñÆ÷¶¯Ì¬·ÖÅäµÄ¿ç·þ¸±±¾½øÈëÐÅÏ¢
|
|
playerIDList, dataMapID, mapID, copyMapID = msgData
|
|
if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
mapPosInfo = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 2)
|
else:
|
return
|
posX, posY = mapPosInfo
|
|
for playerID in playerIDList:
|
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
if not curPlayer:
|
continue
|
CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, posX, posY)
|
|
return
|
|
def __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID):
|
## »ñÈ¡¿ç·þ·ÖÇø¶ÔÓ¦¶¯Ì¬·ÖÅäµÄ¸±±¾µØÍ¼ÐéÄâÏß·ÐÅÏ¢
|
|
isOpenNew = False
|
zoneLineKey = (zoneID, funcLineID)
|
if dataMapID not in PyGameData.g_crossDynamicLineInfo:
|
PyGameData.g_crossDynamicLineInfo[dataMapID] = {}
|
zoneLineDict = PyGameData.g_crossDynamicLineInfo[dataMapID] # ¿ç·þ¶¯Ì¬Ïß·ÐÅÏ¢ {dataMapID:{(zoneID, funcLineID):[mapID, copyMapID], ...}, ...}
|
if zoneLineKey in zoneLineDict:
|
mapID, copyMapID = zoneLineDict[zoneLineKey]
|
GameWorld.DebugLog("ÒÑ´æÔڸ÷ÖÇø¹¦ÄÜÏß·ID£¬²»ÐèÒªÖØÐ·ÖÅä: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s" % (zoneID, funcLineID, mapID, copyMapID))
|
return mapID, copyMapID, isOpenNew
|
|
if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
mapIDList = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 1)
|
|
# ÆäËûµØÍ¼´ýÀ©Õ¹
|
else:
|
return
|
|
usedMapCopyList = zoneLineDict.values() # ÒѾʹÓÃÖеĵØÍ¼ÐéÄâÏß·
|
openMapID, openCopyMapID = 0, 0
|
for mapID in mapIDList:
|
maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(mapID, 0)
|
for copyMapID in xrange(maxCopyMapCount):
|
if [mapID, copyMapID] not in usedMapCopyList:
|
openMapID, openCopyMapID = mapID, copyMapID
|
break
|
if openMapID:
|
break
|
if not openMapID:
|
GameWorld.ErrLog("ûÓпÕÓàµÄÐéÄâÏß·£¬ÎÞ·¨¶¯Ì¬¿ªÆô¿ç·þ¸±±¾!dataMapID=%s, funcLineID=%s, zoneID=%s, mapIDList=%s"
|
% (dataMapID, funcLineID, zoneID, mapIDList))
|
return
|
isOpenNew = True
|
mapID, copyMapID = openMapID, openCopyMapID
|
|
zoneLineDict[zoneLineKey] = [mapID, copyMapID]
|
propertyID = zoneID * 1000 + funcLineID
|
GameWorld.DebugLog("²»´æÔڸ÷ÖÇø¹¦ÄÜÏß·ID£¬ÖØÐ·ÖÅä: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s,propertyID=%s"
|
% (zoneID, funcLineID, mapID, copyMapID, propertyID))
|
|
# ֪ͨµØÍ¼¿ªÆôеĵØÍ¼ÐéÄâ·ÖÏß
|
msgInfo = str([copyMapID, propertyID])
|
GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo))
|
return mapID, copyMapID, isOpenNew
|
|
def __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID):
|
## Ìí¼Ó¿ç·þÍæ¼Ò½øÈëµÈ´ý¶¯Ì¬¸±±¾ÐéÄâÏß·¿ªÆô¶ÓÁÐ
|
|
if mapID not in PyGameData.g_crossDynamicLineOpeningInfo:
|
PyGameData.g_crossDynamicLineOpeningInfo[mapID] = {}
|
openingMapCopyIDDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID] # ¿ç·þ¶¯Ì¬Ïß·ÕýÔÚ¿ªÆôÖеÄÏß·ÐÅÏ¢ {mapID:{copyMapID:{playerID:serverGroupID, ...}, ...}, ...}
|
|
if isOpenNew or copyMapID in openingMapCopyIDDict:
|
if copyMapID not in openingMapCopyIDDict:
|
openingMapCopyIDDict[copyMapID] = {}
|
waitingPlayerDict = openingMapCopyIDDict[copyMapID]
|
waitingPlayerDict[playerID] = serverGroupID
|
GameWorld.Log("Ìí¼ÓÍæ¼Ò½øÈëµÈ´ý¿ç·þ¶¯Ì¬¸±±¾ÐéÄâÏß·¿ªÆô¶ÓÁÐ: mapID=%s,copyMapID=%s,isOpenNew=%s,playerID=%s,serverGroupID=%s"
|
% (mapID, copyMapID, isOpenNew, playerID, serverGroupID))
|
GameWorld.Log(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
|
return True
|
return False
|
|
def OnCrossDynamicLineOpen(mapID, copyMapID):
|
## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÐéÄâÏß·Æô¶¯³É¹¦
|
|
if mapID not in PyGameData.g_crossDynamicLineOpeningInfo:
|
return
|
openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID]
|
waitingPlayerDict = openingCopyMapDict.pop(copyMapID, {})
|
if not waitingPlayerDict:
|
return
|
|
# ֪ͨ×Ó·þµÈ´ýÖеÄÍæ¼Ò¿ÉÒÔ½øÈ븱±¾
|
serverPlayerIDListDict = {}
|
for playerID, serverGroupID in waitingPlayerDict.items():
|
if serverGroupID not in serverPlayerIDListDict:
|
serverPlayerIDListDict[serverGroupID] = []
|
playerIDList = serverPlayerIDListDict[serverGroupID]
|
playerIDList.append(playerID)
|
|
dataMapID = GetRecordMapID(mapID)
|
GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·Æô¶¯³É¹¦£¬Í¨Öª×Ó·þµÈ´ýÍæ¼Ò¿É½øÈë: dataMapID=%s,mapID=%s,copyMapID=%s,serverPlayerIDListDict=%s"
|
% (dataMapID, mapID, copyMapID, serverPlayerIDListDict))
|
for serverGroupID, playerIDList in serverPlayerIDListDict.items():
|
retInfo = [playerIDList, dataMapID, mapID, copyMapID]
|
CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
|
|
GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo)
|
GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
|
return
|
|
def OnCrossDynamicLineClose(mapID, copyMapID):
|
## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÐéÄâÏß·¹Ø±Õ
|
|
dataMapID = GetRecordMapID(mapID)
|
GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·¹Ø±Õ dataMapID=%s,mapID=%s,copyMapID=%s" % (dataMapID, mapID, copyMapID))
|
zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {})
|
for key, mapCopyInfo in zoneLineDict.items():
|
if mapCopyInfo[0] == mapID and mapCopyInfo[1] == copyMapID:
|
zoneLineDict.pop(key)
|
break
|
|
openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo.get(mapID, {})
|
openingCopyMapDict.pop(copyMapID, {})
|
|
GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo)
|
GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
|
return
|
|
def OnCrossDynamicMapReset(mapID, copyMapCount):
|
## ¶¯Ì¬·ÖÅäÏß·µÄµØÍ¼ÖØÖÃ
|
|
dataMapID = GetRecordMapID(mapID)
|
GameWorld.Log("¶¯Ì¬·ÖÅäÐéÄâÏß·µØÍ¼ÖØÖà dataMapID=%s,mapID=%s,copyMapCount=%s" % (dataMapID, mapID, copyMapCount))
|
PyGameData.g_crossMapCopyMapCountDict[mapID] = copyMapCount
|
|
zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {})
|
for key, mapCopyInfo in zoneLineDict.items():
|
if mapCopyInfo[0] == mapID:
|
zoneLineDict.pop(key)
|
|
PyGameData.g_crossDynamicLineOpeningInfo.pop(mapID, None)
|
return
|
|
## ÇëÇó½øÈ븱±¾·ÖÏß
|
# @param curPlayer: ÇëÇóÍæ¼Ò
|
# @param queryCallName: ÇëÇ󻨵÷Ãû
|
# @param sendCMD: ÇëÇóµÄÃüÁî ¸ù¾ÝÇëÇóÀàÐͺÍÇëÇóÃüÁîÀ´¾ö¶¨×îÖÕ²Ù×÷
|
# @return None
|
def EnterFBLine(curPlayer, queryCallName, sendCMD, tick):
|
GameWorld.Log("EnterFBLine()...queryCallName=%s,sendCMD=%s" % (queryCallName, sendCMD), curPlayer.GetPlayerID())
|
playerManager = GameWorld.GetPlayerManager()
|
try:
|
mapInfo = eval(sendCMD)
|
except Exception, e:
|
GameWorld.ErrLog("EnterFBLine() sendCMD=%s error" % sendCMD)
|
return
|
|
if not mapInfo or len(mapInfo) < 2:
|
GameWorld.ErrLog("EnterFBLine() sendCMD=%s error!" % sendCMD)
|
return
|
|
#if mapInfo and len(mapInfo) == 2:
|
tagMapID = mapInfo[0]
|
tagLineID = mapInfo[1]
|
|
fbLineIpyData = GetFBLineIpyData(tagMapID, tagLineID)
|
sceneMapID = tagMapID if not fbLineIpyData else fbLineIpyData.GetMapID()
|
gameMap = GameWorld.GetMap(sceneMapID)
|
if not gameMap:
|
GameWorld.ErrLog("Ä¿±ê¸±±¾µØÍ¼²»´æÔÚ!tagMapID=%s,sceneMapID=%s" % (tagMapID, sceneMapID), curPlayer.GetPlayerID())
|
return
|
|
# ×é¶Ó¸±±¾, ÓжÓÎéµÄÇé¿ö²ÅÑéÖ¤ÆäËû¶ÓÔ±¿É·ñ½øÈ룬·ñÔò´ú±íµ¥È˽øÈë
|
if gameMap.GetMapFBType() == ChConfig.fbtTeam:
|
PlayerTeam.OnEnterFBTeamAsk(curPlayer, PlayerTeam.TeamFBAskType_Enter, tagMapID, tagLineID, tick)
|
return
|
|
#·âħ̳¸±±¾ÅжÏÀïÃæµÄBOSSÊÇ·ñµ½ÁËË¢ÐÂʱ¼ä
|
if tagMapID in ChConfig.WorldBossFBMapIDList:
|
bossID = mapInfo[2]
|
if not GameWorldBoss.GetBossIsAliveOrCanReborn(bossID):
|
return
|
|
elif tagMapID == ChConfig.Def_FBMapID_FamilyWar:
|
if not GameWorldFamilyWar.CheckPlayerCanEnterFamilyWarFBMap(curPlayer):
|
return
|
|
elif tagMapID == ChConfig.Def_FBMapID_FamilyBossMap:
|
if not PlayerFamilyBoss.CheckIsFamilyBossFBOpen(curPlayer.GetFamilyID(), tagMapID):
|
GameWorld.Log("EnterFBLine mapID=%s is familyBossFB, but is not open!" % tagMapID)
|
return
|
#ÊØÎÀÈË»Ê ÊÇ·ñÒѲμÓ
|
elif tagMapID == ChConfig.Def_FBMapID_FamilyInvade:
|
if curPlayer.GetFamilyID() in PyGameData.g_swrhJoinRecord:
|
PlayerControl.NotifyCode(curPlayer, "TheEmperor1")
|
return
|
#¶àÏÉÃËBOSS ÊÇ·ñÒѽáÊø
|
elif tagMapID == ChConfig.Def_FBMapID_AllFamilyBoss:
|
if not PlayerFamilyBoss.IsInAllFamilyBoss(tagLineID):
|
#»î¶¯Î´¿ªÆô
|
return
|
if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_AllFamilyBossTime):
|
#BOSSÒѱ»»÷ɱ
|
return
|
#Æï³èBOSS ÊÇ·ñÒѽáÊø
|
elif tagMapID == ChConfig.Def_FBMapID_HorsePetBoss:
|
if not PlayerHorsePetBoss.IsInHorsePetBoss():
|
#»î¶¯Î´¿ªÆô
|
return
|
if PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_HorsePetBossTime % tagLineID):
|
#BOSSÒѱ»»÷ɱ
|
return
|
# MapServer_QueryPlayer(int srcPlayerID, int queryType, int queryID, int mapID, char *callName, char *cmd,WORD cmdLen, int RouteServerIndex)
|
playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_EnterFB, 0, tagMapID,
|
queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex())
|
return
|