hch
12 小时以前 1cf37b4b51fc287ca3e443afb72604ec88f72cc4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -99,8 +99,9 @@
import PlayerCharm
import PlayerTask
import PlayerFace
import PlayerMail
import PlayerHero
import ChPlayer
import GMShell
import GameObj
import random
@@ -338,189 +339,16 @@
#---------------------------------------------------------------------
def SendMailBatch(mailTypeKey, batchPlayerIDList, batchAddItemList=[], batchParamList=[], batchGold=[], batchGoldPaper=[], batchSilver=[], batchDetail=[], moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
    '''批量发送邮件, 用于瞬间需要发送多封(大量)邮件的,比如一些公共副本活动等结算时
    @param mailTypeKey: 邮件模板key
    @param batchPlayerIDList: [playerIDList, playerIDList, ...]
    @param batchAddItemList: [addItemList, addItemList, ...]
    @param batchParamList: [paramList, paramList, ...]
    @param batchGold: [batchGold, batchGold, ...]
    @param batchGoldPaper: [batchGoldPaper, batchGoldPaper, ...]
    @param batchSilver: [batchSilver, batchSilver, ...]
    @param batchDetail: [记录邮件流向用, ...]
    @param moneySource: 货币来源
    '''
    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
    for i, playerIDList in enumerate(batchPlayerIDList):
        for playerID in playerIDList[::-1]:
            curPlayer = copyMapPlayerManager.FindPlayerByID(playerID)
            if curPlayer and not curPlayer.GetGameServerInitOK():
                bAddItemList = [batchAddItemList[i]] if len(batchAddItemList) > i else []
                bParamList = [batchParamList[i]] if len(batchParamList) > i else []
                bGold = [batchGold[i]] if len(batchGold) > i else []
                bGoldPaper = [batchGoldPaper[i]] if len(batchGoldPaper) > i else []
                bSilver = [batchSilver[i]] if len(batchSilver) > i else []
                bDetail = [batchDetail[i]] if len(batchDetail) > i else []
                AddUnLoginOKPlayerMailCache(playerID, "ByMailTemplate", [mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail])
                playerIDList.pop(playerIDList.index(playerID))
                continue
    msgInfo = str([mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource, crossMail])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendMailBatch", msgInfo, len(msgInfo))
    GameWorld.Log("SendMailBatch %s, batchPlayerIDList=%s, batchAddItemList=%s, batchParamList=%s, batchGold=%s, batchGoldPaper=%s, batchSilver=%s"
                  % (mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver))
    ## 删除旧版发送邮件,如果功能还有需要,可使用新版本发送邮件 PlayerMail
    ## 批量发送邮件的一般是活动类型功能,一般都需要用到GameServer
    ## 所以暂时不兼容使用新版本发送邮件,等相应功能有需要时再同步修改
    return
def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
    '''
    @param detail: 记录邮件流向用
    '''
    if not mailTypeKey:
        mailTypeKey = ShareDefine.DefaultLackSpaceMailType
    content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, json.dumps(paramList, ensure_ascii=False))
    SendMail("", content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
    return
def SendCrossMail(serverGroupID, mailTypeKey, playerIDList, addItemList, paramList=[]):
    ## 发送跨服邮件
    if not serverGroupID:
        return
    dataMsg = {"MailTypeKey":mailTypeKey, "Player":playerIDList}
    if addItemList:
        dataMsg["Item"] = CombineMailItem(addItemList)
    if paramList:
        dataMsg["Param"] = paramList
    GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_SendMail, dataMsg, [serverGroupID])
    return
