hxp
2025-08-26 a90e9dd726f63017404ed69d8c682956e42cd172
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -18,46 +18,30 @@
import SkillShell
import BuffSkill
import PlayerControl
import PlayerRequest
import ChEquip
import SkillCommon
import FBLogic
import AttackCommon
import ChItem
import PlayerGMOper
import ItemCommon
import OperControlManager
import ShareDefine
import PlayerAutoCheckOnline
import PlayerGameWallow
import ReadChConfig
import PlayerDienstgrad
import PlayerVip
import IpyGameDataPY
import PlayerFB
import GameObj
import GameMap
import math
import time
import PetControl
import ItemControler
import PlayerGuaji
import AICommon
import PlayerSuccess
import CrossPlayerData
import PassiveBuffEffMng
import FunctionNPCCommon
import FormulaControl
import PlayerGoldGift
import PlayerActLianqi
import PlayerActFamilyGCZ
import PlayerFlashSale
import PlayerChatBox
import PlayerFace
import PlayerYinji
import PlayerActivity
import PlayerBackup
import MirrorAttack
import PlayerOnline
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -671,25 +655,6 @@
    return
#---------------------------------------------------------------------
##刷新时效道具
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 返回值, 是否重刷玩家属性
# @remarks 刷新以单位时间(分钟)消耗耐久的物品
def ProcessRefreshTimeItem(curPlayer, tick):
    reFlash = False
    #2分钟遍历一次,时效道具时间到不消失,
    if tick - curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_EquipTime) \
        < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_TimeItem]:
        return reFlash
    #耐久减少值/分钟
    reFlash = ProcessTimeEquip(curPlayer, tick)
    return reFlash
#---------------------------------------------------------------------
##刷新玩家Buff
# @param curPlayer 玩家实例
# @param tick 时间戳
@@ -805,7 +770,7 @@
    curPlayer.SetDict(ChConfig.Def_PlayerKey_SitForZhenQi, tick)
    
    vipLV = curPlayer.GetVIPLv()
    vipRate = ShareDefine.Def_MaxRateValue#PlayerVip.GetVIPMuseSitRate(vipLV)
    vipRate = ShareDefine.Def_MaxRateValue
    
    #取得人物当前经验
    curTotalExp = PlayerControl.GetPlayerTotalExp(curPlayer) # 超过20亿支持,功能待定
@@ -821,7 +786,7 @@
                             isSysHint=False)
        
        if vipLV == 0:
            canVipRate = ShareDefine.Def_MaxRateValue#PlayerVip.GetVIPMuseSitRate(ShareDefine.Def_VIPType_Platina)
            canVipRate = ShareDefine.Def_MaxRateValue
            canVipExpValue = int(addExpValue * canVipRate / float(ShareDefine.Def_MaxRateValue))
            #GeRen_chenxin_684833:获得经验%s点,成为VIP经验%s
            PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_684833", [addExpValue, canVipExpValue])
@@ -875,68 +840,6 @@
    #    curPlayer.SetXP(nextXPValue)
    #===========================================================================
#---------------------------------------------------------------------
##玩家自动回复生命和魔法
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return None
# @remarks 玩家自动回复生命和魔法
def ProcessHPMPState(curPlayer, tick):
#    #仅打坐状态回复
#    if curPlayer.GetPlayerAction() != IPY_GameWorld.paSit:
#        return
    if not curPlayer.IsAlive():
        #死亡状态不处理
        return
    #检测是否到CD时间, 暂定5秒回一次
    if tick - curPlayer.GetRestoreTime() < ChConfig.Def_HPRestoreInterval:
        return
    #设置当前回复开始时间
    curPlayer.SetRestoreTime(tick)
    #没有恢复能力
    if curPlayer.GetHPRestorePer() == 0:
        return
    #满血不处理
    if GameObj.GetHP(curPlayer) == GameObj.GetMaxHP(curPlayer):
        return
    #战斗中返回
    #if curPlayer.IsBattleState():
    #    return False
