hch
2019-04-20 945b1b54d5041f091bcb2b14a78b6c18bc4d93e5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -49,7 +49,6 @@
import PlayerLVAward
import PlayerGoldGift
import PlayerSignDay
import MixServerCampaign
import PlayerPet
import PlayerPrestigeSys
import PlayerFamily
@@ -65,13 +64,13 @@
import PlayerAttrFruit
import PlayerSuccess
import PlayerDienstgrad
import PlayerMixLoginDayAward
import PlayerFreeGoods
import PlayerRecover
import GameLogic_IceLode
import PlayerEquipDecompose
import PlayerGreatMaster
import PlayerGatherSoul
import PlayerFairyDomain
import PlayerCrossRealmPK
import GameFuncComm
import PlayerMagicWeapon
@@ -79,6 +78,7 @@
import GameLogic_FamilyWar
import PlayerBossReborn
import PlayerWeekParty
import PlayerFeastWeekParty
import PlayerActLogin
import Operate_EquipWash
import PlayerTreasure
@@ -102,6 +102,9 @@
import PlayerActTotalRecharge
import PlayerSpringSale
import PlayerFairyCeremony
import PlayerNewFairyCeremony
import PlayerFeastRedPacket
import PlayerLuckyTreasure
import CrossRealmPlayer
import ChNetSendPack
import FamilyRobBoss
@@ -111,6 +114,8 @@
import PlayerGeTui
import PlayerDogz
import PlayerCoat
import PlayerQuDaoDoubleBill
import PlayerFB
import datetime
import time
@@ -133,10 +138,6 @@
#@return 返回值无意义
#@remarks 玩家登陆游戏初始化
def InitLoginPlayer(curPlayer, tick):
    #初始化职业阶数,默认1
    if PlayerControl.GetJobRank(curPlayer) == 0:
        PlayerControl.SetJobRank(curPlayer, 1)
    ##初始化交易列表
    if curPlayer.GetTradeList().GetTradeItemCount() == 0:
        curPlayer.GetTradeList().SetTradeListCount(ChConfig.Def_PlayerTradeMaxItemCount)
@@ -225,6 +226,64 @@
    
    return
#// A2 31 前端开始自定义场景 #tagCMClientStartCustomScene
#
#struct    tagCMClientStartCustomScene
#{
#    tagHead        Head;
#    DWORD        MapID;
#    WORD        FuncLineID;
#};
def OnClientStartCustomScene(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    DoEnterCustomScene(curPlayer, clientData.MapID, clientData.FuncLineID)
    return
#// A2 33 前端退出自定义场景 #tagCMClientExitCustomScene
#
#struct    tagCMClientExitCustomScene
#{
#    tagHead        Head;
#};
def OnClientExitCustomScene(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    DoExitCustomScene(curPlayer)
    return
def DoEnterCustomScene(curPlayer, mapID, lineID):
    ## 进入自定义场景状态
    curPlayer.SetCanAttack(False)
    curPlayer.SetVisible(False)
    curPlayer.SetSight(0)
    curPet = curPlayer.GetPetMgr().GetFightPet()
    if curPet:
        curPet.SetVisible(False)
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomScene, 1) # 由于前端不一定有发mapID,所以这里额外记录这个状态,不能直接用mapID判断
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneMapID, mapID)
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneLineID, lineID)
    GameWorld.Log("玩家开始自定义场景!", curPlayer.GetPlayerID())
    if mapID:
        FBLogic.OnEnterCustomScene(curPlayer, mapID, lineID)
    return
def DoExitCustomScene(curPlayer):
    ## 退出自定义场景状态
    curPlayer.SetCanAttack(True)
    curPlayer.SetVisible(True)
    curPlayer.SetSight(1)
    curPlayer.RefreshView()
    curPlayer.SetSight(ChConfig.Def_PlayerSight_Default)
    curPlayer.RefreshView()
    curPet = curPlayer.GetPetMgr().GetFightPet()
    if curPet:
        curPet.SetVisible(True)
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomScene, 0)
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneMapID, 0)
    curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneLineID, 0)
    GameWorld.Log("玩家退出自定义场景!", curPlayer.GetPlayerID())
    return
#// A1 08 刷新主服角色信息 #tagCMRefreshMainServerRole
#
#struct tagCMRefreshMainServerRole
@@ -245,8 +304,16 @@
    playerControl = PlayerControl.PlayerControl(curPlayer)
    playerControl.ReCalcAllState()
    
    # 同步所有buff
    __Sync_ClientBuff(curPlayer)
    PlayerState.Sync_PKBossState(curPlayer)
    if PlayerControl.GetCrossMapID(curPlayer):
        CrossRealmPlayer.DoExitCrossRealm(curPlayer)
    if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):
        DoExitCustomScene(curPlayer)
        
    msgInfo = ""
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetPlayerID(), 0, 0, "RefreshMainServerRole", msgInfo, len(msgInfo))
@@ -427,14 +494,12 @@
        # 离线过久恢复为非跨服状态
        if PlayerControl.GetCrossMapID(curPlayer):
            PlayerControl.SetCrossMapID(curPlayer, 0)
        PyGameData.g_customFBPrizeInfo.pop(curPlayer.GetPlayerID(), None)
    SyncGuideState(curPlayer)
    
    #上线检查一次装备属性
    ItemControler.PlayerItemControler(curPlayer).CheckRolePackEquipAttr()
    #上线检查加点属性点
    PlayerControl.FixOldAddPoint(curPlayer)
    ItemControler.PlayerItemControler(curPlayer).CheckRolePackEquipAttr()
    #更新服务器组ID
    PlayerControl.UpdPlayerServerGroupID(curPlayer)
    
