#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package GameWorldLogic.FBProcess.GameLogic_CrossFamilyFlagwar
|
#
|
# @todo:¿ç·þÏÉÃ˶áÆìÕ½/Öð¹Íò½ç
|
# @author hxp
|
# @date 2023-04-25
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: ¿ç·þÏÉÃ˶áÆìÕ½
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2023-04-25 15:30"""
|
#-------------------------------------------------------------------------------
|
|
import ChConfig
|
import FBCommon
|
import GameWorld
|
import ShareDefine
|
import IPY_GameWorld
|
import IpyGameDataPY
|
import GameWorldProcess
|
import DataRecordPack
|
import PlayerControl
|
import SkillCommon
|
import BuffSkill
|
import AICommon
|
import GameObj
|
import GameMap
|
|
import operator
|
import time
|
|
#µ±Ç°¸±±¾µØÍ¼µÄ״̬
|
(
|
FB_Step_Open, # µØÍ¼¿ªÆô
|
FB_Step_Prepare, # µØÍ¼×¼±¸
|
FB_Step_Fighting, # Õ½¶·ÖÐ
|
FB_Step_LeaveTime, # ×ÔÓÉʱ¼ä
|
FB_Step_Over, # ¸±±¾¹Ø±Õ
|
) = range(5)
|
|
(
|
Time_Prepare, # ¸±±¾×¼±¸Ê±¼ä 0
|
Time_Fight, # ¸±±¾Õ½¶·Ê±¼ä 1
|
Time_Leave, # ¸±±¾À뿪ʱ¼ä 2
|
) = range(3)
|
|
FightRefreshInterval = 5000 # Õ½¶·½×¶Îˢд¦Àí¼ä¸ô£¬ºÁÃë
|
|
GameFBData_BattleMgr = "BattleMgr"
|
|
## Õ½³¡¹ÜÀíÀà
|
class BattleMgr():
|
|
def __init__(self):
|
self.zoneID = 0
|
self.battlePlayerDict = {} # ²ÎÓëÕ½¶·µÄÍæ¼Ò {playerID:BattlePlayer, ...}
|
self.battleFamilyDict = {} # ²ÎÓëÕ½¶·µÄÏÉÃË {familyID:BattleFamily, ...}
|
self.battleFamilySortList = [] # ²ÎÓëÕ½¶·µÄÏÉÃË»ý·ÖÅÅÃûÁбí [BattleFamily, ...]
|
|
self.allotRebornPointInfo = {} # ÒѾ·ÖÅäµÄ¸´»îµã£¬Ò»¸ö¸´»îµã¿ÉÄܶà¸öÏÉÃ˹²Óà {index:[familyID, ...], ...}
|
|
self.playerFlagDict = {} # Íæ¼Ò»ñµÃÕ½Æì {playerID:flagNPC, ...}
|
|
self.worldHelpDict = {} # δ֪ͨµÄÊÀ½ç±ä¸üÐÅÏ¢
|
return
|
|
def sortBattleFamilyScore(self):
|
self.battleFamilySortList = self.battleFamilyDict.values()
|
self.battleFamilySortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True)
|
return
|
|
def getBattleFamily(self, familyID):
|
if familyID in self.battleFamilyDict:
|
batFamily = self.battleFamilyDict[familyID]
|
else:
|
batFamily = BattleFamily(familyID)
|
self.battleFamilyDict[familyID] = batFamily
|
return batFamily
|
|
def getBattlePlayer(self, playerID):
|
if playerID in self.battlePlayerDict:
|
batPlayer = self.battlePlayerDict[playerID]
|
else:
|
batPlayer = BattlePlayer(playerID)
|
self.battlePlayerDict[playerID] = batPlayer
|
return batPlayer
|
|
def addBattleFamily(self, familyID, name):
|
batFamily = self.getBattleFamily(familyID)
|
batFamily.name = name
|
self.__allotRebornPoint(familyID)
|
return batFamily
|
|
def __allotRebornPoint(self, familyID):
|
batFamily = self.getBattleFamily(familyID)
|
for familyIDList in self.allotRebornPointInfo.values():
|
if familyID in familyIDList:
|
return
|
allotIndex = -1
|
allotAlreadyIndexs = self.allotRebornPointInfo.keys()
|
rebornPointList = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwar", 2)
|
if len(rebornPointList) > len(allotAlreadyIndexs):
|
# »¹ÓпÕÓàµãδ·ÖÅ䣬ֱ½Ó·ÖÅä¿ÕÓàµã
|
for index, _ in enumerate(rebornPointList):
|
if index not in allotAlreadyIndexs:
|
allotIndex = index
|
break
|
|
if allotIndex == -1:
|
# ûÓпÕÓàµãÁË£¬ÓëÆäËûÏÉÃ˹²Ó㬷ÖÅäÒ»¸ö×îÉÙÏÉÃ˵ĸ´»îµã
|
leastIDCount = 99999
|
for index, familyIDList in self.allotRebornPointInfo.items():
|
if len(familyIDList) < leastIDCount and index < len(rebornPointList):
|
leastIDCount = len(familyIDList)
|
allotIndex = index
|
|
rebornPoint = rebornPointList[allotIndex]
|
if len(rebornPoint) != 3:
|
GameWorld.ErrLog("¸´»îµãÅäÖÃÒì³£! index=%s, %s" % (allotIndex, rebornPoint))
|
return
|
|
if allotIndex not in self.allotRebornPointInfo:
|
self.allotRebornPointInfo[allotIndex] = []
|
familyIDList = self.allotRebornPointInfo[allotIndex]
|
familyIDList.append(familyID)
|
|
batFamily.rebornPoint = rebornPoint
|
GameWorld.Log("·ÖÅäÏÉÃ˸´»îµã: familyID=%s,allotIndex=%s,rebornPoint=%s,allotRebornPointInfo=%s"
|
% (familyID, allotIndex, rebornPoint, self.allotRebornPointInfo), self.zoneID)
|
return True
|
|
def setPlayerFlag(self, playerID, flagNPC):
|
self.playerFlagDict[playerID] = flagNPC
|
|
npcID = flagNPC.GetNPCID()
|
batPlayer = self.getBattlePlayer(playerID)
|
flagOwner = self.worldHelpDict.get("flagOwner", {})
|
flagOwner[npcID] = [playerID, batPlayer.name]
|
self.worldHelpDict["flagOwner"] = flagOwner
|
return
|
|
def popPlayerFlag(self, playerID):
|
self.playerFlagDict.pop(playerID, None)
|
|
flagOwner = self.worldHelpDict.get("flagOwner", {})
|
for npcID, playerInfo in flagOwner.items():
|
if playerID == playerInfo[0]:
|
flagOwner.pop(npcID, None)
|
break
|
return
|
|
def getWorldHelpInfo(self, isAll, familyID):
|
helpInfo = {}
|
if not isAll:
|
helpInfo = self.worldHelpDict
|
else:
|
flagOwner = {}
|
for playerID, flagNPC in self.playerFlagDict.items():
|
npcID = flagNPC.GetNPCID()
|
batPlayer = self.getBattlePlayer(playerID)
|
flagOwner[npcID] = [playerID, batPlayer.name]
|
helpInfo = {"flagOwner":flagOwner}
|
|
# È¡×ÔÉíÏÉÃ˼°Ç°ºóÃû´ÎÏÉÃËÐÅÏ¢
|
familyIndex = -1
|
familyList = []
|
for index, batFamily in enumerate(self.battleFamilySortList):
|
if familyID == batFamily.familyID:
|
familyIndex = index
|
break
|
# µÚÒ»ÃûĬÈÏȡǰ3Ãû
|
if familyIndex == 0:
|
familyList = self.battleFamilySortList[:3]
|
# µÚÒ»ÃûĬÈÏȡǰ3Ãû
|
elif familyIndex == len(self.battleFamilySortList) - 1:
|
familyList = self.battleFamilySortList[-3:]
|
elif familyIndex > 0:
|
familyList = self.battleFamilySortList[familyIndex - 1:familyIndex + 2]
|
for i, batFamily in enumerate(familyList):
|
familyList[i] = [batFamily.familyID, batFamily.score, batFamily.name]
|
helpInfo["familyList"] = familyList
|
return {"world":helpInfo}
|
|
## Õ½³¡ÏÉÃËÀà
|
class BattleFamily():
|
|
def __init__(self, familyID):
|
self.familyID = familyID
|
self.name = ""
|
self.score = 0 # »ý·Ö
|
self.scoreSortTime = 0 # »ý·Ö±ä¸üÅÅÐòtimeÖµ£¬ÓÃÓÚͬ»ý·Öʱ£¬Ïȵ½ÅÅÃû¿¿Ç°
|
self.rebornPoint = [130, 300, 10] # ¸´»îµã×ø±ê [x,y,r]£¬ÕâÀïΪĬÈÏÖµ£¬·ÀֹûÓзÖÅäµ½±¨´íµÈ
|
|
self.battlePlayerIDList = [] # ²ÎÓëÕ½¶·µÄÏÉÃËÍæ¼ÒIDÁбí [playerID, ...]
|
self.battlePlayerSortList = [] # ²ÎÓëÕ½¶·µÄÏÉÃËÍæ¼Ò»ý·ÖÅÅÃûÁбí [BattlePlayer, ...]
|
|
self.homePlayerIDList = [] # ÔÚ¸´»îµãÀïµÄÍæ¼Ò
|
|
self.familyHelpDict = {} # δ֪ͨµÄÏÉÃ˱ä¸üÐÅÏ¢
|
return
|
|
def addJoinPlayer(self, playerID):
|
if playerID not in self.battlePlayerIDList:
|
self.battlePlayerIDList.append(playerID)
|
self.familyHelpDict["playerCount"] = len(self.battlePlayerIDList)
|
return
|
|
def setPlayerToRebornPoint(self, curPlayer):
|
if not self.rebornPoint:
|
return
|
randPosX, randPosY, maxDist = self.rebornPoint
|
posPoint = GameMap.GetEmptyPlaceInAreaEx(randPosX, randPosY, 3, maxDist)
|
curPlayer.ResetPos(posPoint.GetPosX(), posPoint.GetPosY())
|
return
|
|
def sortBattlePlayerScore(self):
|
if len(self.battlePlayerIDList) != len(self.battlePlayerSortList):
|
self.battlePlayerSortList = []
|
mgr = GetBattleMgr()
|
for playerID in self.battlePlayerIDList:
|
batPlayer = mgr.getBattlePlayer(playerID)
|
self.battlePlayerSortList.append(batPlayer)
|
self.battlePlayerSortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True)
|
return
|
|
def addFamilyScore(self, addValue):
|
## Ôö¼Ó»ý·Ö
|
if addValue <= 0:
|
return
|
self.score = max(0, self.score + addValue)
|
self.familyHelpDict["score"] = self.score
|
calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
|
self.scoreSortTime = max(0, calcTime - int(time.time()))
|
#GameWorld.DebugLog(" Ôö¼ÓÏÉÃË»ý·Ö: familyID=%s,addValue=%s,updScore=%s" % (self.familyID, addValue, self.score))
|
return
|
|
def getFamilyHelpInfo(self, isAll):
|
helpInfo = {}
|
if not isAll:
|
helpInfo = self.familyHelpDict
|
else:
|
helpInfo = {"score":self.score, "playerCount":len(self.battlePlayerIDList)}
|
return {"family":helpInfo}
|
|
## Õ½³¡Íæ¼ÒÀà
|
class BattlePlayer():
|
|
def __init__(self, playerID):
|
self.playerID = playerID
|
self.name = ""
|
self.familyID = 0
|
self.familyName = ""
|
self.accID = ""
|
self.job = 1
|
self.realmLV = 0
|
self.fightPower = 0
|
|
self.restoreHPTick = 0 # ÓªµØ»ØÑªtick
|
self.healthRebornCount = 0 # Եؽ¡¿µ¸´»î´ÎÊý
|
self.continueKillCount = 0 # Á¬É±´ÎÊý
|
|
self.score = 0 # »ý·Ö
|
self.scoreSortTime = 0 # »ý·Ö±ä¸üÅÅÐòtimeÖµ£¬ÓÃÓÚͬ»ý·Öʱ£¬Ïȵ½ÅÅÃû¿¿Ç°
|
self.hurtTotal = 0 # ÀÛ¼ÆÉ˺¦
|
|
self.onlineCalcTick = 0 # ÔÚÏß¼ÆËãtick
|
self.outsideFlagTick = 0 # ³¬³öÕ½Æì·¶Î§¼ÆËãtick
|
self.outsideFlagNotifySecond = 0 # ֪ͨ³¬³ö·¶Î§Ãë
|
|
self.playerHelpDict = {} # δ֪ͨµÄÍæ¼Ò±ä¸üÐÅÏ¢
|
return
|
|
def doPlayerEnter(self, curPlayer, tick):
|
self.familyID = curPlayer.GetFamilyID()
|
self.familyName = curPlayer.GetFamilyName()
|
self.job = curPlayer.GetJob()
|
self.accID = curPlayer.GetAccID()
|
self.name = curPlayer.GetPlayerName()
|
self.realmLV = curPlayer.GetOfficialRank()
|
self.fightPower = PlayerControl.GetFightPower(curPlayer)
|
|
self.onlineCalcTick = tick
|
return
|
|
def addPlayerScore(self, addValue):
|
if addValue <= 0:
|
return
|
self.score = max(0, self.score + addValue)
|
calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
|
self.scoreSortTime = max(0, calcTime - int(time.time()))
|
#GameWorld.DebugLog(" Ôö¼ÓÍæ¼Ò»ý·Ö: playerID=%s,addValue=%s,updScore=%s" % (self.playerID, addValue, self.score))
|
self.playerHelpDict.update({"score":self.score})
|
return
|
|
def addHealthRebornCount(self):
|
self.healthRebornCount += 1
|
self.playerHelpDict["healthRebornCount"] = self.healthRebornCount
|
return
|
|
def getPlayerHelpInfo(self, isAll):
|
helpInfo = {}
|
if not isAll:
|
helpInfo = self.playerHelpDict
|
else:
|
helpInfo = {"score":self.score, "healthRebornCount":self.healthRebornCount}
|
return {"player":helpInfo}
|
|
def GetBattleMgr():
|
mgr = FBCommon.GetGameFBData(GameFBData_BattleMgr)
|
if not mgr:
|
mgr = BattleMgr()
|
FBCommon.SetGameFBData(GameFBData_BattleMgr, mgr)
|
return mgr
|
|
def GetBFStepTime(): return IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwar", 1) # ½×¶Îʱ¼ä
|
|
def OnOpenFB(tick):
|
FBCommon.SetGameFBData(GameFBData_BattleMgr, None)
|
|
mgr = GetBattleMgr()
|
mgr.zoneID = GameWorld.GetGameWorld().GetPropertyID()
|
|
FBCommon.SetFBStep(FB_Step_Prepare, tick)
|
return
|
|
def OnCloseFB(tick):
|
GameWorld.GetGameWorld().SetPropertyID(0)
|
FBCommon.SetGameFBData(GameFBData_BattleMgr, None)
|
#FBCommon.ClearFBNPC()
|
return
|
|
|
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
|
if GameWorld.IsCrossServer():
|
return True
|
|
if not curPlayer.GetFamilyID():
|
GameWorld.DebugLog("ÎÞÏÉÃËÎÞ·¨½øÈë: mapID=%s" % mapID)
|
return False
|
|
if not GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_CrossDailyActionState % ShareDefine.CrossDailyActionID_FamilyWarFlag):
|
GameWorld.DebugLog("·Ç»î¶¯ÖУ¬ÎÞ·¨½øÈë: CrossDailyActionID=%s" % ShareDefine.CrossDailyActionID_FamilyWarFlag)
|
return False
|
|
return True
|
|
def OnChangeMapAsk(ask, tick):
|
return IPY_GameWorld.cmeAccept
|
|
##¸±±¾Íæ¼Ò½øÈëµã, Íæ¼Ò·ÖÉ¢ÔÚ°ë¾¶3¸ñ·¶Î§
|
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
|
return ipyEnterPosInfo
|
|
def DoEnterFB(curPlayer, tick):
|
gameFB = GameWorld.GetGameFB()
|
fbStep = gameFB.GetFBStep()
|
playerID = curPlayer.GetPlayerID()
|
familyID = curPlayer.GetFamilyID()
|
familyName = curPlayer.GetFamilyName()
|
mgr = GetBattleMgr()
|
|
if fbStep not in [FB_Step_Prepare, FB_Step_Fighting] or not familyID:
|
GameWorld.Log("DoEnterFB... fbStep=%s,familyID=%s,playerID=%s PlayerLeaveFB" % (fbStep, familyID, playerID), mgr.zoneID)
|
PlayerControl.PlayerLeaveFB(curPlayer)
|
return
|
|
GameWorld.Log("DoEnterFB... fbStep=%s,familyID=%s,playerID=%s" % (fbStep, familyID, playerID), mgr.zoneID)
|
|
#--- ²âÊÔ ---
|
# testFamilyCount = 50
|
# if len(mgr.battleFamilyDict) < testFamilyCount:
|
# import random
|
# for i in range(testFamilyCount):
|
# fakeID = i + 10
|
# fakeName = "¼ÙÃû×Ö%s" % fakeID
|
# fakeName = fakeName.decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
|
# fakeFamily = mgr.addBattleFamily(fakeID, fakeName)
|
# fakeFamily.addFamilyScore(random.randint(1000, 1500))
|
#-----------
|
|
batFamily = mgr.addBattleFamily(familyID, familyName)
|
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batPlayer.doPlayerEnter(curPlayer, tick)
|
|
batFamily.addJoinPlayer(playerID)
|
batFamily.setPlayerToRebornPoint(curPlayer)
|
|
if fbStep == FB_Step_Prepare:
|
notify_tick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)
|
|
elif fbStep == FB_Step_Fighting:
|
notify_tick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
|
|
NotifyCrossFamilyFlagHelp(True, curPlayer)
|
return
|
|
def NotifyCrossFamilyFlagHelp(isAll=False, curPlayer=None, helpEx=None):
|
## ¹ã²¥Õ½³¡°ïÖúÐÅÏ¢£¬Õë¶ÔËùÓÐÍæ¼Ò
|
|
mgr = GetBattleMgr()
|
|
if curPlayer:
|
__notifyPlayerHelp(curPlayer, mgr, isAll, helpEx)
|
else:
|
playerManager = GameWorld.GetMapCopyPlayerManager()
|
for index in xrange(playerManager.GetPlayerCount()):
|
player = playerManager.GetPlayerByIndex(index)
|
if not player:
|
continue
|
playerID = player.GetPlayerID()
|
if playerID not in mgr.battlePlayerDict:
|
#GameWorld.DebugLog("»¹Î´¼ÓÈëÕ½¶·£¬Ôݲ»´¦Àí! playerID=%s" % playerID)
|
continue
|
__notifyPlayerHelp(player, mgr, isAll, helpEx)
|
|
# ÖØÖÃδ֪ͨµÄ
|
mgr.worldHelpDict = {}
|
for familyID in mgr.battleFamilyDict.keys():
|
batFamily = mgr.getBattleFamily(familyID)
|
batFamily.familyHelpDict = {}
|
|
return
|
|
def __notifyPlayerHelp(curPlayer, mgr, isAll, helpEx):
|
if not mgr:
|
mgr = GetBattleMgr()
|
|
playerID = curPlayer.GetPlayerID()
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batFamily = mgr.getBattleFamily(batPlayer.familyID)
|
|
helpDict = {}
|
helpDict.update(mgr.getWorldHelpInfo(isAll, batPlayer.familyID))
|
helpDict.update(batFamily.getFamilyHelpInfo(isAll))
|
helpDict.update(batPlayer.getPlayerHelpInfo(isAll))
|
|
if helpEx:
|
helpDict.update(helpEx)
|
|
GameWorld.DebugLog("FBHelp: %s" % helpDict, playerID)
|
FBCommon.Notify_FBHelp(curPlayer, helpDict)
|
batPlayer.playerHelpDict = {}
|
return
|
|
|
##»ñµÃ¸±±¾°ïÖúÐÅÏ¢, ÓÃÓÚ֪ͨÕóÓª±È·ÖÌõ
|
def DoFBHelp(curPlayer, tick):
|
return
|
|
##Íæ¼ÒÍ˳ö¸±±¾
|
def DoExitFB(curPlayer, tick):
|
gameFB = GameWorld.GetGameFB()
|
fbStep = gameFB.GetFBStep()
|
if fbStep != FB_Step_Fighting:
|
return
|
|
mgr = GetBattleMgr()
|
playerID = curPlayer.GetPlayerID()
|
GameWorld.Log("DoExitFB... playerID=%s,fbStep=%s" % (playerID, fbStep), mgr.zoneID)
|
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batPlayer.onlineCalcTick = 0
|
return
|
|
##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.
|
def DoPlayerLeaveFB(curPlayer, tick):
|
return
|
|
##¸±±¾×ÜÂß¼¼ÆÊ±Æ÷
|
# @param tick ʱ¼ä´Á
|
# @return ÎÞÒâÒå
|
# @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷
|
def OnProcess(tick):
|
fbStep = GameWorld.GetGameFB().GetFBStep()
|
|
# ¸±±¾×¼±¸
|
if fbStep == FB_Step_Prepare:
|
__DoLogic_FB_Prepare(fbStep, tick)
|
|
# ¸±±¾½øÐÐÖÐ
|
elif fbStep == FB_Step_Fighting:
|
__DoLogic_FB_Fighting(tick)
|
|
# ¸±±¾½áÊø
|
elif fbStep == FB_Step_LeaveTime:
|
__DoLogic_FB_Leave(tick)
|
|
return
|
|
|
def __DoLogic_FB_Prepare(fbStep, tick):
|
|
remaindTick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
if remaindTick > 0:
|
return
|
|
FBCommon.SetFBStep(FB_Step_Fighting, tick)
|
|
mgr = GetBattleMgr()
|
fightTime = GetBFStepTime()[Time_Fight] * 1000
|
playerManager = GameWorld.GetMapCopyPlayerManager()
|
for index in xrange(playerManager.GetPlayerCount()):
|
curPlayer = playerManager.GetPlayerByIndex(index)
|
playerID = curPlayer.GetPlayerID()
|
if not playerID:
|
continue
|
if playerID not in mgr.battlePlayerDict:
|
#GameWorld.DebugLog("»¹Î´¼ÓÈëÕ½¶·£¬Ôݲ»´¦Àí! playerID=%s" % playerID)
|
continue
|
curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, fightTime, True)
|
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batPlayer.onlineCalcTick = tick # ¿ªÊ¼Õ½¶·ÖØÐÂͳ¼ÆÔÚÏßÊÕÒæ
|
|
batFamily = mgr.getBattleFamily(batPlayer.familyID)
|
batFamily.setPlayerToRebornPoint(curPlayer)
|
|
NotifyCrossFamilyFlagHelp(True)
|
#PlayerControl.FBNotify("CrossBattlefieldStartFighting")
|
return
|
|
def __DoLogic_FB_Fighting(tick):
|
|
passTick = tick - GameWorld.GetGameFB().GetFBStepTick()
|
remaindTick = GetBFStepTime()[Time_Fight] * 1000 - passTick
|
if remaindTick > 0:
|
__refreshFamilyHome(tick)
|
__refreshFlagoutside(tick)
|
|
gameFB = GameWorld.GetGameFB()
|
lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)
|
if tick - lastTick >= FightRefreshInterval:
|
gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)
|
refreshCrossFamilyFlagwar(tick)
|
NotifyCrossFamilyFlagHelp()
|
return
|
|
DoOver(tick)
|
return
|
|
def __DoLogic_FB_Leave(tick):
|
remaindTick = GetBFStepTime()[Time_Leave] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
if remaindTick > 0:
|
return
|
|
FBCommon.DoLogic_FBKickAllPlayer()
|
GameWorldProcess.CloseFB(tick)
|
FBCommon.SetFBStep(FB_Step_Over, tick)
|
return
|
|
def __refreshFamilyHome(tick):
|
# Ë¢ÐÂÓªµØÏà¹Ø£¬Èç»ØÑªµÈ
|
|
restoreHPPerBySecond = IpyGameDataPY.GetFuncCfg("CrossFamilyFlagwar", 3) # ÿÃë»ØÑª°Ù·Ö±È
|
|
mgr = GetBattleMgr()
|
copyMapMgr = GameWorld.GetMapCopyPlayerManager()
|
for familyID in mgr.battleFamilyDict.keys():
|
batFamily = mgr.getBattleFamily(familyID)
|
safePosX, safePosY, safeRadius = batFamily.rebornPoint
|
|
for playerID in batFamily.homePlayerIDList[::-1]:
|
curPlayer = copyMapMgr.FindPlayerByID(playerID)
|
if not curPlayer:
|
continue
|
|
batPlayer = mgr.getBattlePlayer(playerID)
|
|
if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) > safeRadius:
|
batFamily.homePlayerIDList.remove(playerID)
|
batPlayer.restoreHPTick = 0
|
continue
|
|
# ÓªµØ»ØÑª
|
restoreSeconds = (tick - batPlayer.restoreHPTick) / 1000.0 if batPlayer.restoreHPTick else 1 # Ê״α£µ×1Ãë
|
if restoreSeconds < 1:
|
continue
|
maxHP = GameObj.GetMaxHP(curPlayer)
|
if GameObj.GetHP(curPlayer) < maxHP:
|
restoreHP = int(maxHP * restoreHPPerBySecond / 100.0 * round(restoreSeconds, 1))
|
SkillCommon.SkillAddHP(curPlayer, 0, restoreHP)
|
batPlayer.restoreHPTick = tick
|
|
return
|
|
def __refreshFlagoutside(tick):
|
# Ë¢ÐÂÕ½Æì³ö½ç
|
|
mgr = GetBattleMgr()
|
|
if not mgr.playerFlagDict:
|
return
|
|
outsideR, protectSeconds = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 4)
|
|
copyMapMgr = GameWorld.GetMapCopyPlayerManager()
|
for playerID, flagNPC in mgr.playerFlagDict.items():
|
curPlayer = copyMapMgr.FindPlayerByID(playerID)
|
if not curPlayer:
|
# ÕÒ²»µ½Íæ¼Ò£¬Ö±½Ó¹é»¹Õ½Æì
|
setFlagOwner(flagNPC, None, tick)
|
continue
|
|
flagPosX, flagPosY = flagNPC.GetPosX(), flagNPC.GetPosY()
|
batPlayer = mgr.getBattlePlayer(playerID)
|
if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), flagPosX, flagPosY) <= outsideR:
|
batPlayer.outsideFlagTick = 0
|
batPlayer.outsideFlagNotifySecond = 0
|
else:
|
if not batPlayer.outsideFlagTick:
|
batPlayer.outsideFlagTick = tick
|
continue
|
passSeconds = (tick - batPlayer.outsideFlagTick) / 1000
|
if passSeconds < protectSeconds:
|
remainSecond = protectSeconds - passSeconds
|
if remainSecond != batPlayer.outsideFlagNotifySecond:
|
batPlayer.outsideFlagNotifySecond = remainSecond
|
PlayerControl.NotifyCode(curPlayer, "CrossFamilyFlagwarOutsideflag", [flagNPC.GetNPCID(), remainSecond])
|
continue
|
setFlagOwner(flagNPC, None, tick)
|
return
|
|
def setFlagOwner(flagNPC, newOwner, tick):
|
|
if not flagNPC:
|
return
|
|
ownerBuffDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 5, {})
|
|
flagNPCID = flagNPC.GetNPCID()
|
flagType = getFlagType(flagNPC)
|
if not flagType:
|
return
|
|
mgr = GetBattleMgr()
|
copyMapMgr = GameWorld.GetMapCopyPlayerManager()
|
GameWorld.DebugLog("ÉèÖÃÕ½Æì¹éÊô: flagNPCID=%s,flagType=%s" % (flagNPCID, flagType), mgr.zoneID)
|
|
for oldPlayerID, npc in mgr.playerFlagDict.items():
|
if not npc or flagNPCID != npc.GetNPCID():
|
continue
|
GameWorld.DebugLog(" ÒÆ³ý¾É¹éÊô: flagNPCID=%s,oldPlayerID=%s" % (flagNPCID, oldPlayerID), mgr.zoneID)
|
mgr.popPlayerFlag(oldPlayerID)
|
oldOwner = copyMapMgr.FindPlayerByID(oldPlayerID)
|
if oldOwner:
|
PlayerControl.NotifyCode(oldOwner, "CrossFamilyFlagwarFlagDrop", [flagNPCID])
|
# ɾ³ý¹éÊôbuff
|
for delBuffID in ownerBuffDict.values():
|
BuffSkill.DelBuffBySkillID(oldOwner, delBuffID, tick)
|
|
if newOwner:
|
newPlayerID = newOwner.GetPlayerID()
|
|
# ÒѾÓÐÕ½Æì£¬ÅжÏÕ½ÆìÀàÐÍ£¬¸ß¼¶¿ÉÌæ»»µÍ¼¶
|
if newPlayerID in mgr.playerFlagDict:
|
bodyFlagNPC = mgr.playerFlagDict[newPlayerID]
|
bodyFlagType = getFlagType(bodyFlagNPC)
|
bodyFlagNPCID = bodyFlagNPC.GetNPCID()
|
if bodyFlagType >= flagType:
|
GameWorld.DebugLog(" йéÊôÕßÒÑÓи߼¶Õ½Æì£¬±£ÁôÔ¹éÊô: bodyFlagNPCID=%s,bodyFlagType=%s >= flagType=%s"
|
% (bodyFlagNPCID, bodyFlagType, flagType), mgr.zoneID)
|
setFlagOwnerNone(flagNPC)
|
return
|
GameWorld.DebugLog(" йéÊôÕßÒÑÓеͼ¶Õ½Æì£¬Ïȹ黹Եͼ¶Õ½Æì: bodyFlagNPCID=%s,bodyFlagType=%s < flagType=%s"
|
% (bodyFlagNPCID, bodyFlagType, flagType), mgr.zoneID)
|
setFlagOwner(bodyFlagNPC, None, tick)
|
|
batPlayer = mgr.getBattlePlayer(newPlayerID)
|
batFamily = mgr.getBattleFamily(batPlayer.familyID)
|
|
batPlayer.outsideFlagTick = 0
|
mgr.setPlayerFlag(newPlayerID, flagNPC)
|
|
PlayerControl.NotifyCode(newOwner, "CrossFamilyFlagwarFlagOwn", [flagNPCID])
|
|
# ¹éÊô»ý·Ö
|
ownScoreDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 2, {})
|
ownPlayerScore, ownFamilyScore = ownScoreDict.get(flagType, [0, 0])
|
batPlayer.addPlayerScore(ownPlayerScore)
|
batFamily.addFamilyScore(ownFamilyScore)
|
|
# ¹éÊôbuff
|
ownerBuffID = ownerBuffDict.get(flagType, 0)
|
if ownerBuffID:
|
SkillCommon.AddBuffBySkillType_NoRefurbish(newOwner, ownerBuffID, tick)
|
|
flagNPC.SetVisible(False)
|
|
GameWorld.DebugLog(" ¸üÐÂйéÊô: flagNPCID=%s,newPlayerID=%s,ownerBuffID=%s" % (flagNPCID, newPlayerID, ownerBuffID), mgr.zoneID)
|
|
# ûÓÐйéÊô£¬¹é»¹Õ½Æì
|
else:
|
GameWorld.DebugLog(" ûÓÐйéÊô£¬¹é»¹Õ½Æì: flagNPCID=%s" % flagNPCID, mgr.zoneID)
|
setFlagOwnerNone(flagNPC)
|
|
return
|
|
def setFlagOwnerNone(flagNPC):
|
GameWorld.DebugLog(" setFlagOwnerNone: npcID=%s" % flagNPC.GetNPCID())
|
flagNPC.SetVisible(True)
|
return
|
|
def refreshCrossFamilyFlagwar(tick):
|
## Ë¢ÐÂÕ½³¡Ïà¹Ø
|
|
olPlayerScore, olFamilyScore = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarScore", 2) # Íæ¼ÒÔÚÕ½³¡Ê±Ã¿Ãë¹Ì¶¨»ñµÃ ¸öÈ˵÷Ö|ÏÉÃ˵÷Ö
|
flagTimeScoreDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 3, {})
|
|
mgr = GetBattleMgr()
|
|
copyMapMgr = GameWorld.GetMapCopyPlayerManager()
|
for familyID in mgr.battleFamilyDict.keys():
|
batFamily = mgr.getBattleFamily(familyID)
|
|
batFamily.battlePlayerSortList = []
|
|
safePosX, safePosY, safeRadius = batFamily.rebornPoint
|
for playerID in batFamily.battlePlayerIDList:
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batFamily.battlePlayerSortList.append(batPlayer)
|
|
curPlayer = copyMapMgr.FindPlayerByID(playerID)
|
if not curPlayer:
|
continue
|
onlineTimes = 0
|
# ÀۼƲÎÓëÕ½¶·Ê±³¤
|
if batPlayer.onlineCalcTick:
|
onlineTimes = max(0, tick - batPlayer.onlineCalcTick) / 1000
|
batPlayer.onlineCalcTick = tick
|
|
batPlayer.addPlayerScore(onlineTimes * olPlayerScore)
|
batFamily.addFamilyScore(onlineTimes * olFamilyScore)
|
|
# »ØÓªµØ
|
if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) <= safeRadius:
|
if playerID not in batFamily.homePlayerIDList:
|
batFamily.homePlayerIDList.append(playerID)
|
|
# Õ½Æì¶¨Ê±»ý·Ö
|
if playerID in mgr.playerFlagDict:
|
flagType = getFlagType(mgr.playerFlagDict[playerID])
|
ftPlayerScore, ftFamilyScore = flagTimeScoreDict.get(flagType, [0, 0])
|
|
batPlayer.addPlayerScore(onlineTimes * ftPlayerScore)
|
batFamily.addFamilyScore(onlineTimes * ftFamilyScore)
|
|
batFamily.sortBattlePlayerScore()
|
|
# ·Å×îºóÅÅÐò£¬ÉÏÃæµÄÂß¼¿ÉÄÜ»¹»á¼Ó·Ö
|
mgr.sortBattleFamilyScore()
|
return
|
|
def getFlagType(curNPC):
|
if not curNPC:
|
return 0
|
|
npcID = curNPC.GetNPCID()
|
flagTypeDict = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarFlag", 1, {})
|
for ft, npcIDList in flagTypeDict.items():
|
if npcID in npcIDList:
|
return ft
|
return 0
|
|
##ÊÇ·ñ¿ÉÒÔ¶áÆì
|
def OnCanCollect(curPlayer, curNPC, tick):
|
gameFB = GameWorld.GetGameFB()
|
fbStep = gameFB.GetFBStep()
|
|
# ·ÇÕ½¶·½×¶Î²»¿É²É¼¯
|
if fbStep != FB_Step_Fighting:
|
return False
|
|
playerID = curPlayer.GetPlayerID()
|
mgr = GetBattleMgr()
|
|
if playerID in mgr.playerFlagDict:
|
ownerFlagType = getFlagType(mgr.playerFlagDict[playerID])
|
if ownerFlagType >= getFlagType(curNPC):
|
GameWorld.Log("ÒѾӵÓиü¸ß¼¶µÄÕ½Æì£¬ÎÞ·¨²É¼¯! ownerFlagType=%s >= %s" % (ownerFlagType, getFlagType(curNPC)), playerID)
|
return False
|
|
return True
|
|
## ¿ªÊ¼²É¼¯
|
def OnBeginCollect(curPlayer, curNPC):
|
return
|
|
## Í˳ö²É¼¯
|
def OnExitCollect(curPlayer, curNPC):
|
#if not curNPC or not hasattr(curNPC, "GetNPCID"):
|
# return
|
return
|
|
##Íæ¼ÒÊÕ¼¯³É¹¦(Ëþ, Æì)
|
def OnCollectOK(curPlayer, npcID, tick):
|
#GameWorld.DebugLog("OnCollectOK npcID=%s" % npcID, curPlayer.GetPlayerID())
|
tagObj = curPlayer.GetActionObj()
|
if not tagObj:
|
return
|
if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:
|
return
|
|
curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())
|
#npcID = curNPC.GetNPCID()
|
flagType = getFlagType(curNPC)
|
AICommon.ClearPlayerPreparing(curNPC, curPlayer, "CrossFamilyFlagwarCollectOKSlow")
|
|
if flagType:
|
setFlagOwner(curNPC, curPlayer, tick)
|
|
return
|
|
## PVPÉ˺¦Ïà¹Ø
|
def OnPVPDamage(curPlayer, damageValue, tagPlayer, tick):
|
playerID = curPlayer.GetPlayerID()
|
|
mgr = GetBattleMgr()
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batPlayer.hurtTotal += damageValue
|
|
#GameWorld.DebugLog("OnPVPDamage: damageValue=%s,hurtTotal=%s" % (damageValue, batPlayer.hurtTotal), playerID)
|
return
|
|
##´¦Àí¸±±¾ÖÐɱËÀÍæ¼ÒÂß¼
|
def DoFBOnKill_Player(curPlayer, defender, tick):
|
playerID = curPlayer.GetPlayerID()
|
defPlayerID = defender.GetPlayerID()
|
#GameWorld.DebugLog("DoFBOnKill_Player playerID=%s,defPlayerID=%s" % (playerID, defPlayerID))
|
|
mgr = GetBattleMgr()
|
|
killPlayerScore, killFamilyScore = IpyGameDataPY.GetFuncEvalCfg("CrossFamilyFlagwarScore", 1) # »÷É±Íæ¼Ò ¸öÈ˵÷Ö|ÏÉÃ˵÷Ö
|
batPlayer = mgr.getBattlePlayer(playerID)
|
batFamily = mgr.getBattleFamily(batPlayer.familyID)
|
|
batPlayer.addPlayerScore(killPlayerScore)
|
batFamily.addFamilyScore(killFamilyScore)
|
|
# »ñµÃ¶Ô·½Õ½Æì¹éÊô
|
if defPlayerID in mgr.playerFlagDict:
|
setFlagOwner(mgr.playerFlagDict[defPlayerID], curPlayer, tick)
|
return True
|
|
def OnCanFBReborn(curPlayer, rebornType):
|
playerID = curPlayer.GetPlayerID()
|
if rebornType == ChConfig.rebornType_Health:
|
mgr = GetBattleMgr()
|
playerID = curPlayer.GetPlayerID()
|
batPlayer = mgr.getBattlePlayer(playerID)
|
|
healthRebornMax = IpyGameDataPY.GetFuncCfg("CrossFamilyFlagwarReborn", 1)
|
if healthRebornMax and batPlayer.healthRebornCount >= healthRebornMax:
|
GameWorld.Log("ÒÑ´ïԵؽ¡¿µ¸´»î´ÎÊýÉÏÏÞ! playerID=%s" % playerID, mgr.zoneID)
|
return False
|
|
return True
|
|
def OnPlayerReborn():
|
## ÊÇ·ñ¸±±¾¸´»î
|
return True
|
|
## Íæ¼Ò¸´»îºó´¦Àí
|
def OnPlayerRebornOver(curPlayer, rebornType):
|
mgr = GetBattleMgr()
|
playerID = curPlayer.GetPlayerID()
|
batPlayer = mgr.getBattlePlayer(playerID)
|
|
if rebornType == ChConfig.rebornType_Health:
|
batPlayer.addHealthRebornCount()
|
else:
|
# ·ÇÔµØ
|
batFamily = mgr.getBattleFamily(curPlayer.GetFamilyID())
|
batFamily.setPlayerToRebornPoint(curPlayer)
|
|
batPlayer.continueKillCount = 0 # ÖжÏÁ¬É±Êý
|
|
FBCommon.Notify_FBHelp(curPlayer, batPlayer.getPlayerHelpInfo(False))
|
return
|
|
def DoOver(tick):
|
|
mgr = GetBattleMgr()
|
zoneID = mgr.zoneID
|
|
gameFB = GameWorld.GetGameFB()
|
gameWorld = GameWorld.GetGameWorld()
|
copyMapID = gameWorld.GetCopyMapID()
|
|
fbStep = gameFB.GetFBStep()
|
if fbStep > FB_Step_Fighting:
|
GameWorld.ErrLog("¿ç·þÏÉÃ˶áÆìÕ½´¥·¢Öظ´½áË㣬²»´¦Àí£¡ zoneID=%s,copyMapID=%s" % (mgr.zoneID, copyMapID), zoneID)
|
return
|
FBCommon.SetFBStep(FB_Step_LeaveTime, tick)
|
|
GameWorld.Log("¿ç·þÏÉÃ˶áÆìÕ½½áË㣡 zoneID=%s,copyMapID=%s" % (mgr.zoneID, copyMapID), zoneID)
|
|
refreshCrossFamilyFlagwar(tick) # ½áËãǰǿˢһ´Î
|
NotifyCrossFamilyFlagHelp(True)
|
|
leaveTime = GetBFStepTime()[Time_Leave] * 1000
|
|
copyMapMgr = GameWorld.GetMapCopyPlayerManager()
|
|
drDict = {"mapID":GameWorld.GetMap().GetMapID(), "realMapID":gameWorld.GetRealMapID(), "copyMapID":copyMapID, "zoneID":zoneID}
|
drBatFamilyList = []
|
|
battleFamilyList = []
|
for familyRank, batFamily in enumerate(mgr.battleFamilySortList, 1):
|
familyID = batFamily.familyID
|
#batFamily = mgr.getBattleFamily(familyID)
|
familyScore = batFamily.score
|
familyName = batFamily.name
|
GameWorld.Log("familyRank=%s,familyID=%s,familyScore=%s" % (familyRank, familyID, familyScore), zoneID)
|
|
overPlayerList = [] # ͬ²½Ç°¶Ë½áËã
|
drPlayerList = [] # Á÷Ïò¼Ç¼
|
battlePlayerList = [] # ͬ²½GameServer½áËã
|
|
for playerRank, batPlayer in enumerate(batFamily.battlePlayerSortList, 1):
|
playerID = batPlayer.playerID
|
#batPlayer = mgr.getBattlePlayer(playerID)
|
|
score = batPlayer.score
|
#job = batPlayer.job
|
#realmLV = batPlayer.realmLV
|
name = batPlayer.name
|
|
hurtTotal = batPlayer.hurtTotal
|
|
GameWorld.Log(" familyID=%s,playerRank=%s,playerID=%s,score=%s,hurtTotal=%s,accID=%s"
|
% (familyID, playerRank, playerID, score, hurtTotal, batPlayer.accID), zoneID)
|
|
overPlayerList.append([name, score])
|
battlePlayerList.append([playerID, score, hurtTotal])
|
drPlayerList.append({"playerID":playerID, "accID":batPlayer.accID, "playerRank":playerRank, "score":score, "hurtTotal":hurtTotal})
|
|
overDict = {"familyScore":familyScore, "familyRank":familyRank, "playerList":overPlayerList}
|
for playerRank, batPlayer in enumerate(batFamily.battlePlayerSortList, 1):
|
playerID = batPlayer.playerID
|
player = copyMapMgr.FindPlayerByID(playerID)
|
if not player:
|
continue
|
player.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTime, True)
|
|
lineID = 0
|
overDict.update({"familyScore":familyScore, "familyRank":familyRank})
|
FBCommon.NotifyFBOver(player, ChConfig.Def_FBMapID_CrossFamilyFlagwar, lineID, True, overDict)
|
|
battleFamilyList.append([familyRank, familyID, familyName, familyScore, battlePlayerList])
|
drBatFamilyList.append({"familyID":familyID, "familyScore":familyScore, "familyRank":familyRank, "drPlayerList":drPlayerList})
|
|
# ͬ²½GameServer ±ÈÈü½á¹û
|
msgInfo = str([zoneID, battleFamilyList])
|
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossFamilyFlagwarOver", msgInfo, len(msgInfo))
|
|
# ¼Ç¼Á÷Ïò
|
drDict["batFamilyList"] = drBatFamilyList
|
DataRecordPack.SendEventPack("CrossFamilyFlagwarOver", drDict)
|
return
|
|
|
|