def SendEntireMail(mailTypeKey, getDays, limitLV, limitLVType, addItemList=[], paramList=[], \
                   gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
    ''' 发送全服邮件
    @param mailTypeKey: 邮件模板key
    @param getDays: 有效天数
    @param limitLV: 领取最低等级限制
    @param limitLVType: 等级不足的升级后是否可领 0-不可,1-可以
    '''
    # 有效天数限制
    if not mailTypeKey or getDays <= 0:
        return
    # 跨服服务器不允许发送邮件
    if GameWorld.IsCrossServer():
        return
    combineItemList = CombineMailItem(addItemList)
    cmdList = [mailTypeKey, getDays, limitLV, limitLVType, combineItemList, paramList, gold, goldPaper, silver, detail, moneySource]
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendEntireMail", '%s' % (cmdList), len(str(cmdList)))
    GameWorld.Log("发送全服邮件: %s,getDays=%s,limitLV=%s,limitLVType=%s,combineItemList=%s,paramList=%s,gold=%s,goldPaper=%s,silver=%s,detail=%s,moneySource=%s" %
                  (mailTypeKey, getDays, limitLV, limitLVType, combineItemList, paramList, gold, goldPaper, silver, detail, moneySource))
    return
## 功能发放物品补偿/奖励邮件
#  @param addItemList [(itemID, itemCnt, 是否拍品), {或物品信息字典}, ...]
#  @return
def SendMail(title, content, getDays, playerIDList, addItemList, gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
    if not playerIDList:
        return
#    if not addItemList:
#        return
    # 有效天数限制
    if getDays <= 0:
        return
    # 跨服服务器不允许发送邮件
    if GameWorld.IsCrossServer() and not crossMail:
        return
    sendPlayerIDList = []
    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
    ## 函数先保留,之后功能直接使用 PlayerMail.SendMailByKey
    for playerID in playerIDList:
        curPlayer = copyMapPlayerManager.FindPlayerByID(playerID)
        if curPlayer and not curPlayer.GetGameServerInitOK():
            AddUnLoginOKPlayerMailCache(playerID, "ByMailContent", [title, content, getDays, addItemList, gold, goldPaper, silver, detail, moneySource])
            continue
        sendPlayerIDList.append(playerID)
    combineItemList = CombineMailItem(addItemList)
    cmdList = [title, content, getDays, sendPlayerIDList, combineItemList, gold, goldPaper, silver, detail, moneySource, crossMail]
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendMail", '%s' % (cmdList), len(str(cmdList)))
    return True
def AddUnLoginOKPlayerMailCache(playerID, cacheType, mailInfo):
    ''' 添加未登录成功的玩家个人邮件发送缓存
    '''
    if playerID not in PyGameData.g_unLoginOKPlayerMailInfo:
        PyGameData.g_unLoginOKPlayerMailInfo[playerID] = []
    mailList = PyGameData.g_unLoginOKPlayerMailInfo[playerID]
    if [cacheType, mailInfo] in mailList:
        GameWorld.Log("###重复添加GetGameServerInitOK未登录成功的玩家个人邮件发送缓存! 不添加! mailCount=%s, mailInfo=%s"
                      % (len(mailList), str(mailInfo)), playerID)
        return
    if len(mailList) >= 30: # 做个限制,防止出问题刷邮件
        GameWorld.Log("###限制添加GetGameServerInitOK未登录成功的玩家个人邮件发送缓存! 超出最大可添加数,不添加! mailCount=%s, mailInfo=%s"
                      % (len(mailList), str(mailInfo)), playerID)
        return
    mailList.append([cacheType, mailInfo])
    # curPlayer.GetGameServerInitOK()
    GameWorld.Log("添加GetGameServerInitOK未登录成功的玩家个人邮件发送缓存! 等待发送! mailCount=%s, mailInfo=%s"
                  % (len(mailList), str(mailInfo)), playerID)
        PlayerMail.SendMailByKey(mailTypeKey, playerID, addItemList, paramList)
    return
def SendUnLoginOKPlayerMailCache(curPlayer):
    ## 未登录成功的玩家个人邮件发送缓存  - 登录成功后处理
    if not curPlayer.GetGameServerInitOK():
        return
    playerID = curPlayer.GetPlayerID()
    if playerID not in PyGameData.g_unLoginOKPlayerMailInfo:
        return
    mailList = PyGameData.g_unLoginOKPlayerMailInfo.pop(playerID)
    for cacheType, mailInfo in mailList:
        playerIDList = [playerID]
        GameWorld.Log("发送未登录成功时缓存的待发送邮件! cacheType=%s, mailInfo=%s" % (cacheType, str(mailInfo)), playerID)
        if cacheType == "ByMailContent":
            title, content, getDays, addItemList, gold, goldPaper, silver, detail, moneySource = mailInfo
            SendMail(title, content, getDays, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource)
        elif cacheType == "ByMailTemplate":
            mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail = mailInfo
            SendMailBatch(mailTypeKey, [playerIDList], bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail)
    return
def CombineMailItem(addItemList):
    ## 合并邮件物品
    itemCountDict = {}
    combineItemList = [] # 合并后的物品列表
    for mailItem in addItemList:
        if isinstance(mailItem, dict):
            combineItemList.append(mailItem)
            continue
        if len(mailItem) != 3:
            continue
        itemID, itemCnt, isAuctionItem = mailItem
        if ItemControler.GetAppointItemRealID(itemID):
            # 定制物品转化为物品信息字典
            appointItemObj = ItemControler.GetItemByData(ItemControler.GetAppointItemDictData(itemID, isAuctionItem))
            if not appointItemObj:
                GameWorld.ErrLog("邮件定制物品转化失败!itemID, itemCnt, isAuctionItem" % (itemID, itemCnt, isAuctionItem))
                continue
            combineItemList.append(ItemCommon.GetMailItemDict(appointItemObj))
            appointItemObj.Clear()
        elif isAuctionItem:
            combineItemList.append((itemID, itemCnt, isAuctionItem))
        else:
            key = (itemID, isAuctionItem)
            itemCountDict[key] = itemCountDict.get(key, 0) + itemCnt
    for key, itemCnt in itemCountDict.items():
        itemID, isAuctionItem = key
        combineItemList.append((itemID, itemCnt, isAuctionItem))
    return combineItemList
## 构建系统提示参数列表
#  @param msgParamList 信息参数列表
@@ -3056,6 +2884,8 @@
    #轮回殿
    PlayerActLunhuidian.AddLunhuidianValue(curPlayer, PlayerActLunhuidian.AwardType_PayMoney, type_Price, price)
    if type_Price == ShareDefine.TYPE_Price_Xiantao:
        unXiantaoCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCnt)
        NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCnt, unXiantaoCnt + price)
        PlayerPrestigeSys.AddRealmTaskValue(curPlayer, PlayerPrestigeSys.RealmTaskType_UseXiantao, price)
    unitPrice = price if quantity == 1 else int(math.ceil(price * 1.0 / quantity)) # 单价
    #reason_name = "Unknown" if not costType else costType