@@ -446,15 +511,10 @@
    
    #通知玩家技能信息
    __Sync_ClientSkill(curPlayer)
    #替换旧物品
    ItemControler.LoginCheckChangeOldItem(curPlayer)
    #清除生产采集Buff
    #PlayerControl.DelProduceBuff(curPlayer, tick)
    #清除国家答题Buff
    #PlayerExam.DoLogic_ExitExam(curPlayer, tick, needRefresh = False)
    #清除VIPbuff
    #BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_VIPExp_SkillTypeID, tick)
    #PlayerReincarnation.ReincarOnLogin(curPlayer)
    
    #通知玩家的buff
    __Sync_ClientBuff(curPlayer)
@@ -489,11 +549,11 @@
    SyncPKModel(curPlayer)
        
    #通用强化星级信息
    ChEquip.NotifyEquipPartStarLV(curPlayer)
    ChEquip.NotifyEquipPartPlusLV(curPlayer)
    ChEquip.NotifyEquipPartStar(curPlayer)
    Operate_EquipWash.OnEquipWashLogin(curPlayer)
    #通知套装信息
    ChEquip.NotifyEquipPartSuiteLV(curPlayer)
    ChEquip.SyncAllEquipAttrActiveInfo(curPlayer)
    #ChEquip.SyncAllEquipAttrActiveInfo(curPlayer)
    #装备位宝石镶嵌通知
    Operate_EquipStone.OnLogin(curPlayer)
    
@@ -539,9 +599,6 @@
    # 首充/天天首充/充值豪礼
    PlayerGoldGift.OnLogin(curPlayer)
    
    #玩家回归通知
    #PlayerRecall.PlayerBack(curPlayer)
    #通知购买功能中各购买类型的已购买和可购买次数
    Operate_PlayerBuyZhenQi.DoPlayerLogin(curPlayer)
#    
@@ -572,78 +629,54 @@
    #通知运行成功
    curPlayer.BalanceServer_PlayerLoginInitOK()
    
    # 新手指导员上线处理
#    #PlayerFreshmanGuide.FreshmanGuiderOnLogin(curPlayer)
#
    # 坐骑相关通知
    PlayerHorse.PlayerHorseLogin(curPlayer)
    
    PlayerTreasure.OnTreasureLogin(curPlayer)
    
#    # 通知累计登陆礼
    # 通知累计登陆礼
    PlayerLoginDayAward.OnLoginNotifyLoginDayAward(curPlayer)
#
    # 开服活动奖励信息
    OpenServerCampaign.OnOpenServerCampaignLogin(curPlayer)
#
#    # 通知合服奖励领取状态
#    PlayerMixLoginDayAward.OnLoginNotifyMixLoginDayAward(curPlayer)
#
#    # 通知合服奖励
#    MixServerCampaign.OnMixServerCampaignLogin(curPlayer)
#
#    # 节日登陆奖励
#    PlayerFestivalLogin.OnLoginFestivalLogin(curPlayer)
    # 试炼之塔
    GameLogic_TrialTower.OnFBPlayerLogin(curPlayer)
    # 古神禁地
    GameLogic_GodArea.GodAreaOnLogin(curPlayer)
#    # 采集NPC次数通知
    # 采集NPC次数通知
    NPCCommon.SyncCollNPCTime(curPlayer)
#
#    # 特惠活动
#    PlayerTeHui.PlayerLogin_TeHui(curPlayer)
#
#    # 自定义商店
#    ShopItemManage.DoOnLogin(curPlayer)
#
#    # 每日活跃度
    # 每日活跃度
    PlayerActivity.OnLogin(curPlayer)
#
#    # 副本进入时间
    # 副本进入时间
    FBCommon.FBOnLogin(curPlayer)
#
#    #天梯竞技场
#    HighLadderTube.OnLogin(curPlayer)
#
#    #世界等级
    #世界等级
    PlayerWorldAverageLv.OnLogin(curPlayer)
#
    # 投资理财
    PlayerGoldInvest.OnLogin(curPlayer)
#
#    #节日活动
#    PlayerAction.ActionOnLogin(curPlayer)
#
#    #属性果实使用情况
    #属性果实使用情况
    PlayerAttrFruit.AttrFruitOnLogin(curPlayer)
