ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -18,23 +18,18 @@
import SkillShell
import BuffSkill
import PlayerControl
import EventShell
import PlayerRequest
import ChEquip
import SkillCommon
import FBLogic
import AttackCommon
import ChItem
import PlayerGMOper
import GameLogInfo
import PlayerMissionCollect
import ItemCommon
import OperControlManager
import ShareDefine
import PlayerAutoCheckOnline
import PlayerGameWallow
import ReadChConfig
import PlayerViewCacheTube
import PlayerDienstgrad
import PlayerVip
import IpyGameDataPY
@@ -46,7 +41,6 @@
import PetControl
import ItemControler
import PlayerGuaji
import PlayerTJG
import AICommon
import PlayerSuccess
import CrossPlayerData
@@ -59,12 +53,11 @@
import PlayerFlashSale
import PlayerChatBox
import PlayerFace
import PlayerWing
import ChEquip
import PlayerYinji
import PlayerActivity
import PlayerBackup
import MirrorAttack
import PlayerOnline
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -550,7 +543,7 @@
    
    if prepareState == IPY_GameWorld.pstDig:
        #挖宝状态
        EventShell.EventResponse_OnDig(curPlayer)
        pass
        
    elif prepareState == IPY_GameWorld.pstSkill:
        SkillShell.SkillPrepareEnd(curPlayer, tick)
@@ -566,11 +559,10 @@
    
    elif prepareState == IPY_GameWorld.pstTownPortal:
        #战斗中回城成功
        ChItem.UseTownPortal(curPlayer)
        pass
    
    elif prepareState == IPY_GameWorld.pstMissionCollecting:
        #任务采集
        PlayerMissionCollect.EndMissionCollect(curPlayer, tick)
        pass
        
    elif prepareState == ShareDefine.Def_PstTrans:
        
@@ -581,7 +573,7 @@
        if not TransCostAfterPrepare(curPlayer):
            return
        
        PlayerControl.PlayerResetWorldPos(curPlayer, mapID, posX, posY, False)
        PlayerControl.PlayerResetWorldPos(curPlayer, mapID, posX, posY)
        #PlayerControl.NotifyCode(curPlayer, "Map_Deliver_Succeed", [mapID])
        
    #重置玩家状态
@@ -677,25 +669,6 @@
        
    FBLogic.OnCollectOK(curPlayer, curNPC.GetNPCID(), tick)
    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
@@ -883,68 +856,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 玩家实例
@@ -1061,7 +972,6 @@
# @return 返回值, 无意义
# @remarks C++封包触发, 全局定时器, 处理玩家状态
def __Func_ProcessState(tick):
    timeClock = time.clock()
    #2009-07-01断言tick >=0 ,服务器tick为DWord,超过24天未重启硬件,将导致逻辑不可预知
    if tick < 0 :
        GameWorld.Log('###服务器运行时间超过24天 tick = %s' % (tick))
@@ -1075,87 +985,10 @@
        if curPlayer.GetID() == 0:
            continue
        
        ProcessPlayerState(curPlayer, tick)
    #记录玩家逻辑处理总耗时
    GameLogInfo.LogInfo_PlayerLogicTime(timeClock)
        ProcessPlayerState(curPlayer, tick)
    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 玩家实例
@@ -1177,117 +1010,56 @@
    PlayerBackup.CheckPlayerBackup(curPlayer)
    
    #玩家镜像战斗AI
    MirrorAttack.ProcessPlayerMirrorAI(curPlayer, tick)
    #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)
    
    #玩家数据缓存定时同步
    PlayerViewCacheTube.ProcessCache(curPlayer, tick)
    #脱机计算
    #PlayerTJG.ProcessPlayerTJG(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)
    #限时抢购
@@ -1297,15 +1069,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):
@@ -1379,45 +1151,7 @@
#        return
#===============================================================================
    return
#---------------------------------------------------------------------
##GM开关活动, 地图服务器给经验
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 返回值无意义
# @remarks GM开关活动, 地图服务器给经验
def ProcessMapGiveExp(curPlayer, tick):
    gameWorld = GameWorld.GetGameWorld()
    #经验倍率
    exp_Multiple = 0
    if gameWorld.IsEventActive(ChConfig.Def_GY_GM_GameID_MapGiveExp_Ten):
        exp_Multiple = 10
    elif gameWorld.IsEventActive(ChConfig.Def_GY_GM_GameID_MapGiveExp_Fifty):
        exp_Multiple = 50
    else:
        #无活动
        return
    mapExpTick = curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_GiveMapExp)
    if mapExpTick == 0:
        #第一次设定当前时间
        curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_GiveMapExp, tick)
        return
    if tick - mapExpTick < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_GiveMapExp]:
        #没有到刷新间隔
        return
    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_GiveMapExp, tick)
    reExp = 0
    playerControl = PlayerControl.PlayerControl(curPlayer)
    #玩家经验增加 参考经验 * 经验倍率
    playerControl.AddExp(reExp * exp_Multiple)
    return
#---------------------------------------------------------------------
##清空玩家连续击杀数量
# @param curPlayer 玩家实例
# @param tick 时间戳
@@ -1477,66 +1211,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)
@@ -1544,40 +1218,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):