@@ -4411,6 +4241,7 @@
        PlayerFamilyZhenfa.CalcZhenfaAttr(curPlayer)
        PlayerFace.CalcFaceAttr(curPlayer)
        PlayerFace.CalcFacePicAttr(curPlayer)
        PlayerHero.CalcHeroItemAddAttr(curPlayer)
        self.RefreshAllState(isForce=True)
        GameWorld.DebugLog("End ReCalcAllState!!!", playerID)
        return
@@ -4879,10 +4710,11 @@
    def __DoRefreshGMAttr(self):
        ## 刷新GM测试属性
        curPlayer = self.__Player
        platform = GameWorld.GetPlatform()
        if platform not in GMShell.TestPlatformList:
            return
        if curPlayer.GetGMLevel() != ChConfig.Def_GM_LV_God:
            return
        platform = GameWorld.GetPlatform()
        if not GameWorld.IsTestPlatform(platform):
            return
        
        ipyDataMgr = IpyGameDataPY.IPY_Data()
@@ -5209,7 +5041,7 @@
    def __SetAtkInterval(self):
        curPlayer = self.__Player
        
        atkSpeed = GetAtkSpeed(curPlayer)
        atkSpeed = GameObj.GetAtkSpeed(curPlayer)
        
        formula = IpyGameDataPY.GetFuncCfg("AtkInterval")
        atkInterval = 0 if not formula else eval(FormulaControl.GetCompileFormula("AtkInterval", formula))
@@ -5848,8 +5680,20 @@
    #通知客户端
    curPack.Sync_PackCanUseCount()
    return
def Init_HeroPack(curPlayer):
    packType = ShareDefine.rptHero
    #获取玩家背包
    curPack = curPlayer.GetItemManager().GetPack(packType)
    initCount = ItemCommon.GetPackInitCount(packType)
    if packType in ChConfig.Def_Type_CanBuyPack_PlayerDict.keys():
        keyName = ChConfig.Def_Type_CanBuyPack_PlayerDict.get(packType)[ChConfig.Def_PlayerPackDict_Index_Key]
        initCount += curPlayer.NomalDictGetProperty(keyName)
    curPack.SetCount(initCount)
    #通知客户端背包格子数目