#
#    #成就
    #成就
    PlayerSuccess.SuccOnLogin(curPlayer)
#
#    #同步自动战斗配置记录
    #同步自动战斗配置记录
#    Sync_AutoFightSetting(curPlayer)
#
    PlayerFamily.FamilyPlayerOnLogin(curPlayer, tick)
    #改到 GameServerRefresh GameSever_PlayerInitOK后处理才能保证玩家已经在Gameserver注册
    #PlayerDienstgrad.RefreshBillBoardDienstgrad(curPlayer)
    # 称号
    PlayerDienstgrad.Sync_AllDienstgradOnLogin(curPlayer)
#    # 资源找回OnLogin
    # 资源找回OnLogin
    PlayerRecover.RecoverOnLogin(curPlayer)
#
#    # ʱװ
    # ʱװ
    PlayerCoat.OnLogin_Coat(curPlayer)
    
    # 跨服PK
@@ -664,21 +697,16 @@
    PlayerFlashGiftbag.OnPlayerLogin(curPlayer)
    #限时抢购
    PlayerFlashSale.OnPlayerLogin(curPlayer)
#    # 消费VIP
#    PlayerCostVIP.CostVIPOnLogin(curPlayer, tick)
#
#    # QQ相关奖励OnLogin
#    #PlayerQQ.Sync_QQAllAwardRecord(curPlayer)
#
#    # 世界boss
    # 世界boss
    BossHurtMng.OnLogin(curPlayer)
    ChItem.Sync_ItemDayUseCnt(curPlayer)
#    # 悬赏登录通知
#    PlayerArrestTask.OnLogin(curPlayer)
    # 悬赏登录通知
    #PlayerArrestTask.OnLogin(curPlayer)
    # 符印登录通知
    PlayerRune.PlayerRuneLogin(curPlayer)
    # 仙盟红包登录通知
    PlayerFamilyRedPacket.OnPlayerLogin(curPlayer)
    PlayerFeastRedPacket.DoPlayerOnLogin(curPlayer)
    # 法宝登录通知
    PlayerMagicWeapon.PlayerMagicWeaponLogin(curPlayer)
    # 商店物品购买次数登录通知
@@ -706,10 +734,14 @@
    PlayerBossReborn.OnLogin(curPlayer)
    # 周狂欢活动
    PlayerWeekParty.OnLogin(curPlayer)
    # 节日巡礼活动
    PlayerFeastWeekParty.OnLogin(curPlayer)
    # 登录奖励活动
    PlayerActLogin.OnLogin(curPlayer)
    # 仙界盛典活动
    PlayerFairyCeremony.OnLogin(curPlayer)
    # 新仙界盛典活动
    PlayerNewFairyCeremony.OnLogin(curPlayer)
    # 分支下载奖励记录通知
    SyncPackDownloadAward(curPlayer)
    # 登录触发功能开启(老号处理)
@@ -722,6 +754,8 @@
    PlayerBindJadeWheel.OnLogin(curPlayer)
    # 许愿池
    PlayerWishingWell.OnLogin(curPlayer)
    #幸运鉴宝
    PlayerLuckyTreasure.OnLogin(curPlayer)
    # 上线查询一次充值订单
    curPlayer.SendDBQueryRecharge()
    # 小助手
@@ -732,6 +766,10 @@
    FBHelpBattle.DoPlayerLogin(curPlayer)
    # 聚魂
    PlayerGatherSoul.PlayerLogin(curPlayer)
    #缥缈仙域
    PlayerFairyDomain.OnLogin(curPlayer)
    PlayerFB.OnLogin(curPlayer)
    curPlayer.SetState(0)   # 脱机挂恢复为正常上线
    curPlayer.SetFacePic(0) # 通知数据库是否保存还是下线,做一次恢复,1为保存 0为正常下线
    tjgTime = PlayerTJG.GetTJGTime(curPlayer)
@@ -741,6 +779,7 @@
    # 如果被禁言的,上线同步前端
    if curPlayer.GetGMForbidenTalk():
        curPlayer.SendPropertyRefresh(ShareDefine.CDBPlayerRefresh_ForbidenTalk, curPlayer.GetGMForbidenTalk(), False)
    return