#    #战斗对峙返回
#    if curPlayer.GetIsConfronting():
#        return False
    #---回复玩家血量---
    playerHP = GameObj.GetHP(curPlayer)
    #playerMP = curPlayer.GetMP()
    playerMaxHP = GameObj.GetMaxHP(curPlayer)
    #playerMaxMP = curPlayer.GetMaxMP()
    # 目前回复频率暂定5秒回复一次,回复数值是1秒的值,所以此处乘5
    addHPValue = curPlayer.GetHPRestorePer() * 5
    #addMPValue = GameWorld.GetFloatUpper(playerMaxMP * mpPer + mpValue)
    #GameWorld.Log('addHPValue = %s, addMPValue = %s'%(addHPValue, addMPValue))
    #当前不是满血, 就回血
    if playerHP != playerMaxHP:
        SkillCommon.SkillAddHP(curPlayer, 0, addHPValue)
        #GameObj.SetHP(curPlayer, min(playerHP + addHPValue, playerMaxHP))
    #当前不是满魔, 就回魔
    #if playerMP != playerMaxMP:
    #    curPlayer.SetMP(min(playerMP + addMPValue, playerMaxMP))
    return
#---------------------------------------------------------------------
##刷新组队状态
# @param curPlayer 玩家实例
@@ -963,11 +866,8 @@
# @remarks 刷新玩家在线时间
def ProcessPlayer_OnlineTime(curPlayer, tick):
    if not CommonCheckTick(curPlayer, tick, ChConfig.TYPE_Player_Tick_PlayerOnlineTime):
        return
        return
    
    #处理防沉迷在线时间,
    PlayerGameWallow.DoLogic_WallowOnlineTime(curPlayer, tick)
    return
    
@@ -1071,81 +971,6 @@
    return
#---------------------------------------------------------------------
##处理耐久计算方式为:现实时间刷新方式的物品
# @param curPlayer 玩家实例
# @return 布尔值
# @remarks 处理耐久计算方式为:现实时间刷新方式的物品
def ProcessTimeEquip(curPlayer, tick):
    itemManager = curPlayer.GetItemManager()
    hasItemClear = False
    classLV = 0 # 只处理非境界装备的时效物品
    curPack = itemManager.GetPack(IPY_GameWorld.rptEquip)
    for equipPlace in ChConfig.EquipPlace_LingQi:
        ipyData = IpyGameDataPY.GetIpyGameData('EquipPlaceIndexMap', classLV, equipPlace)
        if not ipyData:
            continue
        index = ipyData.GetGridIndex()
        curItem = curPack.GetAt(index)
        #异常物品
        if not ItemCommon.CheckItemCanUse(curItem):
            continue
        if curItem.GetEndureReduceType() not in [ChConfig.Def_EquipReduceType_RTimeItem,
                                                 ChConfig.Def_EquipReduceType_Time]:
            continue
        #处理现实时间物品逻辑
        if __DoLogic_ProcessTimeEquip(curPlayer, curItem, index):
            hasItemClear = True
    if hasItemClear:
        #装备重刷属性
        ChEquip.RefreshPlayerLingQiEquipAttr(curPlayer)
    # 进行更新时效道具刷新时间
    curPlayer.SetDict(ChConfig.Def_PlayerKey_EquipTime, tick)
    return hasItemClear