#    curPlayer.Sync_ItemCount(curPack.GetCount())
    curPack.Sync_PackCanUseCount()
    return
##初始化寻宝背包
@@ -6090,18 +5934,58 @@
        SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ForbidenTalk, 0)
    return
def IsMainLevelPass(curPlayer, lvID):
    ## 判断玩家是否过关某个主线关卡ID
    # @param lvID: 关卡唯一ID,与策划约定好 = 章节*100+关卡编号
    passChapterID, passLevelNum, _ = GetMainLevelPassInfo(curPlayer)
    passValue = passChapterID * 100 + passLevelNum # 因为pass的记录是带波数的,即当前关卡boss还没过关,所以只有大于该记录值的才算过关
    return passValue > lvID
## 主线关卡过关进度值 = 章节*10000+关卡编号*100+第x波
def GetMainLevelPassValue(curPlayer): return curPlayer.GetExAttr1()
def SetMainLevelPassValue(curPlayer, value): curPlayer.SetExAttr1(value, False, False) # 不通知GameServer
def SetMainLevelPassInfo(curPlayer, chapterID, levelNum, wave=0):
    ## 设置主线关卡过关进度
    # @param chapterID: 章节ID
    # @param levelNum: 关卡编号
    # @param wave: 第x波
    value = ComMainLevelValue(chapterID, levelNum, wave)
    SetMainLevelPassValue(curPlayer, value)
    return value
def GetMainLevelPassInfo(curPlayer):
    ## 获取主线关卡过关进度信息
    # @return: chapterID, levelNum, wave
    return GetMainLevelValue(GetMainLevelPassValue(curPlayer))
## 主线关卡当前进度值 = 章节*10000+关卡编号*100+第x波
def GetMainLevelNowValue(curPlayer): return curPlayer.GetExAttr2()
def SetMainLevelNowValue(curPlayer, value): curPlayer.SetExAttr2(value, False, False) # 不通知GameServer
def SetMainLevelNowInfo(curPlayer, chapterID=1, levelNum=1, wave=1):
    ## 设置主线关卡当前进度
    # @param chapterID: 章节ID
    # @param levelNum: 关卡编号
    # @param wave: 第x波
    value = ComMainLevelValue(chapterID, levelNum, wave)
    SetMainLevelNowValue(curPlayer, value)
    return value
def GetMainLevelNowInfo(curPlayer):
    ## 获取主线关卡当前进度信息
    # @return: chapterID, levelNum, wave
    return GetMainLevelValue(GetMainLevelNowValue(curPlayer))
def ComMainLevelValue(chapterID, levelNum, wave=0): return chapterID * 10000 + levelNum * 100 + wave
def GetMainLevelValue(value):
    chapterID = value / 10000
    levelNum = value % 10000 / 100
    wave = value % 100
    return chapterID, levelNum, wave
## 协助目标玩家ID
def SetAssistTagPlayerID(curPlayer, value):
    curPlayer.SetExAttr1(value, True, False) # 不通知GameServer
    NPCHurtManager.OnSetAssistTagPlayerID(curPlayer, value)
    return
def GetAssistTagPlayerID(curPlayer): return curPlayer.GetExAttr1()
def GetAssistTagPlayerID(curPlayer): return 0
## 队伍相关审核开关状态, joinReqCheck-入队申请是否需要审核; inviteCheck-组队邀请是否需要审核;
def SetTeamCheckStateEx(curPlayer, joinReqCheck, inviteCheck): return SetTeamCheckState(curPlayer, joinReqCheck * 10 + inviteCheck)
def SetTeamCheckState(curPlayer, checkState): return curPlayer.SetExAttr2(checkState, False, True)
def GetTeamCheckState(curPlayer): return curPlayer.GetExAttr2()
def SetTeamCheckState(curPlayer, checkState): return
## 副本功能线路ID, 这里做db存储,防止在合并地图副本中掉线重上时前端无法加载正确的场景资源,登录加载场景时机为0102包
def SetFBFuncLineID(curPlayer, mapID, funcLineID):
    value = mapID * 1000 + funcLineID