@@ -764,37 +803,61 @@
    if not isMixServer:
        return
    
    lastMixServerDayKey = ShareDefine.Def_Notify_WorldKey_LastMixServerDay
    lastMixServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(lastMixServerDayKey)
    GameWorld.DebugLog("合服首登处理lastMixServerDay=%s" % lastMixServerDay, curPlayer.GetPlayerID())
    playerID = curPlayer.GetPlayerID()
    lastMixServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_LastMixServerDay)
    
    playerDay = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MixLoginDay)
    
    if playerDay == lastMixServerDay:
        GameWorld.DebugLog("本次合服已经登录过.")
        GameWorld.DebugLog("本次合服已经登录过. lastMixServerDay=%s" % (lastMixServerDay), playerID)
        return
    mixServerWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_LastMixServerWorldLV) # 合服时的世界等级
    GameWorld.Log("玩家合服首登处理! lastMixServerDay=%s,mixServerWorldLV=%s" % (lastMixServerDay, mixServerWorldLV), playerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MixLoginDay, lastMixServerDay)
    
    if curPlayer.GetLV() <= 1:
        GameWorld.Log("    新号不给合服奖励!", playerID)
        return
    # 重置首充双倍
    PlayerCoin.DoResetCTGCount(curPlayer, "MixServer")
    # 重置商店购买次数,暂定只重置类型 7 的
    FunctionNPCCommon.ResetShopItemBuyCount(curPlayer, [7])
    # 合服邮件,盟主专属邮件在GameServer处理
    mailItemList = IpyGameDataPY.GetFuncEvalCfg("MixServerMail", 1)
    worldLVMailItemList = IpyGameDataPY.GetFuncEvalCfg("MixServerMail", 2)
    mailMoneyList = IpyGameDataPY.GetFuncEvalCfg("MixServerMail", 3)
    worldLVDown = IpyGameDataPY.GetFuncCfg("MixServerMail", 5) # 等级丹相对合服世界等级差值
    itemWorldLV = max(150, mixServerWorldLV - worldLVDown)
    goldPaper, silver = mailMoneyList
    worldLVItemList = []
    for itemID, itemCount, isBind in worldLVMailItemList:
        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
        if not itemData:
            continue
        curEff = itemData.GetEffectByIndex(0)
        curEffID = curEff.GetEffectID()
        if curEffID != ChConfig.Def_Effect_ItemAddLV:
            continue
        lvLimit = curEff.GetEffectValue(1)
        if not lvLimit:
            continue
        if lvLimit <= itemWorldLV:
            worldLVItemList = [[itemID, itemCount, isBind]]
        else:
            break
    detailDict = {"MixServerWorldLV":mixServerWorldLV, "LastMixServerDay":lastMixServerDay, "ItemWorldLV":itemWorldLV}
    addItemList = mailItemList + worldLVItemList
    PlayerControl.SendMailByKey("MixServer1", [playerID], addItemList, goldPaper=goldPaper, silver=silver, detail=detailDict)
    GameWorld.Log("    发送合服补偿邮件: itemWorldLV=%s,addItemList=%s" % (itemWorldLV, addItemList), playerID)
    # 同步排行榜
    PlayerBillboard.UpdBillboardOnMixServerFirstLogin(curPlayer, lastMixServerDay)
    # 其他
    # ...
    # 重置登录奖励领取状态
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MixLoginDayState, 0)
    PlayerMixLoginDayAward.NotifyPlayerAwardState(curPlayer)
    # 重置各合服活动数据
    for campaignType in ShareDefine.Def_MixCampaign_Type_List:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MixServerCampaign_AwardRecord \
                                % campaignType, 0, ChConfig.Def_PDictType_OpenServerCampaign)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_MixServerCampaign_RecordData \
                                % campaignType, 0, ChConfig.Def_PDictType_OpenServerCampaign)
    PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=True)
    
    # 重置玩家改名次数
    UpdatePlayerName.ResetChangeNameCnt(curPlayer)
    #UpdatePlayerName.ResetChangeNameCnt(curPlayer)
    return
#---------------------------------------------------------------------
        
@@ -1029,7 +1092,8 @@
    #切地图要清除的buff
    __CheckClearBuffOnMapChange(curPlayer, tick)
    #上线和切地图加有限无敌Buff
    SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_LimitSuperBuff, tick)
    if curPlayer.GetLV() > 50:
        SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_LimitSuperBuff, tick)
            
    #刷新玩家的视野
    if not GameWorld.IsCrossServer() and PlayerControl.GetCrossMapID(curPlayer):
@@ -1282,7 +1346,7 @@
    #设置装备实际个数
    curPack = itemManager.GetPack(IPY_GameWorld.rptEquip)
    curPack.SetCount(ShareDefine.retMax)
    curPack.SetCount(ChConfig.Def_PackCnt_Equip)
    
    #初始化垃圾桶
    #curPack = itemManager.GetPack(IPY_GameWorld.rptRecycle)
@@ -1455,11 +1519,6 @@
    PlayerTeam.PlayerLoginSetTeam(curPlayer, tick)
    
    #要求数据库得到邮件状态
    #curPlayer.DataServer_GetPlayerMailState()
    #curPlayer.EndLoadMap()
    #激活玩家(保证持续性Buff处理间隔)
    PlayerControl.SetIsNeedProcess(curPlayer, True)
@@ -1512,7 +1571,7 @@
            GameWorld.Log('玩家登录重置位置失败, 设置附近点 nearPosX = %s nearPosY = %s' % (nearPosX, nearPosY) , curPlayer.GetPlayerID())
    #申请得到奖励物品
    curPlayer.DataServer_CheckPrizeItem()
    #curPlayer.DataServer_CheckPrizeItem()
    
    #===========================================================================
    # #if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Frist_Lock) == 1 \