#---------------------------------------------------------------------
## 装备有效时间到了需要脱下,有效时间物品改成不消失,但是无使用效果 可出售和续费
def __DoLogic_ProcessTimeEquip(curPlayer, curItem, equipIndex):
    #验证物品是否过期
    curItemExpireTime = curItem.GetUserAttr(ShareDefine.Def_IudetExpireTime)
    if not curItemExpireTime:
        curItemExpireTime = curItem.GetExpireTime()
    curItemPastTime = time.time() - curItem.GetUserAttr(ShareDefine.Def_IudetCreateTime)
    if curItemExpireTime - curItemPastTime > 0:
        return
    spaceIndex = ItemControler.GetItemPackSpaceIndex(curPlayer, IPY_GameWorld.rptItem)
    if spaceIndex == -1:
        # 没有空位,玩家主动取下,计算属性时无效化
        # 过期属性时效需刷属性
        return True
    result = ItemControler.PlayerItemControler(curPlayer).UnEquipItem(equipIndex, spaceIndex)
    if not result:
        # 过期属性时效需刷属性
        return True
    equipID = result[0]
    equipPlace = result[1]
    if equipPlace in [ShareDefine.retGuard1, ShareDefine.retGuard2]:
        PlayerControl.NotifyCode(curPlayer, 'Guardian_Timeout', [equipID, spaceIndex])
    elif equipPlace == ShareDefine.retWing:
        PlayerControl.NotifyCode(curPlayer, 'WingTiyan_Timeout')
    tryItemDict = IpyGameDataPY.GetFuncEvalCfg('FirstGoldTryItem', 1, {})
    tryItemID = tryItemDict.get(curPlayer.GetJob(), 0)
    if tryItemID and ItemControler.GetAppointItemRealID(tryItemID) == equipID:
        #首充试用武器过期并且还没首充的提示()
        if not curPlayer.GetChangeCoinPointTotal():
            PlayerControl.NotifyCode(curPlayer, 'FirstGoldWPOver')
            PlayerGoldGift.FirstGoldTryItemOutTime(curPlayer)
    return True
#---------------------------------------------------------------------
##全局定时器调用, 刷新玩家状态
# @param curPlayer 玩家实例
# @param tick 时间戳
@@ -1165,113 +990,54 @@
    #定时备档
    PlayerBackup.CheckPlayerBackup(curPlayer)
    
    #玩家镜像战斗AI
    MirrorAttack.ProcessPlayerMirrorAI(curPlayer, tick)
    #被GM封状态响应
    ProcessGMOperLogic(curPlayer, tick)
    
    #刷新玩家战斗状态
    ProcessPlayerBattle(curPlayer, tick)
    #ProcessPlayerBattle(curPlayer, tick)
    
    #战斗状态判断
    CheckBattleState(curPlayer, tick)
    #CheckBattleState(curPlayer, tick)
    
    #切换玩家呆滞状态
    ProcessPlayerNeedProcess(curPlayer , tick)
    #ProcessPlayerNeedProcess(curPlayer , tick)
    
    #放在刷buff前
    ProcessPassiveSkill(curPlayer, tick)
    #---影响属性刷新---------------------------------------------
    #是否刷新列表
    reFlashList = []
    #刷新玩家Buff
    reFlashBuff = ProcessRefreshBuffState(curPlayer, tick)
    #刷新玩家场景buff效果
    ProcessPlayerBuffEffect(curPlayer, tick)
    #时效道具刷新
    reFlash = ProcessRefreshTimeItem(curPlayer, tick)
    reFlashList.append(reFlash)
#    GameWorld.Log('刷新以单位时间(分钟)消耗耐久的物品 %s'%(time.clock() - curTime))
#    curTime = time.clock()
    #ProcessPassiveSkill(curPlayer, tick)
    
    ProcessPlayerMinute(curPlayer, tick)
    
    #vip体验
    reFlash = PlayerVip.CheckVIPExperience(curPlayer, tick)
    reFlashList.append(reFlash)
    #===影响人物行为刷新, 支持控制类BUFF可刷属性======================================
    # 控制类有属性刷新交给属性处理
    attrBuffResult, actBuffResult = ProcessRefreshActionBuffState(curPlayer, tick)
    playerControl = PlayerControl.PlayerControl(curPlayer)
    if actBuffResult:
        playerControl.RefreshPlayerActionState()
    #===行为刷新结束==============================================================
    #重刷属性
    # 1. 循环内需要刷属性
    # 2. buff消失刷属性
    # 3. 玩家其他行为触发缓存刷属性
    # 4. 玩家因buff缓存刷属性
    if True in reFlashList :
        #Buff影响到属性刷新
        playerControl.RefreshPlayerAttrState()
    #此处才是真正的刷新人物属性值,需刷属性逻辑应在此行前调用
    if not playerControl.RefreshPlayerAttrStateEx():
        if reFlashBuff or attrBuffResult:
            playerControl.RefreshPlayerAttrByBuff()
        # 只刷BUFF情况
        playerControl.RefreshPlayerAttrByBuffEx()
    PlayerOnline.GetOnlinePlayer(curPlayer).DoRefreshRoleAttr()
    #---到这边应该属性刷新结束,下面的逻辑有的需要用到属性值--------------------
    
    
    #当前玩家的状态
    curPlayerAction = curPlayer.GetPlayerAction()
    #curPlayerAction = curPlayer.GetPlayerAction()
    
