#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package Player.PlayerOnline
|
#
|
# @todo:ÔÚÏßÍæ¼Ò¹ÜÀí
|
# @author hxp
|
# @date 2025-07-02
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: ÔÚÏßÍæ¼Ò¹ÜÀí£¬ÓÃÓÚ¹ÜÀíÔÚÏßÍæ¼Ò¡¢×¼ÔÚÏßÍæ¼ÒµÄÁÙʱÊý¾Ý£¬ÖضÁ²»»á±»ÖØÖÃ
|
# ×¼ÔÚÏßÍæ¼Ò - ʵ¼Ê²»ÔÚÏߣ¬x·ÖÖÓÄÚÀëÏßµÄÍæ¼Ò£¬ÓÃÓÚÖ§³Ö¶ÏÏßÖØÁ¬£¬¶Ìʱ¼äÄÚÁÙʱÊý¾Ý¿É³ÖÐø
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-07-02 17:30"""
|
#-------------------------------------------------------------------------------
|
|
import TurnAttack
|
import PyGameData
|
import ShareDefine
|
import PlayerControl
|
import IpyGameDataPY
|
import FormulaControl
|
import PlayerHero
|
import GameWorld
|
import ChConfig
|
import ChEquip
|
|
import time
|
|
class LineupHero():
|
## ÕóÈÝÕ½¶·Î佫£¬×¢Ò⣺ͬһ¸öÎ佫ÔÚ²»Í¬ÕóÈÝÖпÉÄÜÊôÐÔ²»Ò»Ñù
|
|
def __init__(self):
|
self.Clear()
|
return
|
|
def Clear(self):
|
self.itemIndex = 0
|
self.heroID = 0
|
self.posNum = 0
|
self.heroBatAttrDict = {} # Î佫µÄ×îÖÕÕ½¶·ÊôÐÔ×ֵ䣬 {attrID:value, ...}
|
self.heroSkillIDList = [] # Î佫ӵÓеļ¼ÄÜIDÁбí [skillID, ...]
|
self.fightPower = 0 # Î佫×îÖÕÕ½Á¦
|
self.skillFightPower = 0 # ¼¼ÄÜÕ½Á¦
|
return
|
|
class Lineup():
|
## ÕóÈÝ
|
|
def __init__(self, playerID, lineupID):
|
self.playerID = playerID
|
self.lineupID = lineupID
|
self.olPlayer = None
|
self.shapeType = 0
|
self.heroItemDict = {} # ÕóÈÝÎ佫±³°üË÷ÒýÐÅÏ¢ {itemIndex:posNum, ...}
|
self.__refreshState = 0 # Ë¢ÊôÐÔ±ê¼Ç£¬ 0-²»ÐèҪˢÐÂÁË£¬1-ÐèҪˢÐÂ
|
|
self.__freeLineupHeroObjs = [] # ÊͷŵĿÕÏжÔÏó[LineupHero, ...]
|
self.lineupHeroDict = {} # ÕóÈÝÎ佫 {posNum:LineupHero, ...}
|
self.fightPower = 0 # ÕóÈÝ×ÜÕ½Á¦
|
return
|
|
def UpdLineup(self, heroItemDict, shapeType=0, refreshForce=False):
|
'''±ä¸üÕóÈÝʱ¸üÐÂ
|
@param heroItemDict: Î佫±³°üË÷ÒýÐÅÏ¢ {itemIndex:posNum, ...}
|
@param shapeType: ÕóÐÍ
|
@param refreshForce: ÊÇ·ñÇ¿ÖÆË¢ÊôÐÔ
|
'''
|
self.shapeType = shapeType
|
self.heroItemDict = heroItemDict
|
GameWorld.DebugLog("¸üÐÂÕóÈÝ: lineupID=%s,%s" % (self.lineupID, heroItemDict), self.playerID)
|
self.RefreshLineupAttr(refreshForce)
|
return
|
|
def FreeLineupHero(self):
|
## ÊÍ·ÅÕóÈÝÎ佫¶ÔÏó£¬ÖØÐ¼ÆËã
|
for freeObj in self.lineupHeroDict.values():
|
if freeObj not in self.__freeLineupHeroObjs:
|
self.__freeLineupHeroObjs.append(freeObj)
|
self.lineupHeroDict = {}
|
self.fightPower = 0
|
return
|
|
def GetLineupHero(self, posNum):
|
lineupHero = None
|
if posNum in self.lineupHeroDict:
|
lineupHero = self.lineupHeroDict[posNum]
|
elif self.__freeLineupHeroObjs:
|
lineupHero = self.__freeLineupHeroObjs.pop(0)
|
lineupHero.Clear()
|
self.lineupHeroDict[posNum] = lineupHero
|
else:
|
lineupHero = LineupHero()
|
self.lineupHeroDict[posNum] = lineupHero
|
return lineupHero
|
|
def GetLineupHeroByID(self, heroID):
|
for posNum in self.lineupHeroDict.keys():
|
lineup = self.GetLineupHero(posNum)
|
if lineup.heroID == heroID:
|
return lineup
|
return
|
|
def GetLineupInfo(self):
|
## »ñÈ¡ÕóÈÝÐÅÏ¢£¬¼´ÒªÓõ½¸ÃÕóÈÝÁË£¬ÈçÕ½¶·»òÕß±£´æ»º´æÐÅÏ¢µÈ
|
self.DoRefreshLineupAttr() # È¡ÕóÈÝʱÏȼì²é
|
return
|
|
def SetNeedRefreshState(self):
|
## ÉèÖÃÐèҪˢÊôÐÔ
|
self.__refreshState = 1
|
return
|
|
def RefreshLineupAttr(self, refreshForce=False):
|
self.__refreshState = 1 # ±ê¼ÇҪˢÐÂ
|
if refreshForce:
|
self.DoRefreshLineupAttr()
|
return
|
|
def DoRefreshLineupAttr(self):
|
if not self.__refreshState:
|
return False
|
doRefreshLineupAttr(self.olPlayer.curPlayer, self.olPlayer, self)
|
self.__refreshState = 0
|
return True
|
|
def CheckHeroItemUpdate(self, itemIndex):
|
if itemIndex not in self.heroItemDict:
|
return
|
self.RefreshLineupAttr()
|
return True
|
|
class OnlinePlayer():
|
## Íæ¼ÒÔÚÏßÁÙʱÊý¾Ý£¬Ö÷ҪʱÊý¾ÝµÄ»º´æ£¬Âß¼¿É²»ÔÚÀàÖд¦Àí£¬·½±ãÖØ¶Á½Å±¾Ê±²âÊÔ
|
|
def __init__(self, playerID):
|
self.playerID = playerID
|
self.curPlayer = None
|
|
# ÊôÐÔ¡¢ÕóÈÝ
|
self.calcAttrDict = {} # ·ÇÎ佫¹¦ÄܵãÊôÐÔͳ¼Æ {calcIndex:{attrID:value, ...}, ...}
|
self.lineupDict = {} # ÉÏÕóÕóÈÝ {lineupID:Lineup, ...}
|
|
# Ö÷ÏßÕ½¶·
|
self.mainFight = TurnAttack.MainFight(playerID)
|
return
|
|
def OnClear(self):
|
self.mainFight.clear()
|
return
|
|
def SetPlayer(self, curPlayer):
|
self.curPlayer = curPlayer
|
self.mainFight.turnFight.curPlayer = curPlayer
|
return
|
|
def IsRealOnline(self):
|
## ÊÇ·ñÕæµÄÔÚÏß
|
return self.curPlayer != None
|
|
def GetLineup(self, lineupID):
|
lineup = None
|
if lineupID in self.lineupDict:
|
lineup = self.lineupDict[lineupID]
|
else:
|
lineup = Lineup(self.playerID, lineupID)
|
self.lineupDict[lineupID] = lineup
|
lineup.olPlayer = self
|
return lineup
|
|
def GetCalcAttr(self, calcIndex): return self.calcAttrDict.get(calcIndex, {})
|
def SetCalcAttr(self, calcIndex, attrDict):
|
## ÉèÖÃij¸ö¹¦ÄÜµã¼ÆËãµÄÊôÐÔ
|
self.calcAttrDict[calcIndex] = attrDict
|
return
|
|
def ReCalcAllAttr(self):
|
## ÖØÖÃËùÓй¦ÄÜµã¼ÆËãµÄÊôÐÔ£¬Ò»°ãµÇ¼µÄʱºòµ÷ÓÃÒ»´Î¼´¿É£¬ÆäËûµ¥¹¦ÄÜË¢ÐµĻ°Ò»°ãʹÓà RefreshRoleAttr
|
curPlayer = self.curPlayer
|
GameWorld.DebugLog("ReCalcAllAttr...", self.playerID)
|
|
self.calcAttrDict = {}
|
self.lineupDict = {}
|
|
doCalcAllAttr(curPlayer)
|
doReloadLineup(curPlayer, self)
|
|
self.RefreshRoleAttr()
|
return
|
|
def RefreshRoleAttr(self, refreshForce=False, isAllLineup=False):
|
'''Ë¢ÐÂÖ÷¹«ÊôÐÔ£¬Ó°ÏìÖ÷¹«ÊôÐԵŦÄܵãÊôÐԱ仯ʱͳһµ÷Óô˺¯Êý
|
@param refreshForce: ÊÇ·ñÇ¿ÖÆÁ¢ÂíË¢ÐÂ
|
@param isAllLineup: ÊÇ·ñֻͬ²½Ë¢ËùÓÐÕóÈÝÊôÐÔ£¬Èç¹ûÉèÖÃFalseÔòĬÈϽöË¢Ö÷ÕóÈÝÊôÐÔ
|
'''
|
GameWorld.DebugLog("ÇëÇóË¢ÊôÐÔ: refreshForce=%s" % (refreshForce), self.playerID)
|
# Ö÷¹«ÊôÐÔË¢ÐÂʱ£¬ËùÓÐÕóÈݶ¼ÒªÍ¬²½Ë¢ÐÂ
|
for lineup in self.lineupDict.values():
|
lineup.SetNeedRefreshState()
|
|
if refreshForce:
|
self.DoRefreshRoleAttr(isAllLineup)
|
return
|
|
def DoRefreshRoleAttr(self, isAllLineup=False):
|
'''Ö´ÐÐË¢ÊôÐÔ£¬Ä¬È϶îÍâË¢Ö÷ÕóÈÝ£¬ÆäËûÕóÈÝ¿ÉÒÔÓõ½µÄʱºòÔÙË¢ÐÂ
|
@param isAllLineup: ÊÇ·ñË¢ËùÓÐÕóÈÝ£¬Èç¹ûÉèÖÃFalseÔòĬÈϽöË¢Ö÷ÕóÈÝÊôÐÔ
|
@return: ÊÇ·ñÓÐË¢ÊôÐÔ£¬0-ÎÞ£»1-ÓÐ
|
'''
|
|
isRefresh = False
|
# ͬ²½Ö´ÐÐÕóÈÝÊôÐÔË¢ÐÂ
|
for lineupID, lineup in self.lineupDict.items():
|
if not isAllLineup and lineupID != ShareDefine.Lineup_Main:
|
continue
|
if lineup.DoRefreshLineupAttr():
|
isRefresh = True
|
|
return isRefresh
|
|
def OnHeroItemUpate(self, itemIndexList):
|
'''Î佫ÎïÆ·Ñø³É¸üÐÂ
|
@param itemIndexList: ±ä»¯Î佫ÎïÆ·ËùÔÚÎ佫±³°ü¸ñ×ÓË÷ÒýÁбí
|
@param return: Ó°ÏìµÄÕóÈÝIDÁбí
|
'''
|
effLineupIDList = []
|
|
for lineupID, lineup in self.lineupDict.items():
|
for itemIndex in itemIndexList:
|
if lineup.CheckHeroItemUpdate(itemIndex):
|
if lineupID not in effLineupIDList:
|
effLineupIDList.append(lineupID)
|
|
GameWorld.DebugLog("Î佫ÎïÆ·Ñø³É¸üÐÂË÷Òý: %s, Ó°ÏìÕóÈÝ:%s" % (itemIndexList, effLineupIDList), self.playerID)
|
return effLineupIDList
|
|
class OnlineMgr():
|
## ×¼ÔÚÏßÍæ¼Ò¹ÜÀí
|
|
def __init__(self):
|
self.__onlinePlayerDict = {} # ×¼ÔÚÏßÍæ¼ÒÁÙʱÊý¾Ý×Öµä {playerID:OnlinePlayer, ...}
|
self.__offlinePlayerTimeDict = {} # ×¼ÔÚÏßÍæ¼ÒÁÙʱÀëÏßʱ¼ä´Á {playerID:ÀëÏßʱ¼ä´Á, ...}
|
return
|
|
def GetOnlinePlayer(self, curPlayer):
|
olPlayer = None
|
playerID = curPlayer.GetPlayerID()
|
if playerID in self.__onlinePlayerDict:
|
olPlayer = self.__onlinePlayerDict[playerID]
|
else:
|
olPlayer = OnlinePlayer(playerID)
|
self.__onlinePlayerDict[playerID] = olPlayer
|
olPlayer.SetPlayer(curPlayer)
|
return olPlayer
|
|
def SetPlayerOnline(self, curPlayer):
|
## ÉèÖÃÍæ¼ÒÔÚÏß
|
playerID = curPlayer.GetPlayerID()
|
self.__offlinePlayerTimeDict.pop(playerID, None)
|
if playerID not in self.__onlinePlayerDict:
|
olPlayer = OnlinePlayer(playerID)
|
self.__onlinePlayerDict[playerID] = olPlayer
|
else:
|
olPlayer = self.__onlinePlayerDict[playerID]
|
olPlayer.SetPlayer(curPlayer)
|
return
|
|
def SetPlayerOffline(self, curPlayer):
|
## ÉèÖÃÍæ¼ÒÀëÏß
|
playerID = curPlayer.GetPlayerID()
|
if playerID not in self.__onlinePlayerDict:
|
return
|
olPlayer = self.__onlinePlayerDict[playerID]
|
olPlayer.SetPlayer(None)
|
self.__offlinePlayerTimeDict[playerID] = int(time.time())
|
return
|
|
def ProcessOffline(self):
|
## ¶¨Ê±´¦ÀíÀëÏßÍæ¼Ò
|
curTime = int(time.time())
|
offlineTimes = 5 * 60 # 5·ÖÖÓºóÇå³ýÊý¾Ý
|
for playerID, offlineTime in self.__offlinePlayerTimeDict.items():
|
if curTime - offlineTime < offlineTimes:
|
continue
|
self.__offlinePlayerTimeDict.pop(playerID, None)
|
if playerID not in self.__onlinePlayerDict:
|
continue
|
olPlayer = self.__onlinePlayerDict.pop(playerID, None)
|
olPlayer.OnClear()
|
return
|
|
def GetOnlineMgr():
|
mgr = None
|
if PyGameData.g_onlineMgr:
|
mgr = PyGameData.g_onlineMgr
|
else:
|
mgr = OnlineMgr()
|
PyGameData.g_onlineMgr = mgr
|
return mgr
|
|
def GetOnlinePlayer(curPlayer): return GetOnlineMgr().GetOnlinePlayer(curPlayer)
|
|
def OnPlayerLogin(curPlayer):
|
## ÐèµÇ¼Âß¼×îÔçµ÷ÓÃ
|
GetOnlineMgr().SetPlayerOnline(curPlayer)
|
return
|
|
def OnPlayerLogoff(curPlayer):
|
## ÐèÏÂÏßÂß¼×îºóµ÷ÓÃ
|
GetOnlineMgr().SetPlayerOffline(curPlayer)
|
return
|
|
def OnMinute():
|
GetOnlineMgr().ProcessOffline()
|
return
|
|
def CalcRoleBase(curPlayer):
|
playerID = curPlayer.GetID()
|
playerLV = curPlayer.GetLV()
|
lvIpyData = PlayerControl.GetPlayerLVIpyData(playerLV)
|
|
lvAttrDict = {}
|
if lvIpyData:
|
lvAttrDict = {ChConfig.AttrID_Atk:lvIpyData.GetAtk(),
|
ChConfig.AttrID_Def:lvIpyData.GetDef(),
|
ChConfig.AttrID_MaxHP:lvIpyData.GetMaxHP()
|
}
|
|
GameWorld.DebugLog("½ÇÉ«µÈ¼¶ÊôÐÔ: %s" % lvAttrDict, playerID)
|
GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_LV, lvAttrDict)
|
return
|
|
def doReloadLineup(curPlayer, olPlayer):
|
## ÖØÐÂÔØÈëÕóÈÝ
|
loadLineupIDList = ShareDefine.LineupList
|
lineupDict = {} # {ÕóÈÝID:{itemIndex:posNum, ...}, ...}
|
lineShapeTypeDict = {} # {ÕóÈÝID:ÕóÐÍ, ...}
|
syncItemDict = {} # ÐèҪͬ²½µÄÒì³£ÎïÆ· {index:heroItem, ...}
|
curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
|
for index in range(curPack.GetCount()):
|
heroItem = curPack.GetAt(index)
|
if not heroItem or heroItem.IsEmpty():
|
continue
|
lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
|
if not lineupCount:
|
continue
|
delValueList = []
|
for lpIndex in range(lineupCount)[::-1]:
|
lineupValue = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
|
lineupID, shapeType, posNum = PlayerHero.GetLineupValue(lineupValue)
|
if lineupID not in loadLineupIDList:
|
continue
|
# ÈÎÒâȡһ¸öÎ佫±£´æµÄÕóÐͼ´¿É£¬Í¬ÕóÈݵÄÎ佫ÀíÂÛÉϱ£´æµÄÕóÐÍÊÇÒ»ÑùµÄ
|
if lineupID not in lineShapeTypeDict:
|
lineShapeTypeDict[lineupID] = shapeType
|
if lineupID not in lineupDict:
|
lineupDict[lineupID] = {}
|
heroItemDict = lineupDict[lineupID]
|
|
# ³¬³öÈËÊýÏÞÖÆ»òλÖÃÒì³£
|
if len(heroItemDict) >= ShareDefine.LineupObjMax or posNum in heroItemDict.values() or index in heroItemDict:
|
delValueList.append(lineupValue)
|
else:
|
heroItemDict[index] = posNum
|
|
if delValueList:
|
item = heroItem.GetItem()
|
for lineupValue in delValueList:
|
item.DelUserAttr(ShareDefine.Def_IudetHeroLineup, lineupValue)
|
syncItemDict[index] = heroItem
|
|
for syncItem in syncItemDict.values():
|
syncItem.Sync_Item()
|
|
GameWorld.DebugLog("ÖØÔØÕóÈÝ: %s" % lineupDict, curPlayer.GetPlayerID())
|
for lineupID, heroItemDict in lineupDict.items():
|
lineup = olPlayer.GetLineup(lineupID)
|
|
# »ñÈ¡ÆäËû°ó¶¨¸ÃÕóÈݵŦÄÜ£¬ÈçºìÑÕ¡¢ÁéÊÞµÈ
|
|
shapeType = lineShapeTypeDict.get(lineupID, 0)
|
lineup.UpdLineup(heroItemDict, shapeType)
|
|
return
|
|
def doCalcAllAttr(curPlayer):
|
## ¼ÆËãËùÓÐÊôÐÔ
|
GameWorld.DebugLog("doCalcAllAttr...", curPlayer.GetPlayerID())
|
CalcRoleBase(curPlayer)
|
ChEquip.CalcRoleEquipAttr(curPlayer)
|
PlayerHero.CalcHeroAddAttr(curPlayer)
|
return
|
|
def doRefreshLineupAttr(curPlayer, olPlayer, lineup):
|
''' Ë¢ÐÂij¸öÕóÈÝÊôÐÔ
|
»ù´¡ÊôÐÔ-Ãæ°åÏÔʾ£º
|
1.È«Ìå»ù´¡¹Ì¶¨Öµ=ËùÓд©´÷×°±¸¡¾×°±¸»ù´¡¹Ì¶¨Öµ¡¿+¡¾·¨±¦»ù´¡¹Ì¶¨Öµ¡¿+¡¾ºìÑÕ»ù´¡¹Ì¶¨Öµ¡¿+¡¾ÆäËüÄ£¿éµÄ¹Ì¶¨Öµ¡¿
|
2.È«Ìå°Ù·Ö±È¼Ó³É=ͼ¼ø¼Ó³É+¡¾ÁéÊÞÄ£¿é¡¿+¡¾ºìÑÕÄ£¿é¡¿+¡¾ÆäËüÄ£¿é¡¿+ËùÓÐÉÏÕó¿¨ÅÆ¡¾³õʼ¼Ó³É+Éý¼¶¼Ó³É+Í»ÆÆ¼Ó³É+ÍÌÊɼӳɡ¿
|
3.¿¨ÅƼ̳бÈÀý=¿¨ÅÆÆ·Öʼ°Ö°Òµ¼Ì³Ð±ÈÀý²»Í¬
|
4.¿¨ÅÆ×ÔÉíÅàÑø¼Ó³É=¡¾î¿°í¼Ó³É%+Í»ÆÆ´ÊÌõ¼Ó³É%+Ì츳¼Ó³É%¡¿
|
×îÖÕÃæ°åÉúÃü=¡¾EÈ«Ìå»ù´¡¹Ì¶¨Öµ¡¿*¡¾1+EÈ«Ìå°Ù·Ö±È¼Ó³É¡¿*¡¾¿¨ÅÆ×ÔÉí¼Ì³Ð±ÈÀý+ ¿¨ÅÆ×ÔÉíÅàÑø%¼Ó³É¡¿+¡¾¿¨ÅÆ×ÔÉí¹Ì¶¨Öµ¡¿
|
|
Õ½¶·ÊôÐÔ/Õ½¶·¿¹ÐÔ/ÌØÊâÊôÐÔ-Ãæ°åÏÔʾ£º
|
1.È«ÌåÕ½¶·ÊôÐÔÖµ=ËùÓд©´÷×°±¸¡¾×°±¸Õ½¶·ÊôÐÔÖµ¡¿+¡¾·¨±¦Õ½¶·ÊôÐÔÖµ¡¿+¡¾ºìÑÕÕ½¶·ÊôÐÔÖµ¡¿+¡¾ÆäËüÄ£¿éµÄÕ½¶·ÊôÐÔ¡¿
|
2.¿¨ÅƼ̳бÈÀý=ĬÈÏ100%
|
3.¿¨ÅÆ×ÔÉíÅàÑøÕ½¶·ÊôÐÔ=¡¾¿¨ÅƳõʼս¶·ÊôÐÔ+Í»ÆÆ´ÊÌõÕ½¶·ÊôÐÔ+Ì츳ս¶·ÊôÐÔ+¾õÐÑÕ½¶·ÊôÐÔ¡¿+¡¾·¨ÔòÏ´Á¶¡¿+¡¾ÃØÄÜ×°±¸¡¿+¡¾ÆäËüÄ£¿é¡¿
|
×îÖÕÃæ°åÕ½¶·ÊôÐÔ=¡¾EÈ«ÌåÕ½¶·ÊôÐÔÖµ¡¿*¡¾¿¨ÅƼ̳бÈÀý¡¿+¡¾¿¨ÅÆ×ÔÉíÅàÑøÕ½¶·ÊôÐÔ¡¿
|
'''
|
playerID = curPlayer.GetPlayerID()
|
lineupID = lineup.lineupID
|
|
GameWorld.DebugLog("Ë¢ÐÂÕóÈÝÊôÐÔ: lineupID=%s" % lineupID, playerID)
|
GameWorld.DebugLog(" itemIndex-posNum : %s" % lineup.heroItemDict, playerID)
|
|
lineup.FreeLineupHero()
|
|
# ÒòΪͬÕóÈݵÄÎ佫ID²»ÄÜÖØ¸´£¬ËùÒÔ×Öµäkey¿ÉÒÔÓÃÎ佫ID
|
countryHeroInfo = {} # ¹ú¼ÒÎ佫ͳ¼Æ {country:[heroID, ...], ...}
|
fetterHeroInfo = {} # ÕóÈÝî¿°íÎ佫ͳ¼ÆÐÅÏ¢ {fetterID:[heroID, ...], ...}
|
heroSelfAttrInfo = {} # Î佫×ÔÉíÊôÐÔ {heroID:{attrID:value, ...}, ...}
|
heroStarTalentInfo = {} # Î佫ÐǼ¶Ì츳ÊôÐÔ {heroID:{attrID:value, ...}, ...}
|
heroBreakAttrInfo = {} # Îä½«Í»ÆÆÇ±ÄÜÊôÐÔ {heroID:{attrID:value, ...}, ...}
|
heroAwakeTalentInfo = {} # Î佫¾õÐÑÌ츳ÊôÐÔ {heroID:{attrID:value, ...}, ...}
|
|
# ÉÏÕó¿¨ÅÆ¡¾³õʼ¼Ó³É+Éý¼¶¼Ó³É+Í»ÆÆ¼Ó³É+ÍÌÊɼӳɡ¿
|
InitAddPer, LVAddPer, BreakLVAddPer, StarAddPer = 0, 0, 0, 0
|
|
curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
|
for itemIndex, posNum in lineup.heroItemDict.items():
|
if itemIndex < 0 or itemIndex >= curPack.GetCount():
|
continue
|
heroItem = curPack.GetAt(itemIndex)
|
if not heroItem or heroItem.IsEmpty():
|
continue
|
heroID = heroItem.GetItemTypeID()
|
heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
if not heroIpyData:
|
continue
|
quality = heroIpyData.GetQuality()
|
qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
|
if not qualityIpyData:
|
continue
|
|
heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
|
star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
|
breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
|
awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
|
|
InitAddPer += qualityIpyData.GetInitAddPer()
|
LVAddPer += qualityIpyData.GetLVAddPer() * heroLV
|
BreakLVAddPer += qualityIpyData.GetBreakLVAddPer() * breakLV
|
StarAddPer += qualityIpyData.GetStarAddPer() * star
|
|
lineupHero = lineup.GetLineupHero(posNum)
|
#if False:
|
# lineupHero = LineupHero()
|
lineupHero.itemIndex = itemIndex
|
lineupHero.posNum = posNum
|
lineupHero.heroID = heroID
|
lineupHero.heroBatAttrDict = {}
|
lineupHero.heroSkillIDList = []
|
lineupHero.fightPower = 0
|
|
normalSkillID = heroIpyData.GetNormalSkillID()
|
angerSkillID = heroIpyData.GetAngerSkillID()
|
lineupHero.heroSkillIDList.extend([normalSkillID, angerSkillID])
|
|
# ×ÔÉíÊôÐÔ
|
selfAttrDict = {}
|
selfAttrDict.update({ChConfig.AttrID_AtkInheritPer:heroIpyData.GetAtkInheritPer(),
|
ChConfig.AttrID_DefInheritPer:heroIpyData.GetDefInheritPer(),
|
ChConfig.AttrID_HPInheritPer:heroIpyData.GetHPInheritPer(),
|
})
|
for k, v in heroIpyData.GetBatAttrDict().items():
|
selfAttrDict[int(k)] = v
|
heroSelfAttrInfo[heroID] = selfAttrDict
|
|
# ÐǼ¶Ì츳
|
starTalentAttrDict = {}
|
idCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID)
|
lvCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDLV)
|
for aIndex in range(min(idCount, lvCount)):
|
talentID = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, aIndex)
|
talentLV = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentIDLV, aIndex)
|
stIpyData = IpyGameDataPY.GetIpyGameData("HeroTalent", talentID)
|
if not stIpyData:
|
continue
|
attrID = stIpyData.GetAttrID()
|
attrValue = stIpyData.GetAttrValue() * talentLV
|
starTalentAttrDict[attrID] = starTalentAttrDict.get(attrID, 0) + attrValue
|
heroStarTalentInfo[heroID] = starTalentAttrDict
|
|
# Í»ÆÆÇ±ÄÜ
|
breakAttrDict = {}
|
awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroBreak", heroID)
|
if awakeIpyDataList:
|
for breakIpyData in awakeIpyDataList:
|
if breakIpyData.GetBreakLV() > breakLV:
|
break
|
attrIDList = breakIpyData.GetAttrIDList()
|
attrValueList = breakIpyData.GetAttrValueList()
|
for aIndex in range(min(len(attrIDList), len(attrValueList))):
|
attrID = attrIDList[aIndex]
|
attrValue = attrValueList[aIndex]
|
breakAttrDict[attrID] = breakAttrDict.get(attrID, 0) + attrValue
|
skillID = breakIpyData.GetSkillID()
|
if skillID:
|
lineupHero.heroSkillIDList.append(skillID)
|
heroBreakAttrInfo[heroID] = breakAttrDict
|
|
# ¾õÐÑÌ츳
|
awakeTalentAttrDict = {}
|
awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID)
|
if awakeIpyDataList:
|
for awakeIpyData in awakeIpyDataList:
|
if awakeIpyData.GetAwakeLV() > awakeLV:
|
break
|
attrIDList = awakeIpyData.GetAttrIDList()
|
attrValueList = awakeIpyData.GetAttrValueList()
|
for aIndex in range(min(len(attrIDList), len(attrValueList))):
|
attrID = attrIDList[aIndex]
|
attrValue = attrValueList[aIndex]
|
awakeTalentAttrDict[attrID] = awakeTalentAttrDict.get(attrID, 0) + attrValue
|
skillID = awakeIpyData.GetSkillID()
|
if skillID:
|
lineupHero.heroSkillIDList.append(skillID)
|
heroAwakeTalentInfo[heroID] = awakeTalentAttrDict
|
|
# î¿°íͳ¼Æ
|
for fetterID in heroIpyData.GetFetterIDList():
|
if fetterID not in fetterHeroInfo:
|
fetterHeroInfo[fetterID] = []
|
fetterHeroIDList = fetterHeroInfo[fetterID]
|
if heroID not in fetterHeroIDList:
|
fetterHeroIDList.append(heroID)
|
|
# ¹ú¼Òͳ¼Æ
|
country = heroIpyData.GetCountry()
|
if country not in countryHeroInfo:
|
countryHeroInfo[country] = []
|
countryHeroIDList = countryHeroInfo[country]
|
if heroID not in countryHeroIDList:
|
countryHeroIDList.append(heroID)
|
|
# î¿°íÊôÐÔ - ½öî¿°íÏà¹ØÎ佫ÓÐЧ
|
heroFetterAttrInfo = {} # Î佫íÊôÐÔ {heroID:{attrID:value, ...}, ...}
|
for fetterID, fetterHeroIDList in fetterHeroInfo.items():
|
fetterIpyData = IpyGameDataPY.GetIpyGameData("HeroFetter", fetterID)
|
if not fetterIpyData:
|
continue
|
needHeroIDList = fetterIpyData.GetHeroIDList()
|
canFetter = True
|
for needHeroID in needHeroIDList:
|
if needHeroID not in fetterHeroIDList:
|
canFetter = False
|
break
|
if not canFetter:
|
continue
|
attrIDList = fetterIpyData.GetAttrIDList()
|
attrValueList = fetterIpyData.GetAttrValueList()
|
for aIndex in range(min(len(attrIDList), len(attrValueList))):
|
attrID = attrIDList[aIndex]
|
attrValue = attrValueList[aIndex]
|
for heroID in needHeroIDList:
|
if heroID not in heroFetterAttrInfo:
|
heroFetterAttrInfo[heroID] = {}
|
heroFetterAttrDict = heroFetterAttrInfo[heroID]
|
heroFetterAttrDict[attrID] = heroFetterAttrDict.get(attrID, 0) + attrValue
|
|
# ÕóÈÝÊôÐÔ - ÕóÈÝËùÓÐÎ佫ÓÐЧ
|
lineupHaloAttrInfo = {} # ÕóÈݹ⻷ÊôÐÔ {attrID:value, ...}
|
for country, countryHeroIDList in countryHeroInfo.items():
|
haloIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroLineupHalo", country)
|
if not haloIpyDataList:
|
continue
|
|
attrIDList, attrValueList = [], []
|
countryHeroCnt = len(countryHeroIDList)
|
for haloIpyData in haloIpyDataList:
|
needHeroCount = haloIpyData.GetNeedHeroCount()
|
if countryHeroCnt < needHeroCount:
|
break
|
attrIDList = haloIpyData.GetAttrIDList()
|
attrValueList = haloIpyData.GetAttrValueList()
|
# ÿ¸ö¹ú¼Ò×î¶à½öÉúЧһÌõÊôÐÔ£¬²»Í¬¹ú¼ÒÊôÐԿɵþ¼Ó
|
for aIndex in range(min(len(attrIDList), len(attrValueList))):
|
attrID = attrIDList[aIndex]
|
attrValue = attrValueList[aIndex]
|
lineupHaloAttrInfo[attrID] = lineupHaloAttrInfo.get(attrID, 0) + attrValue
|
|
# --------------------------- ÉÏÃæÍ³¼ÆºÃÁË£¬ÏÂÃæ¼ÆËãÎ佫×îÖÕÊôÐÔ --------------------------------
|
baseAttrFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 1)
|
otherAttrFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 2)
|
fightPowerFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 3)
|
|
lvAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_LV)
|
equipAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_MainEquip)
|
bookAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_HeroBook)
|
|
GameWorld.DebugLog(" ¹ú¼ÒÎ佫ͳ¼Æ=%s" % countryHeroInfo, playerID)
|
GameWorld.DebugLog(" î¿°íÎ佫ͳ¼Æ=%s" % fetterHeroInfo, playerID)
|
GameWorld.DebugLog(" Î佫×ÔÉíÊôÐÔ=%s" % heroSelfAttrInfo, playerID)
|
GameWorld.DebugLog(" Î佫ÍÌÊÉÊôÐÔ=%s" % heroStarTalentInfo, playerID)
|
GameWorld.DebugLog(" Îä½«Í»ÆÆÇ±ÄÜ=%s" % heroBreakAttrInfo, playerID)
|
GameWorld.DebugLog(" Î佫¾õÐÑÌ츳=%s" % heroAwakeTalentInfo, playerID)
|
GameWorld.DebugLog(" Î佫íÊôÐÔ=%s" % heroFetterAttrInfo, playerID)
|
GameWorld.DebugLog(" ÕóÈݹ⻷ÊôÐÔ=%s" % lineupHaloAttrInfo, playerID)
|
GameWorld.DebugLog(" ÕóÈÝÉÏÕó¼Ó³É=InitAddPer=%s,LVAddPer=%s,BreakLVAddPer=%s,StarAddPer=%s" % (InitAddPer, LVAddPer, BreakLVAddPer, StarAddPer), playerID)
|
|
GameWorld.DebugLog(" Ö÷¹«µÈ¼¶ÊôÐÔ=%s" % lvAttrDict, playerID)
|
GameWorld.DebugLog(" Ö÷¹«×°±¸ÊôÐÔ=%s" % equipAttrDict, playerID)
|
GameWorld.DebugLog(" Ö÷¹«Í¼¼øÊôÐÔ=%s" % bookAttrDict, playerID)
|
|
lineupFightPower = 0 # ÕóÈÝ×ÜÕ½Á¦
|
InitAddPer, LVAddPer, BreakLVAddPer, StarAddPer = InitAddPer / 10000.0, LVAddPer / 10000.0, BreakLVAddPer / 10000.0, StarAddPer / 10000.0
|
for heroID, selfAttrDict in heroSelfAttrInfo.items():
|
lineupHero = lineup.GetLineupHeroByID(heroID)
|
if not lineupHero:
|
continue
|
lineupHero.heroBatAttrDict = {}
|
lineupHero.fightPower = 0
|
|
starTalentAttrDict = heroStarTalentInfo.get(heroID, {})
|
breakAttrDict = heroBreakAttrInfo.get(heroID, {})
|
awakeTalentAttrDict = heroAwakeTalentInfo.get(heroID, {})
|
fetterAttrDict = heroFetterAttrInfo.get(heroID, {})
|
|
logAttrDict = {}
|
fightPowerParamDict = {}
|
for attrID in ChConfig.CalcBattleAttrIDList:
|
attrPerID = ChConfig.AttrPerDict.get(attrID, 0) # ¶ÔÓ¦°Ù·Ö±ÈÌáÉýµÄÊôÐÔID
|
|
lvValue = lvAttrDict.get(attrID, 0)
|
equipValue = equipAttrDict.get(attrID, 0)
|
bookValue = bookAttrDict.get(attrID, 0)
|
bookPer = bookAttrDict.get(attrPerID, 0) / 10000.0 if attrPerID else 0
|
|
lineupInitAddPer, lineupLVAddPer, lineupBreakLVAddPer, lineupStarAddPer = 0, 0, 0, 0
|
if attrID in ChConfig.BaseAttrIDList:
|
lineupInitAddPer, lineupLVAddPer, lineupBreakLVAddPer, lineupStarAddPer = InitAddPer, LVAddPer, BreakLVAddPer, StarAddPer
|
|
heroSelfValue, heroSelfPer = selfAttrDict.get(attrID, 0), 0 # Î佫×ÔÉí»ùÖµ
|
inheritPer = 1 # ¼Ì³Ð±ÈÀý£¬Ä¬ÈÏ100%
|
if attrID in ChConfig.AttrInheritPerDict:
|
attrInheritPerID = ChConfig.AttrInheritPerDict[attrID] # ¼Ì³ÐID
|
inheritPer = selfAttrDict.get(attrInheritPerID, 100) # ¼Ì³Ð±ÈÀý´ÓÎ佫×ÔÉíÊôÐÔÖÐÈ¡
|
inheritPer /= 100.0
|
|
lineupHaloValue, lineupHaloPer = lineupHaloAttrInfo.get(attrID, 0), 0
|
fetterValue, fetterPer = fetterAttrDict.get(attrID, 0), 0
|
starTalentValue, starTalentPer = starTalentAttrDict.get(attrID, 0), 0
|
breakLVValue, breakLVPer = breakAttrDict.get(attrID, 0), 0
|
awakeTalentValue, awakeTalentPer = awakeTalentAttrDict.get(attrID, 0), 0
|
if attrPerID:
|
heroSelfPer = selfAttrDict.get(attrPerID, 0) / 10000.0
|
lineupHaloPer = lineupHaloAttrInfo.get(attrPerID, 0) / 10000.0
|
fetterPer = fetterAttrDict.get(attrPerID, 0) / 10000.0
|
starTalentPer = starTalentAttrDict.get(attrPerID, 0) / 10000.0
|
breakLVPer = breakAttrDict.get(attrPerID, 0) / 10000.0
|
awakeTalentPer = awakeTalentAttrDict.get(attrPerID, 0) / 10000.0
|
|
# ¼ÆËã
|
attrParamDict = {"lvValue":lvValue, "equipValue":equipValue, "bookValue":bookValue, "bookPer":bookPer,
|
"lineupInitAddPer":lineupInitAddPer, "lineupLVAddPer":lineupLVAddPer, "lineupBreakLVAddPer":lineupBreakLVAddPer, "lineupStarAddPer":lineupStarAddPer,
|
"heroSelfValue":heroSelfValue, "heroSelfPer":heroSelfPer, "inheritPer":inheritPer,
|
"lineupHaloValue":lineupHaloValue, "lineupHaloPer":lineupHaloPer, "fetterValue":fetterValue, "fetterPer":fetterPer,
|
"starTalentValue":starTalentValue, "starTalentPer":starTalentPer, "breakLVValue":breakLVValue, "breakLVPer":breakLVPer,
|
"awakeTalentValue":awakeTalentValue, "awakeTalentPer":awakeTalentPer,
|
}
|
|
if attrID in ChConfig.BaseAttrIDList:
|
attrValue = FormulaControl.Eval("baseAttrFormula", baseAttrFormula, attrParamDict)
|
else:
|
attrValue = FormulaControl.Eval("otherAttrFormula", otherAttrFormula, attrParamDict)
|
#GameWorld.DebugLog(" attrID=%s,attrValue=%s,attrParamDict=%s" % (attrID, attrValue, attrParamDict))
|
|
attrIpyData = IpyGameDataPY.GetIpyGameData("PlayerAttr", attrID)
|
attrName = attrIpyData.GetParameter() if attrIpyData else "%s" % attrID
|
fightPowerParamDict[attrName] = attrValue
|
if attrValue:
|
lineupHero.heroBatAttrDict[attrID] = attrValue
|
logAttrDict["%s-%s" % (attrID, attrName)] = attrValue
|
|
# ¼ÆËãÕ½Á¦
|
fightPower = FormulaControl.Eval("fightPowerFormula", fightPowerFormula, fightPowerParamDict)
|
|
GameWorld.DebugLog(" fightPower=%s,heroSkillIDList=%s" % (fightPower, lineupHero.heroSkillIDList))
|
skillTypeIDDict = {}
|
for skillID in lineupHero.heroSkillIDList:
|
skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
|
if not skillData:
|
continue
|
skillTypeID = skillData.GetSkillTypeID()
|
if skillTypeID not in skillTypeIDDict:
|
skillTypeIDDict[skillTypeID] = skillData
|
else:
|
befSkillData = skillTypeIDDict[skillTypeID]
|
befSkillID = befSkillData.GetSkillID()
|
if befSkillID >= skillID:
|
continue
|
skillTypeIDDict[skillTypeID] = skillData
|
|
skillFightPower = 0
|
lineupHero.heroSkillIDList = []
|
for skillData in skillTypeIDDict.values():
|
skillID = skillData.GetSkillID()
|
lineupHero.heroSkillIDList.append(skillID)
|
skillFightPower += skillData.GetFightPower()
|
GameWorld.DebugLog(" skillFightPower=%s,heroSkillIDList=%s" % (skillFightPower, lineupHero.heroSkillIDList))
|
|
# ×îÖÕÕ½Á¦
|
fightPowerTotal = fightPower + skillFightPower
|
lineupHero.skillFightPower = skillFightPower
|
lineupHero.fightPower = fightPowerTotal
|
lineupFightPower += fightPowerTotal
|
|
GameWorld.DebugLog(" Î佫×îÖÕÕ½Á¦: heroID=%s,fightPower=%s(%s+%s),%s,skillIDList=%s"
|
% (heroID, fightPowerTotal, fightPower, skillFightPower, logAttrDict, lineupHero.heroSkillIDList), playerID)
|
|
lineup.fightPower = lineupFightPower
|
GameWorld.DebugLog(" ÕóÈÝ×îÖÕÕ½Á¦: lineupID=%s,lineupFightPower=%s" % (lineupID, lineupFightPower), playerID)
|
|
# ¸üÐÂÅÅÐаñ
|
if lineupID != ShareDefine.Lineup_Main:
|
return
|
|
PlayerControl.SetFightPower(curPlayer, lineupFightPower)
|
|
return
|