@@ -1526,9 +1585,6 @@
    
    #防止玩家读取地图时未触发OnDay,读取地图后再次验证(2009.9.11)
    PlayerEventCounter.UpdatePlayerLoginTime(curPlayer)
    #特惠活动事件
    #PlayerTeHui.PlayerLoadMapOK(curPlayer)
    
    #设置阵营
    if curPlayer.GetFaction() != ChConfig.CampType_Neutral \
@@ -1674,80 +1730,103 @@
#@return 返回值无意义
#@remarks //03 01 加属性点#tagCAddPoint
def AddPoint(index, tick):
    GameWorld.GetPsycoFunc(__Func_AddPoint)(index, tick)
    return
##//03 01 加属性点#tagCAddPoint
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks //03 01 加属性点#tagCAddPoint
def __Func_AddPoint(index, tick):
#// B2 06 玩家加点 #tagCMAddPoint
#
#struct    tagCMAddPoint
#{
#    tagHead         Head;
#    BYTE        PointAttrIDCount;    // 加点属性ID个数
#    BYTE        PointAttrIDList[PointAttrIDCount];    // 加点属性ID列表
#    WORD        PointValueList[PointAttrIDCount];    // 加点属性ID对应的点数列表
#};
def OnAddPoint(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerControl = PlayerControl.PlayerControl(curPlayer)
    #JobQuotiety = PlayerControl.JobQuotiety
    pointAttrIDList = clientData.PointAttrIDList
    pointValueList = clientData.PointValueList
    if not pointAttrIDList or not pointValueList or len(pointAttrIDList) != len(pointValueList):
        return
    needTotalPoint = 0
    for i, attrID in enumerate(pointAttrIDList):
        if not IpyGameDataPY.GetIpyGameData("RolePoint", attrID):
            return
        needTotalPoint += pointValueList[i]
    curFreePoint = curPlayer.GetFreePoint()
    #job = curPlayer.GetJob()
    recvAddPoint = IPY_GameWorld.IPY_CAddPoint()
    addValue = recvAddPoint.GetPoint()
    #检验是否能够加点
    if addValue < 1 or addValue > curFreePoint:
        #检验不通过, 返回
        #GameWorld.ErrLog("(%s,%s)检验是否能够加点,检验不通过, 返回"%(addValue,curFreePoint) , curPlayer.GetPlayerID())
    if needTotalPoint > curFreePoint:
        GameWorld.DebugLog("剩余点数不足! curFreePoint(%s) < needTotalPoint(%s)" % (curFreePoint, needTotalPoint))
        return
    
    #封包加点类型
    addPointType = recvAddPoint.GetType()
    #加点
    if addPointType == ShareDefine.Def_Effect_STR:
        curPlayer.SetBaseSTR(addValue + curPlayer.GetBaseSTR())
    curPlayer.SetFreePoint(curFreePoint - needTotalPoint)
    for i, attrID in enumerate(pointAttrIDList):
        addPoint = pointValueList[i]
        curPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % attrID)
        updPoint = curPoint + addPoint
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_AddPointValue % attrID, updPoint)
        GameWorld.DebugLog("玩家加点: attrID=%s,curPoint=%s,addPoint=%s,updPoint=%s" % (attrID, curPoint, addPoint, updPoint))
        
    elif addPointType == ShareDefine.Def_Effect_PNE:
        curPlayer.SetBasePNE(addValue + curPlayer.GetBasePNE())
    elif addPointType == ShareDefine.Def_Effect_PHY:
        curPlayer.SetBasePHY(addValue + curPlayer.GetBasePHY())
    elif addPointType == ShareDefine.Def_Effect_CON:
        curPlayer.SetBaseCON(addValue + curPlayer.GetBaseCON())
    else:
        #异常超出边界
        GameWorld.ErrLog("AddPoint GetTypeErr = %s" % (addPointType) , curPlayer.GetID())
        return
    curPlayer.SetFreePoint(curFreePoint - addValue)
    DataRecordPack.DR_Freepoint(curPlayer, "AddPoint", curFreePoint, {"AddPointType":addPointType})
    playerControl.RefreshPlayerAttrState()
    NotifyPlayerBasePoint(curPlayer, pointAttrIDList)
    playerControl = PlayerControl.PlayerControl(curPlayer)
    playerControl.RefreshPlayerAttrState()
    return
def NotifyPlayerBasePoint(curPlayer):
    #上线通知基础属性点
    notifyList = []
    notifyBasePointDict = {
                 IPY_GameWorld.CDBPlayerRefresh_BaseSTR:'BaseSTR',
                 IPY_GameWorld.CDBPlayerRefresh_BasePHY:'BasePHY',
                 IPY_GameWorld.CDBPlayerRefresh_BaseCON:'BaseCON',
                 IPY_GameWorld.CDBPlayerRefresh_BasePNE:'BasePNE',
                }
    for refreshType, keyStr in notifyBasePointDict.items():
        notifyStruct = ChPyNetSendPack.tagRefreshType()
        notifyStruct.RefreshType = refreshType
        notifyStruct.Value = getattr(curPlayer, 'Get%s'%keyStr)()
        notifyList.append(notifyStruct)