#    curTime = time.clock()
    #刷新玩家的准备进度条
    if curPlayerAction == IPY_GameWorld.paPreparing :
        ProcessPlayerPrepareState(curPlayer, tick)
    #if curPlayerAction == IPY_GameWorld.paPreparing :
    #    ProcessPlayerPrepareState(curPlayer, tick)
    
    #刷新玩家请求
    PlayerRequest.ProcessPlayerRequest(curPlayer, tick)
    #回血回魔状态处理
    ProcessHPMPState(curPlayer, tick)
    PlayerYinji.ProcessPlayerYinji(curPlayer, tick)
    #PlayerYinji.ProcessPlayerYinji(curPlayer, tick)
    
    #刷新组队状态
    #ProcessTeamState(curPlayer, tick)
    #玩家在线时间刷新
    ProcessPlayer_OnlineTime(curPlayer, tick)
    #ProcessPlayer_OnlineTime(curPlayer, tick)
    
    #反外挂验证
    PlayerAutoCheckOnline.HackDefense(curPlayer, tick)
    #PlayerAutoCheckOnline.HackDefense(curPlayer, tick)
    
    #副本相关时间处理
    PlayerFB.DoPlayerFBTimeProcess(curPlayer, tick)
    #PlayerFB.DoPlayerFBTimeProcess(curPlayer, tick)
    
    #挂机收益
    PlayerGuaji.ProcessGuaji(curPlayer)
    #PK/boss״̬
    ProcessPKBossState(curPlayer, tick)
    #PlayerGuaji.ProcessGuaji(curPlayer)
    
    #恶意攻击时间处理
    AttackCommon.ProcessMaliciousAttackPlayer(curPlayer, tick)
    #AttackCommon.ProcessMaliciousAttackPlayer(curPlayer, tick)
    #成就
    PlayerSuccess.FinishDelayAddSuccessProgress(curPlayer, tick, False)
    #限时抢购
@@ -1281,15 +1047,15 @@
    #神秘商店刷新
    FunctionNPCCommon.CheckMysticalShopRefresh(curPlayer, tick)
    #活跃放置
    PlayerActivity.ProcessActivityPlace(curPlayer)
    #PlayerActivity.ProcessActivityPlace(curPlayer)
    #自定义场景
    FBLogic.OnCustomSceneProcess(curPlayer, tick)
    #FBLogic.OnCustomSceneProcess(curPlayer, tick)
    #炼器
    PlayerActLianqi.OnProcess(curPlayer)
    #PlayerActLianqi.OnProcess(curPlayer)
    #仙盟攻城战
    PlayerActFamilyGCZ.OnProcess(curPlayer)
    #PlayerActFamilyGCZ.OnProcess(curPlayer)
    #跨服数据同步,放最后
    CrossPlayerData.ProcessCrossPlayer(curPlayer, tick)
    #CrossPlayerData.ProcessCrossPlayer(curPlayer, tick)
    return
def ProcessPlayerMinute(curPlayer, tick):
@@ -1423,66 +1189,6 @@
    PlayerGMOper.DoGMOperLogic(curPlayer, tick)
    return