@@ -6768,18 +6652,6 @@
def SetSpeedValue(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_SpeedValue, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_SpeedValue, value, True) # 移动速度值暂定广播周围玩家
##获取玩家攻击速度,用于计算攻击间隔
# @param curPlayer 玩家实例
# @return 玩家攻击速度
def GetAtkSpeed(curPlayer):
    return curPlayer.GetBattleValEx1()
##设置玩家攻击速度,用于计算攻击间隔
# @param curPlayer 玩家实例
# @return None
def SetAtkSpeed(curPlayer, value):
    curPlayer.SetBattleValEx1(value, True)
    
#---攻击回复血量比率----
## 获取玩家攻击回复血量比率
@@ -6851,11 +6723,7 @@
## 卓越一击伤害减免
def GetGreatHitReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GreatHitReducePer)
def SetGreatHitReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GreatHitReducePer, value)
## 暴击伤害减免
def GetSuperHitReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SuperHitReduce)
def SetSuperHitReduce(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_SuperHitReduce, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_SuperHitReduce, value)
## 无视防御伤害减免
def GetIgnoreDefReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IgnoreDefReducePer)
def SetIgnoreDefReducePer(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_IgnoreDefReducePer, value)
@@ -6869,11 +6737,7 @@
## 抗卓越一击概率
def GetGreatHitRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_GreatHitRateReduce)
def SetGreatHitRateReduce(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_GreatHitRateReduce, value)
## 抗暴击概率
def GetSuperHitRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SuperHitRateReduce)
def SetSuperHitRateReduce(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_SuperHitRateReduce, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_SuperHitRateReduce, value)
## 抗无视防御概率
def GetIgnoreDefRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_IgnoreDefRateReduce)
def SetIgnoreDefRateReduce(curPlayer, value):
@@ -6896,18 +6760,6 @@
def SetBossFinalHurtPer(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_BossFinalHurtPer, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_BossFinalHurtPer, value)
## 最终伤害百分比
def GetFinalHurtPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtPer)
def SetFinalHurtPer(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtPer, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtPer, value)
## 最终伤害减免百分比
def GetFinalHurtReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtReducePer)
def SetFinalHurtReducePer(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtReducePer, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtReducePer, value)
    
## 最终固定伤害增加
def GetFinalHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurt)
@@ -7155,17 +7007,6 @@
#  @return None
def SetReduceBackHPPer(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ReduceBackHPPer, value)
#---触发击晕----
def GetFaintRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrFaintRate)
def SetFaintRate(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrFaintRate, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FaintRate, value)
#---击晕抵抗----
def GetFaintDefRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrFaintDefRate)
def SetFaintDefRate(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrFaintDefRate, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FaintDefRate, value)
    
#---触发定身----
def GetAtkerFreezed(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrAtkerFreezed)
@@ -7175,17 +7016,6 @@
def GetAddAngry(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrAddAngry)
def SetAddAngry(curPlayer, value): curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrAddAngry, value)
#---连击几率----
def GetComboRate(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrComboRate)
def SetComboRate(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrComboRate, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ComboRate, value)
#---连击伤害----
def GetComboDamPer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_AttrComboDamPer)
def SetComboDamPer(curPlayer, value):
    curPlayer.SetDict(ChConfig.Def_PlayerKey_AttrComboDamPer, value)
    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_ComboDamPer, value)
#---技能攻击比例减少----
def GetSkillAtkRateReduce(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SkillAtkRateReduce)
def SetSkillAtkRateReduce(curPlayer, value):
@@ -7499,6 +7329,12 @@
                dict1[key] = aValue + value
    return
def GetLordAttr(curPlayer):
    ## 获取主公属性汇总
    lordAttrDict = {"Atk":curPlayer.GetMaxAtk(), "Def":curPlayer.GetDef(), "MaxHP":GameObj.GetMaxHP(curPlayer),
                    "Hit":curPlayer.GetHit(), "Miss":curPlayer.GetMiss()}
    return lordAttrDict
#-------------------------------------------------------------------------------
## 设置玩家字典值, 存库
def NomalDictSetProperty(curPlayer, key, value, dType=0):