def NotifyPlayerBasePoint(curPlayer, syncAttrIDList=[]):
    # 通知基础属性点,已分配的自由点数
    if not syncAttrIDList:
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        syncAttrIDList = [ipyDataMgr.GetRolePointByIndex(index).GetAttrID() for index in xrange(ipyDataMgr.GetRolePointCount())]
        
    #属性组合包 通知自己
    sendPack = ChPyNetSendPack.tagObjInfoListRefresh()
    pointAttrIDList = []
    pointValueList = []
    for attrID in syncAttrIDList:
        curPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AddPointValue % attrID)
        pointAttrIDList.append(attrID)
        pointValueList.append(curPoint)
    pointInfo = ChPyNetSendPack.tagMCRolePointInfo()
    pointInfo.PointAttrIDList = pointAttrIDList
    pointInfo.PointValueList = pointValueList
    pointInfo.PointAttrIDCount = len(pointAttrIDList)
    NetPackCommon.SendFakePack(curPlayer, pointInfo)
    return
#===============================================================================
# //B4 14 根据类型来决定移动的方式 #tagMCMoveByType
#
# struct    tagMCMoveByType
# {
#    tagHead        Head;
#    DWORD        ID;    //玩家ID
#    WORD        PosX;    // 目标X
#    WORD        PosY;    // 目标Y
#    BYTE        MoveType;    //移动方式
# };
#===============================================================================
def OnMoveByType(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #玩家移动通用检查
    if not __CheckPlayerCanMove(curPlayer):
        return
    #先验证目标点是否合法
    if not GameWorld.GetMap().CanMove(clientData.PosX, clientData.PosY):
        return
    curPlayer.StopMove()
    curPlayer.ChangePos(clientData.PosX, clientData.PosY)
    sendPack = ChPyNetSendPack.tagMCMoveByType()
    sendPack.Clear()
    sendPack.ObjID = curPlayer.GetID()
    sendPack.ID = curPlayer.GetID()
    sendPack.ObjType = curPlayer.GetGameObjType()
    sendPack.Count = len(notifyList)
    sendPack.RefreshType = notifyList
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    sendPack.PosX = clientData.PosX
    sendPack.PosY = clientData.PosY
    sendPack.MoveType = clientData.MoveType
    PlayerControl.PyNotifyAll(curPlayer, sendPack, False, -1)
    return
#===============================================================================
@@ -1781,7 +1860,15 @@
    #===========================================================================
    
    #超出视野
    if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), clientData.PosX, clientData.PosY) > curPlayer.GetSight():
    if curPlayer.GetSight() and GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), clientData.PosX, clientData.PosY) > curPlayer.GetSight():
        return
    #玩家移动通用检查
    if not __CheckPlayerCanMove(curPlayer):
        return
    #先验证目标点是否合法
    if not GameWorld.GetMap().CanMove(clientData.PosX, clientData.PosY):
        return
    
    curPlayer.StopMove()