#===============================================================================
# 警告:1.此功能应该会导致更加频繁处理战斗逻辑附带的刷新属性等逻辑
# 需三思考虑,暂时关闭。
#
# ## 计时器入口,战斗逻辑
# # @param None
# # @return None
# def PlayerProcessFight(timerType, tick):
#    if not GameWorld.GetGameWorld().GetInitOK() :
#        return
#
#    #GameWorld.DebugLog("---!!PlayerProcessFight %s"%([timerType, tick]))
#
#    for i in xrange(GameWorld.GetGameWorld().GetGameWorldCount()):
#        #设置当前的世界
#        GameWorld.GetGameWorld().SetCurGameWorldIndex(i)
#
#        playerManager = GameWorld.GetPlayerManager()
#        playerCount = playerManager.GetActivePlayerCount()
#        for i in range(0, playerCount):
#            curPlayer = playerManager.GetActivePlayerByIndex(i)
#            if curPlayer.IsEmpty():
#                continue
#
#            if not curPlayer.GetInitOK():
#                #GameWorld.Log("玩家还未初始化成功, 不处理")
#                continue
#
#            if curPlayer.IsMoving():
#                continue
#
#            ProcessFight(curPlayer, tick)
#
#    GameWorld.GetGameWorld().SetCurGameWorldIndex(-1)
#
#    return
#===============================================================================
def ProcessPKBossState(curPlayer, tick):
    ## 处理PK及boss状态
    validTime = IpyGameDataPY.GetFuncCfg("PKConfig", 4) * 1000
    pkStateTick = curPlayer.GetDictByKey(ChConfig.Def_PDict_PKStateTick)
    if pkStateTick and (tick - pkStateTick) >= validTime:
        curPlayer.SetDict(ChConfig.Def_PDict_PKStateTick, 0)
        PlayerControl.SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_PKState, 0)
        #GameWorld.DebugLog("退出PK状态!", curPlayer.GetPlayerID())
        curPlayer.SetDict("StartProDTick", tick) # 开始恢复时间点
    bossStateTick = curPlayer.GetDictByKey(ChConfig.Def_PDict_BossStateTick)
    if bossStateTick and (tick - bossStateTick) >= validTime:
        curPlayer.SetDict(ChConfig.Def_PDict_BossStateTick, 0)
        PlayerControl.SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_BossState, 0)
        #GameWorld.DebugLog("退出Boss状态!", curPlayer.GetPlayerID())
    # 脱离PK战斗 X秒后按比例恢复
    ProcessProDef(curPlayer, tick)
    return
def Sync_PKBossState(curPlayer):
    psState = 1 if curPlayer.GetDictByKey(ChConfig.Def_PDict_PKStateTick) else 0
    PlayerControl.SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_PKState, psState)
@@ -1490,40 +1196,6 @@
    bossState = 1 if curPlayer.GetDictByKey(ChConfig.Def_PDict_BossStateTick) else 0
    PlayerControl.SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_BossState, bossState)
    return
# 脱离PK战斗 X秒后按比例恢复
def ProcessProDef(curPlayer, tick):
    if PlayerControl.GetProDefHPPer(curPlayer) == 0:
        # 没转化值
        return
    # 脱离PK战斗 X秒后按比例恢复
    if IsInPKState(curPlayer):
        return
    if tick - curPlayer.GetDictByKey("StartProDTick") < IpyGameDataPY.GetFuncCfg("MagicExterior", 2) * 1000:
        return
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
        return
    # 每秒恢复
    if tick - curPlayer.GetDictByKey("restoreProDTick") < 1000:
        return
    curProDef = PlayerControl.GetProDef(curPlayer)
    maxProDef = PlayerControl.GetMaxProDef(curPlayer)
    if curProDef == maxProDef:
        return
    #非PK状态恢复护盾
    PlayerControl.SetProDef(curPlayer, min(curProDef + \
                            IpyGameDataPY.GetFuncCfg("MagicExterior", 3)*maxProDef/ChConfig.Def_MaxRateValue, maxProDef))
    curPlayer.SetDict("restoreProDTick", tick)
    return
def IsInPKState(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PDict_PKStateTick) > 0
def SetPKStateTick(curPlayer, tick):