@@ -2515,62 +2602,64 @@
#@return 返回值无意义
#@remarks 客户端封包响应//04 02 获取鼠标左键点击之后对象的详细信息#tagCClickObjGetInfo
def __Func_PlayerClickOtherPlayerGetInfo(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CClickObjGetInfo()
    sendPack_ID = sendPack.GetObjID()
    sendPack_Type = sendPack.GetObjType()
    tagObj = GameWorld.GetObj(sendPack_ID, sendPack_Type)
    if tagObj == None:
        #GameWorld.Log("玩家请求其他玩家的相貌信息失败, 对象不存在", curPlayer.GetPlayerID())
        return
    dist = GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), tagObj.GetPosX(), tagObj.GetPosY())
    #是否可以目标详细信息
    canGetDetail = (dist <= curPlayer.GetSight())
    #目标类型
    tagObjType = tagObj.GetGameObjType()
    #仅处理Player和NPC
    if tagObjType not in [IPY_GameWorld.gotPlayer, IPY_GameWorld.gotNPC]:
        return
    #---玩家处理---
    if tagObjType == IPY_GameWorld.gotPlayer:
        #获取玩家详细信息成功
        if canGetDetail:
            extendDataDict = {}
            extendDataDict['maxHP'] = tagObj.GetMaxHP()
            extendDataDict['maxMP'] = tagObj.GetMaxMP()
            extendDataDict['hit'] = tagObj.GetHit()
            extendDataDict['miss'] = tagObj.GetMiss()
            extendDataDict['atkSpeed'] = PlayerControl.GetAtkSpeed(tagObj)
            extendDataDict['superHitRate'] = tagObj.GetSuperHitRate()
            extendDataDict['superHit'] = tagObj.GetSuperHit()
            extendDataDict['luckyHitRate'] = tagObj.GetLuckyHitRate()
            extendDataDict['greatHitRate'] = tagObj.GetGreatHitRate()
            extendDataDict['ignoreDefRate'] = tagObj.GetIgnoreDefRate()
            extendDataDict['damageReduceRate'] = tagObj.GetDamageReduceRate()
            extendDataDict['damageBackRate'] = tagObj.GetDamageBackRate()
            extendData = str(extendDataDict)
            extendDataLen = len(extendData)
            curPlayer.PlayerClickOtherPlayerDetail(tagObj, extendDataLen, extendData)
            return
        #获取玩家详细信息失败
        curPlayer.Sync_GetPlayerInfoFail(sendPack_ID)
        return
    #---NPC处理---
    #获取NPC详细信息成功
    if canGetDetail:
        curPlayer.PlayerClickOtherNPCDetail(tagObj)
        return
    #===========================================================================
    # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #
    # sendPack = IPY_GameWorld.IPY_CClickObjGetInfo()
    # sendPack_ID = sendPack.GetObjID()
    # sendPack_Type = sendPack.GetObjType()
    #
    # tagObj = GameWorld.GetObj(sendPack_ID, sendPack_Type)
    #
    # if tagObj == None:
    #    #GameWorld.Log("玩家请求其他玩家的相貌信息失败, 对象不存在", curPlayer.GetPlayerID())
    #    return
    #
    # dist = GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), tagObj.GetPosX(), tagObj.GetPosY())
    # #是否可以目标详细信息
    # canGetDetail = (dist <= curPlayer.GetSight())
    # #目标类型
    # tagObjType = tagObj.GetGameObjType()
    #
    # #仅处理Player和NPC
    # if tagObjType not in [IPY_GameWorld.gotPlayer, IPY_GameWorld.gotNPC]:
    #    return
    #
    # #---玩家处理---
    # if tagObjType == IPY_GameWorld.gotPlayer:
    #    #获取玩家详细信息成功
    #    if canGetDetail:
    #        extendDataDict = {}
    #        extendDataDict['maxHP'] = tagObj.GetMaxHP()
    #        extendDataDict['maxMP'] = tagObj.GetMaxMP()
    #        extendDataDict['hit'] = tagObj.GetHit()
    #        extendDataDict['miss'] = tagObj.GetMiss()
    #        extendDataDict['atkSpeed'] = PlayerControl.GetAtkSpeed(tagObj)
    #        extendDataDict['superHitRate'] = tagObj.GetSuperHitRate()
    #        extendDataDict['superHit'] = tagObj.GetSuperHit()
    #        extendDataDict['luckyHitRate'] = tagObj.GetLuckyHitRate()
    #        extendDataDict['greatHitRate'] = tagObj.GetGreatHitRate()
    #        extendDataDict['ignoreDefRate'] = tagObj.GetIgnoreDefRate()
    #        extendDataDict['damageReduceRate'] = tagObj.GetDamageReduceRate()
    #        extendDataDict['damageBackRate'] = tagObj.GetDamageBackRate()
    #
    #        extendData = str(extendDataDict)
    #        extendDataLen = len(extendData)
    #        curPlayer.PlayerClickOtherPlayerDetail(tagObj, extendDataLen, extendData)
    #        return
    #
    #    #获取玩家详细信息失败
    #    curPlayer.Sync_GetPlayerInfoFail(sendPack_ID)
    #    return
    #
    # #---NPC处理---
    #
    # #获取NPC详细信息成功
    # if canGetDetail:
    #    curPlayer.PlayerClickOtherNPCDetail(tagObj)
    #    return
    #
    #===========================================================================
    #获取NPC详细信息失败
    #暂不处理
    return
@@ -4441,10 +4530,11 @@
#{
#    tagHead        Head;
#    DWORD        DataMapID;
#    WORD        LineID;
#};
def OnEnterCrossServer(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    PlayerControl.PlayerEnterCrossServer(curPlayer, clientData.DataMapID)
    PlayerControl.PlayerEnterCrossServer(curPlayer, clientData.DataMapID, clientData.LineID)
    return
    
#===============================================================================
@@ -5160,81 +5250,6 @@
                                         'RequestIsFamily', sendMsg, len(sendMsg))
    return
#===============================================================================
#// AF 02 合服活动奖励 #tagCMMixCampaignAward
#
#struct    tagCMMixCampaignAward
#
#{
#    tagHead         Head;
#    BYTE        Type;    //0-查询;1-领取
#    DWORD        CampaignType;        //奖励类型
#    BYTE        Index;    //奖励位,领取时用
#};
#===============================================================================
## 合服活动奖励
#  @param index: 玩家索引
#  @param clientData: 封包结构体
#  @param tick: 时间戳
#  @return:
def GiveMixServerCampaignAward(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    campaignType = clientData.CampaignType
    queryType = clientData.Type
    awardIndex = clientData.Index # 奖励位
    GameWorld.DebugLog("GiveMixServerCampaignAward campaignType=%s,queryType=%s,awardIndex=%s"
                       % (campaignType, queryType, awardIndex))
    if queryType == ShareDefine.Def_MSCGameServerQuery_MailAward:
        GameWorld.DebugLog("    客户端不可发领取合服邮件奖励类型")
        return
    isMix = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_IsMixServer)
    if not isMix:
        GameWorld.ErrLog("    当前非合服状态!")
        return
    if campaignType not in ShareDefine.Def_MixCampaign_Type_List:
        GameWorld.ErrLog("    合服活动类型错误campaignType=%s error! not define" % campaignType)
        return
    # 如果直接在MapServer中处理,则返回
    if MixServerCampaign.DoMixServerCampaignOnMapServer(curPlayer, campaignType, queryType, awardIndex):
        return
    awardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MixServerCampaign_AwardRecord \
                                % campaignType, 0, ChConfig.Def_PDictType_OpenServerCampaign)
    awardState = GameWorld.GetDataByDigitPlace(awardRecord, awardIndex)
    if awardState == MixServerCampaign.Def_AwardState_Got:
        if queryType == ShareDefine.Def_MSCGameServerQuery_QueryAward:
            recordData = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MixServerCampaign_RecordData \
                                % campaignType, 0, ChConfig.Def_PDictType_OpenServerCampaign)
            MixServerCampaign.Sync_MixServerCampaignAward(curPlayer, campaignType, awardState, recordData)
        GameWorld.DebugLog("    已经领取过该奖励...")
        return
    #领奖的需要等待GameServer回包以后才处理下一个封包
    if queryType != ShareDefine.Def_MSCGameServerQuery_QueryAward:
        if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_QueryMixServerAwardState) == 1:
            GameWorld.DebugLog("    已经在查询中...")
            return
    curPlayer.SetDict(ChConfig.Def_PlayerKey_QueryMixServerAwardState, 1)
    familyID = curPlayer.GetFamilyID()
    #[请求类型, 活动类型, 领取索引, 家族ID]
    msgList = [queryType, campaignType, awardIndex, familyID]
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, 'MixServerCampaignAward', \
            '%s' % (msgList), len(str(msgList)))
    GameWorld.DebugLog("    msgList=%s" % str(msgList))
    return
#===============================================================================
## 领取奖励表奖励
@@ -5298,9 +5313,6 @@
    # 首充礼包奖励
    elif rewardType == ChConfig.Def_RewardType_GoldGiftFirst:
        PlayerGoldGift.GetPlayerGoldGiftFirst(curPlayer)
    # 领取法宝之魂奖励
    elif rewardType == ChConfig.Def_RewardType_MWSoulAward:
        PlayerMagicWeapon.GetMWSoulAward(curPlayer, dataEx)
    # 领取极品白拿
    elif rewardType == ChConfig.Def_RewardType_FreeGoods:
        PlayerFreeGoods.OnGetFreeGoods(curPlayer, dataEx)
@@ -5340,7 +5352,22 @@
    # 领取登录奖励活动奖励
    elif rewardType == ChConfig.Def_RewardType_ActLoginAwardAct:
        PlayerActLogin.GetLoginAwardActionAward(curPlayer, dataEx, dataExStr)
    # 领取新仙界盛典充值大礼
    elif rewardType == ChConfig.Def_RewardType_NewFairyCRecharge:
        PlayerNewFairyCeremony.GetFCRechargeAward(curPlayer)
    # 领取新仙界盛典全民来嗨
    elif rewardType == ChConfig.Def_RewardType_NewFairyCParty:
        PlayerNewFairyCeremony.GetFCPartyAward(curPlayer, dataEx)
    # 领取节日巡礼活动奖励
    elif rewardType == ChConfig.Def_RewardType_FeastWeekPartyAct:
        PlayerFeastWeekParty.GetFeastWeekPartyActionAward(curPlayer, dataEx, dataExStr)
    # 领取节日巡礼积分奖励
    elif rewardType == ChConfig.Def_RewardType_FeastWeekPartyPoint:
        PlayerFeastWeekParty.GetFeastWeekPartyPointAward(curPlayer, dataEx, dataExStr)
    #缥缈奇遇领取
    elif rewardType == ChConfig.Def_RewardType_FairyAdventuresAward:
        PlayerFairyDomain.GetFairyAdventuresAward(curPlayer, dataEx, dataExStr)
    return
    
    
@@ -5789,7 +5816,7 @@
        PlayerControl.SendMailByKey('SubpackageDownload', [curPlayer.GetID()], awardItemList)
    else:
        for itemID, itemCnt, isBind in awardItemList:
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [IPY_GameWorld.rptItem])
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, 0, [IPY_GameWorld.rptItem])
    SyncPackDownloadAward(curPlayer)
    return