5722 【后端】【1.5】跨服BOSS开发(跨服采集支持,采集支持配置共享采集次数)
10个文件已修改
1个文件已删除
928 ■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossPenglai.py 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Dogz.py 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 636 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_ClientServerReceiveMsg.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossServerReceiveMsg.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -214,7 +214,7 @@
Writer = alee
Releaser = alee
RegType = 0
RegisterPackCount = 9
RegisterPackCount = 10
PacketCMD_1=0xA2
PacketSubCMD_1=0x03
@@ -251,6 +251,10 @@
PacketCMD_9=0xA2
PacketSubCMD_9=0x25
PacketCallFunc_9=ClientTaskCount
PacketCMD_10=0xC1
PacketSubCMD_10=0x06
PacketCallFunc_10=OnCrossNPCTalk
;VIP功能
[PlayerVip]
@@ -868,9 +872,9 @@
PacketSubCMD_1=0x52
PacketCallFunc_1=OnBuyCollectionCnt
PacketCMD_2=0xA2
PacketSubCMD_2=0x20
PacketCallFunc_2=OnOpenCollNPCBox
PacketCMD_2=
PacketSubCMD_2=
PacketCallFunc_2=
PacketCMD_3=0xA5
PacketSubCMD_3=0x0A
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1890,7 +1890,6 @@
                'XMZZ':[Def_FBMapID_XMZZ], #仙魔之争
                'Dogz':[Def_FBMapID_Dogz], #神兽副本
                'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
                'CrossPenglai':[Def_FBMapID_CrossPenglai], #跨服蓬莱仙境
                'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
                }
@@ -3483,9 +3482,6 @@
Def_PDict_FreshmanGuideSpeakerCntToday = "FreshmanGuideSpeakerCntDay"  # 新手指导员今日已免费传音次数
Def_PDict_LoginDayCnt = "PLoginDayCnt"  # 累计登陆天数
Def_PDict_LoginDayAward = "PLoginDayAward"  # 累计登陆领取情况
Def_PDict_CollNpcCollTotalCnt = "CollNpcCollTotalCnt_%s"   # 采集NPC累计采集次数,参数为NPCID
Def_PDict_CollNpcCollTime = "CollNpcCollTime_%s"   # 采集NPC功能号对应每日对应采集次数,%sNPC功能号
Def_PDict_CollNpcBuyTime = "CollNpcBuyTime_%s"   # 采集NPC功能号对应每日购买采集次数,%sNPC功能号
Def_PDict_CollNpcIDCollTime = "CollNpcIDCollTime_%s"   # 采集NPCID对应每日对应采集次数,%sNPCID
Def_PDict_ShopItemDayBuyCnt = "ShopItemDayBuyCnt_%s"   # 商店NPC商品已购买次数,itemIndex
Def_PDict_ShopItemStartTime = "ShopItemStartTime_%s"   # 神秘限购商品开卖时间,itemIndex
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py
@@ -229,6 +229,61 @@
    EventLogic(curPlayer, sendPack_EventNPCID, tick)
    return
#// C1 06 跨服NPC对话 #tagCMCrossNPCTalk
#
#struct    tagCMCrossNPCTalk
#{
#    tagHead        Head;
#    WORD        ObjID;
#    DWORD        NPCID;
#    WORD        PosX;
#    WORD        PosY;
#};
def OnCrossNPCTalk(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    objID = clientData.ObjID
    npcID = clientData.NPCID
    #posX = clientData.PosX
    #posY = clientData.PosY
    if GameWorld.IsCrossServer():
        return
    lastTick = curPlayer.GetDictByKey("CrossNPCTalkTick")
    if tick - lastTick < 2000:
        return
    curPlayer.SetDict("CrossNPCTalkTick", tick)
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
    if not npcData:
        GameWorld.ErrLog("跨服NPCID不存在! npcID=%s" % npcID)
        return
    # 目前暂支持跨服采集
    if npcData.GetType() not in [IPY_GameWorld.ntCollection, IPY_GameWorld.ntMissionCollect]:
        return
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
    if collectNPCIpyData:
        if not NPCCommon.CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):
            return
        msgDict = {"PlayerID":curPlayer.GetPlayerID(), "ObjID":objID, "NPCID":npcID}
        GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_CollectNPC, msgDict)
    return
def ClientServerMsg_CollectNPC(curPlayer, msgData, serverGroupID, tick):
    ## 收到子服同步的采集NPC
    objID = msgData["ObjID"]
    npcID = msgData["NPCID"]
    curNPC = GameWorld.FindNPCByID(objID)
    if npcID !=  curNPC.GetNPCID():
        GameWorld.ErrLog("采集跨服NPC错误!npcID=%s != curNPCID=%s" % (npcID, curNPC.GetNPCID()))
        return
    EventLogic(curPlayer, objID, tick)
    return
##客户端//08 01封包响应 自定义函数: 事件处理
#@param curPlayer 当前玩家
#@param eventNPCID 事件NPCID
@@ -288,9 +343,10 @@
        return
    
    curPlayer.SetActionObj(curNPC)
    if curNPC.GetNPCID() in ReadChConfig.GetEvalChConfig("CollectNPCLostHP"):
        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
    if NPCCommon.OnCollectNPCBegin(curPlayer, curNPC, tick):
        return
    prepareTime = FBLogic.GetFBPrepareTime(curPlayer, curNPC)
    
    collTimeReduceRate = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_CollTimeReduceRate)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py
@@ -17,7 +17,7 @@
import ChConfig
import PlayerControl
import ReadChConfig
import IpyGameDataPY
import NPCCommon
import GameWorld
#---------------------------------------------------------------------
@@ -31,20 +31,22 @@
#  @param list 参数列表 [npcID]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, list):
    # 清总采集次数
    collectNPCCfg = ReadChConfig.GetEvalChConfig('CollectNPCCfg')
    for npcID in collectNPCCfg.keys():
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTotalCnt % npcID, 0)
    # 清NPCID每日采集次数
    collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
    for npcIDTuple in collectNPCIDTimeLimit.keys():
        for npcID in npcIDTuple:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)
def OnExec(curPlayer, paramList):
    
    NPCCommon.SyncCollNPCTime(curPlayer)
    resetNPCIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetCollectNPCCount()):
        ipyData = ipyDataMgr.GetCollectNPCByIndex(index)
        npcID = ipyData.GetNPCID()
        if not ipyData.GetMaxCollectCount():
            continue
        if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID):
            continue
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)
        resetNPCIDList.append(npcID)
    if resetNPCIDList:
        NPCCommon.SyncCollNPCTime(curPlayer, resetNPCIDList)
        
    GameWorld.DebugAnswer(curPlayer, "重置采集NPC成功")
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossPenglai.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Dogz.py
@@ -42,8 +42,6 @@
Map_Dogzfb_NextNeedTime = "NextNeedTime%s"  # 下次刷新需要时间 参数npcid
Map_Dogzfb_LastCheckTick = "LastCheckTick"  # 上次检查时间
Map_Dogzfb_NPCRemainCnt = 'NPCRemainCnt_%s'   # NPC剩余数量
Map_Dogzfb_CollectLostHPTick = 'CollectLostHPTick'   # 采集掉血Tick
Map_Dogzfb_CollectLostHPCnt = 'CollectLostHPCnt'   # 采集掉血次数
## 是否能够通过活动查询进入
#  @param curPlayer 玩家实例
@@ -104,66 +102,6 @@
#  @return None
def DoFBAction(curPlayer, actionType, actionInfo, tick):
    
    return
## 开始采集
#  @param curPlayer 当前玩家
#  @param curNPC 当前NPC
#  @return None or False
#  @remarks 函数详细说明.
def OnBeginCollect(curPlayer, curNPC):
    playerID = curPlayer.GetID()
    tick = GameWorld.GetGameWorld().GetTick()
    gameFB = GameWorld.GetGameFB()
    gameFB.SetPlayerGameFBDict(playerID, Map_Dogzfb_CollectLostHPTick, tick)
    gameFB.SetPlayerGameFBDict(playerID, Map_Dogzfb_CollectLostHPCnt, 0)
    return
## 收集中
def OnCollecting(curPlayer, tick):
    tagObj = curPlayer.GetActionObj()
    if not tagObj:
        return
    if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:
        return
    curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())
    npcID = curNPC.GetNPCID()
    __DoCollectLostHP(curPlayer, npcID, tick)
    return
def __DoCollectLostHP(curPlayer, npcID, tick):
    playerID = curPlayer.GetID()
    gameFB = GameWorld.GetGameFB()
    collectLostHPTick = gameFB.GetPlayerGameFBDictByKey(playerID, Map_Dogzfb_CollectLostHPTick)
    lostHPCnt = gameFB.GetPlayerGameFBDictByKey(playerID, Map_Dogzfb_CollectLostHPCnt)
    lostCD = IpyGameDataPY.GetFuncEvalCfg('DogzFBCollect', 1, {}).get(npcID, 1)
    lostTime = (tick - collectLostHPTick) / (1000*lostCD)-lostHPCnt
    if not lostTime:
        return
    gameFB.SetPlayerGameFBDict(playerID, Map_Dogzfb_CollectLostHPCnt, lostHPCnt+lostTime)
    lostHPPer = IpyGameDataPY.GetFuncEvalCfg('DogzFBCollect', 2, {}).get(npcID, 1)
    skillTypeID, buffOwner = 0, None
    lostValue = min(int(GameObj.GetMaxHP(curPlayer) * lostHPPer / 100.0) * lostTime, GameObj.GetHP(curPlayer)-1)
    if lostValue <=0:
        return
    GameWorld.DebugLog("OnCollecting npcID=%s, lostHPPer=%s,lostTime=%s,lostValue=%s" % (npcID, lostHPPer, lostTime, lostValue))
    SkillCommon.SkillLostHP(curPlayer, skillTypeID, buffOwner, lostValue, tick)
    return
##玩家收集成功(塔, 旗)
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 无意义
# @remarks
def OnCollectOK(curPlayer, npcID, tick):
    __DoCollectLostHP(curPlayer, npcID, tick)
    return
##---副本总逻辑计时器---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -55,6 +55,7 @@
import PlayerWeekParty
import FamilyRobBoss
import IpyGameDataPY
import PlayerState
import PyGameData
import PlayerTeam
import PlayerVip
@@ -5247,130 +5248,87 @@
) = range(Def_CollNPCCfg_Len)
## 该NPC可否同时采集
#  @param curNPC:采集NPC实例
#  @return False-不可以,True-可以
def CanNPCCollectTogether(curNPC):
    npcID = curNPC.GetNPCID()
    collectNPCCfg = ReadChConfig.GetEvalChConfig('CollectNPCCfg')
    if npcID not in collectNPCCfg:
def CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):
    # 根据NPCID判断是否可以采集
    if GameWorld.IsCrossServer():
        return True
    
    collectNPCInfo = collectNPCCfg[npcID]
    if len(collectNPCInfo) != Def_CollNPCCfg_Len:
        return True
    canCollTogether = collectNPCInfo[Def_CollNPCCfg_CanTogether]
    return canCollTogether
## 采集NPC开始采集
#  @param curPlayer:采集玩家实例
#  @param curNPC:采集NPC实例
#  @return False-非采集NPC,True-是采集NPC逻辑
def DoCollectNPCBegin(curPlayer, curNPC):
    npcID = curNPC.GetNPCID()
    collectNPCCfg = ReadChConfig.GetEvalChConfig('CollectNPCCfg')
    if npcID not in collectNPCCfg:
        GameWorld.DebugLog("DoCollectNPCBegin 非特定采集NPC...")
    limitMaxTime = collectNPCIpyData.GetMaxCollectCount()
    if limitMaxTime > 0 and GetTodayCollectCount(curPlayer, npcID) >= limitMaxTime:
        PlayerControl.NotifyCode(curPlayer, collectNPCIpyData.GetCollectCountLimitNotify(), [limitMaxTime])
        return False
    
    collectNPCInfo = collectNPCCfg[npcID]
    if len(collectNPCInfo) != Def_CollNPCCfg_Len:
        GameWorld.ErrLog("CollectNPCCfg.txt配置错误,npcID=%s" % npcID)
        return True
    #如果是打坐召唤的NPC
    isSitCollect = npcID == IpyGameDataPY.GetFuncCfg('RealmSitNPCID')
    if isSitCollect:
        summonOwner = GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)
        #ownerDetail = GetNpcObjOwnerDetail(curNPC)
        if not summonOwner:
            return True
        if summonOwner.GetID() == curPlayer.GetID():
            GameWorld.DebugLog("不能采集自己的打坐召唤兽 summonOwner.GetID()=%s" % summonOwner.GetID())
            return True
    #背包空间判断
    if collectNPCIpyData.GetCollectAward() and not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_202580")
        return False
    
    canCollTogether = collectNPCInfo[Def_CollNPCCfg_CanTogether]
    #消耗物品采集,待扩展...
    return True
def GetTodayCollectCount(curPlayer, npcID):
    ## 获取采集NPC今日已采集次数
    todayCollTime = 0
    collectTimeShareIDList = IpyGameDataPY.GetFuncEvalCfg("CollectNPC", 1)
    for npcIDList in collectTimeShareIDList:
        if npcID not in npcIDList:
            continue
        for collNPCID in npcIDList:
            todayCollTime += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % collNPCID)
        return todayCollTime
    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
def OnCollectNPCBegin(curPlayer, curNPC, tick):
    ## 采集NPC开始采集
    npcID = curNPC.GetNPCID()
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
    if not collectNPCIpyData:
        GameWorld.DebugLog("非特定采集NPC...")
        return False
    if not CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):
        return True
    canCollTogether = 1
    collectPlayerID = GetCollectNPCPlayerID(curNPC)
    # 如果不允许同时采,且有人在采,则直接返回
    if not canCollTogether and collectPlayerID > 0 and collectPlayerID != curPlayer.GetPlayerID():
        GameWorld.DebugLog("DoCollectNPCBegin 不允许同时采集!")
        sysMark = collectNPCInfo[Def_CollNPCCfg_SysMsgMark]
        GameWorld.DebugLog("不允许同时采集!")
        sysMark = "GeRen_liubo_436832"
        if sysMark:
            PlayerControl.NotifyCode(curPlayer, sysMark)
        return True
    
    # 采集次数判断
    limitMaxTime, todayCollTime = 0, 0
    collLimitInfo = GetCollTimeLimitInfo(curPlayer, npcID)
    if collLimitInfo:
        limitMaxTime, todayCollTime = collLimitInfo
    if limitMaxTime > 0 and todayCollTime >= limitMaxTime:
        PlayerControl.NotifyCode(curPlayer, collectNPCInfo[Def_CollNPCCfg_LimitSysMsgMark], [limitMaxTime])
        return True
    DoCollectNPCBegin(curPlayer, curNPC, collectNPCIpyData, tick)
    return True
def DoCollectNPCBegin(curPlayer, curNPC, collectNPCIpyData, tick):
    ## 开始采集
    
    # 采集消耗
    isAutoBuy = True #默认自动购买
    costItemInfo = collectNPCInfo[Def_CollNPCCfg_CostItemInfo]
    if costItemInfo:
        costItemID, costItemCnt = costItemInfo
        if costItemID > 0:
            itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
            enough, indexList, hasBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(
                                                        costItemID, itemPack, costItemCnt)
            if not enough and not isAutoBuy:
                GameWorld.DebugLog("DoCollectNPCLogic 采集消耗物品不足,npcID=%s,costItemID=%s,cnt=%s" \
                                   % (npcID, costItemID, costItemCnt))
                PlayerControl.NotifyCode(curPlayer, collectNPCInfo[Def_CollNPCCfg_NotCostItemNotify],
                                         [npcID, costItemID, costItemCnt])
                return True
            # 改为在采集成功后扣除道具
            #ItemCommon.ReduceItem(curPlayer, itemPack, indexList, costItemCnt, False)
    #背包空间判断
    if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_202580")
        return True
    canCollTogether = 1
    if not canCollTogether and not SetCollectNPC(curPlayer, curNPC):
        GameWorld.ErrLog("DoCollectNPCBegin SetCollectNPC fail!")
        return True
        GameWorld.ErrLog("SetCollectNPC fail!")
        return
    
    # 采集耗时
    prepareTime = collectNPCInfo[Def_CollNPCCfg_PrepareTime]
    prepareTime = collectNPCIpyData.GetPrepareTime() * 1000
    collTimeReduceRate = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_CollTimeReduceRate)
    if collTimeReduceRate:
        prepareTime = max(1000, int(prepareTime * (ShareDefine.Def_MaxRateValue - collTimeReduceRate) / float(ShareDefine.Def_MaxRateValue)))
    PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, IPY_GameWorld.pstMissionCollecting, \
                                    prepareID=curNPC.GetID())
    PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, IPY_GameWorld.pstMissionCollecting, prepareID=curNPC.GetID())
    if collectNPCIpyData.GetLostHPPer():
        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
    FBLogic.OnBeginCollect(curPlayer, curNPC)
    ##添加这个NPC的伤血列表,用于判断可否同时采集,改为字典判断
    AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1)
    return
def GetCollTimeLimitInfo(curPlayer, npcID):
    ## 获取采集次数限制信息
    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
    for npcIDTuple in npcIDCollectCntLimitDict.keys():
        if npcID not in npcIDTuple:
            continue
        limitMaxTime = npcIDCollectCntLimitDict[npcIDTuple][0]
        todayCollTime = 0
        for collNPCID in npcIDTuple:
            todayCollTime += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % collNPCID)
        GameWorld.DebugLog("    limitMaxTime=%s,todayCollTime=%s" % (limitMaxTime, todayCollTime))
        return limitMaxTime, todayCollTime
    return
## 设置玩家采集该NPC
#  @param curPlayer:玩家实例
#  @param curNPC:采集NPC实例
#  @return False-失败,True-成功
def SetCollectNPC(curPlayer, curNPC):
    ## 设置玩家采集该NPC
    curPlayerID = curPlayer.GetPlayerID()
    curNPCObjID = curNPC.GetID()
    curCollectPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_CollectPlayerID)
@@ -5423,391 +5381,125 @@
    #GameWorld.DebugLog("    set collectNPCObjID 0")
    return
## 采集NPC采集结束
#  @param curPlayer:采集玩家实例
#  @param npcID:采集NPCID
#  @return False-非采集NPC,True-是采集NPC逻辑
def DoCollectNPCOK(curPlayer, npcID):
    isOK = DoGetCollectionNPCAwardLogic(curPlayer, npcID, True, 1)
    ClearCollectNPC(curPlayer)
    return isOK
#// A2 20 开启采集NPC奖励箱子 #tagCMOpenCollNPCBox
#
#struct    tagCMOpenCollNPCBox
#{
#    tagHead        Head;
#    DWORD        MapID;        //MapID
#    DWORD        NPCID;        //NPCID
#    BYTE        OpenCnt;        //开启次数
#    BYTE        IsAutoBuy;    //消耗道具不足是否自动购买
#    BYTE        IsOnlyGold;    //是否只消耗钻石
#};
def OnOpenCollNPCBox(index, clientData, tick):
    mapID = clientData.MapID
    npcID = clientData.NPCID
    openCnt = clientData.OpenCnt
    isAutoBuy = clientData.IsAutoBuy
    isOnlyGold = clientData.IsOnlyGold
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    collLimitInfo = GetCollTimeLimitInfo(curPlayer, npcID)
    if not collLimitInfo:
        GameWorld.DebugLog("该NPC不是自定义采集NPC箱子, 不可开启! npcID=%s" % npcID)
def DoCollectNPCOK(curPlayer, npcID, tick):
    ## 采集NPC采集结束
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
    if not collectNPCIpyData:
        GameWorld.DebugLog("    非特定采集NPC...npcID=%s" % npcID)
        return
    GameWorld.DebugLog("OnOpenCollNPCBox...npcID=%s,openCnt=%s,isAutoBuy=%s" % (npcID, openCnt, isAutoBuy))
    DoGetCollectionNPCAwardLogic(curPlayer, npcID, isAutoBuy, openCnt, mapID, isOnlyGold)
    PlayerState.DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, True)
    if GameWorld.IsCrossServer():
        # 发送回本服采集完成
        serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
        msgInfo = {"Result":1, "PlayerID":curPlayer.GetPlayerID(), "NPCID":npcID}
        GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_CollectNPCOK, msgInfo, [serverGroupID])
    else:
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)
    FBLogic.OnCollectOK(curPlayer, npcID, tick)
    ClearCollectNPC(curPlayer)
    return True
def CrossServerMsg_CollectNPCOK(curPlayer, msgData):
    ## 收到跨服同步的采集完成
    if not msgData["Result"]:
        return
    npcID = msgData["NPCID"]
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
    if collectNPCIpyData:
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)
    return
## isOnlyGold:是否全消耗钻石,不扣道具
def DoGetCollectionNPCAwardLogic(curPlayer, npcID, isAutoBuy=False, collectCnt=1, mapID=None, isOnlyGold=False):
    GameWorld.DebugLog("DoGetCollectionNPCAwardLogic...npcID=%s,collectCnt=%s" % (npcID, collectCnt))
    collectNPCCfg = ReadChConfig.GetEvalChConfig('CollectNPCCfg')
    if npcID not in collectNPCCfg:
        GameWorld.DebugLog("    非特定采集NPC...npcID=%s" % npcID)
        return False
def DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, collectCnt=1):
    GameWorld.DebugLog("给采集奖励: npcID=%s,collectCnt=%s" % (npcID, collectCnt))
    if collectCnt <= 0:
        return True
    collectNPCInfo = collectNPCCfg[npcID]
    if len(collectNPCInfo) != Def_CollNPCCfg_Len:
        GameWorld.ErrLog("CollectNPCCfg.txt配置错误,npcID=%s" % npcID)
        return True
        return
    
    # 采集消耗
    costItemID, costItemCnt = 0, 0
    costItemInfo = collectNPCInfo[Def_CollNPCCfg_CostItemInfo]
    if costItemInfo and len(costItemInfo) == 2:
        costItemID, costItemCnt = costItemInfo
    curNPC = GameWorld.GetGameData().FindNPCDataByID(npcID)
    if not curNPC:
        return True
    limitMaxTime = 0 # 0表示不限制次数
    todayCollTime = 0
    # 根据NPCID
    collLimitInfo = GetCollTimeLimitInfo(curPlayer, npcID)
    if collLimitInfo:
        limitMaxTime, todayCollTime = collLimitInfo
    limitMaxTime = collectNPCIpyData.GetMaxCollectCount()
    if limitMaxTime > 0:
        todayCollTime = GetTodayCollectCount(curPlayer, npcID)
        canCollectCnt = max(0, limitMaxTime - todayCollTime)
        collectCnt = min(collectCnt, canCollectCnt)
        if collectCnt <= 0:
            GameWorld.DebugLog("    该NPC已达到最大采集次数: todayCollTime=%s,limitMaxTime=%s" % (todayCollTime, limitMaxTime))
            return True
            return
        
    costItemCntTotal = costItemCnt * collectCnt
    # 需要消耗道具的情况
    bindCnt = 0
    if costItemID > 0 and costItemCntTotal > 0:
        costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID)
        lackCnt = max(0, costItemCntTotal - bindCnt - unBindCnt) if not isOnlyGold else costItemCntTotal
        lackCost = 0 # 缺少道具个数
        itemGold = 0 # 自动购买单价
        if lackCnt > 0 and not isAutoBuy:
            GameWorld.DebugLog("    采集消耗物品不足,npcID=%s,costItemID=%s,costItemCnt=%s,collectCnt=%s,hasCnt=(%s+%s)" \
                               % (npcID, costItemID, costItemCnt, collectCnt, bindCnt, unBindCnt))
            PlayerControl.NotifyCode(curPlayer, collectNPCInfo[Def_CollNPCCfg_NotCostItemNotify],
                                     [npcID, costItemID, costItemCnt])
            return True
        if lackCnt > 0:
            itemGold = PlayerSuperMarket.GetStoreItemPrice(costItemID, IPY_GameWorld.TYPE_Price_Gold_Money)
            lackCost = lackCnt * itemGold
            if lackCost <= 0:
                return True
            if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, lackCost, True):
                return True
    giveItemInfoList = []
    # 饼图随机表, 独立概率随机表
    prizeInfo = __GetGiveCollectItemInfo(curPlayer, collectNPCInfo[Def_CollNPCCfg_GiveItemModeID])
    pieRandomList, randomAllInfoList = prizeInfo[:2]
    besureInfoList = prizeInfo[2] if len(prizeInfo) > 2 else [] # 按次数必出配置
    if not mapID:
        mapID = GameWorld.GetMap().GetMapID()
    successCnt = 0 # 成功次数
    if pieRandomList or randomAllInfoList:
        for i in xrange(collectCnt):
            isBind = 1 if successCnt < bindCnt else 0
            getItemInfo = __DoGiveCollectionNPCSingleAward(curPlayer, mapID, npcID, isBind, pieRandomList, randomAllInfoList, besureInfoList)
            if not getItemInfo:
                break
            giveItemInfoList.extend(getItemInfo)
            successCnt += 1
        if successCnt <= 0:
            return True
    else:
        successCnt = collectCnt
    # 给额外奖励
    reLV = curPlayer.GetLV()
    reExp = PlayerControl.GetPlayerReExp(curPlayer)
    reMoney = PlayerControl.GetPlayerReMoney(curPlayer)
    addExp = eval(collectNPCInfo[Def_CollNPCCfg_ExpFormat]) * successCnt
    addMoney = eval(collectNPCInfo[Def_CollNPCCfg_MoneyFormat]) * successCnt
    addZhenQi = collectNPCInfo[Def_CollNPCCfg_ZhenQi] * successCnt
    playerControl = PlayerControl.PlayerControl(curPlayer)
    playerControl.AddExp(addExp)
    addDataDict = {ChConfig.Def_Give_Reason_SonKey:npcID}
    PlayerControl.GiveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, addMoney,
                            ChConfig.Def_GiveMoney_CollectNPC, addDataDict)
    PlayerControl.PlayerAddZhenQi(curPlayer, addZhenQi, True, True, "Collection")
    GameWorld.DebugLog("    successCnt=%s,addExp=%s,addMoney=%s,addZhenQi=%s"
                       % (successCnt, addExp, addMoney, addZhenQi))
    # 需要消耗道具的情况, 扣除消耗
    if costItemID > 0 and costItemCntTotal > 0:
        unCostCnt = successCnt # 未扣除的消耗个数
        if not isOnlyGold:
            bindIndexList, unBindIndexList = costItemIndexList
            itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
            if bindCnt > 0:
                bindCostCnt = bindCnt if unCostCnt >= bindCnt else unCostCnt # 绑定道具消耗个数
                unCostCnt -= bindCostCnt
                ItemCommon.ReduceItem(curPlayer, itemPack, bindIndexList, bindCostCnt, True, "CollectNPC")
                GameWorld.DebugLog("        扣除绑定道具: %s" % (bindCostCnt), curPlayer.GetPlayerID())
            if unCostCnt > 0 and unBindCnt > 0:
                unBindCostCnt = unBindCnt if unCostCnt >= unBindCnt else unCostCnt # 绑定道具消耗个数
                unCostCnt -= unBindCostCnt
                ItemCommon.ReduceItem(curPlayer, itemPack, unBindIndexList, unBindCostCnt, True, "CollectNPC")
                GameWorld.DebugLog("        扣除未绑道具: %s" % (unBindCostCnt), curPlayer.GetPlayerID())
        if unCostCnt > 0:
            reduceGold = int(unCostCnt * itemGold)
            infoDict = {"PerGold":itemGold, "unCostCnt":unCostCnt, ChConfig.Def_Cost_Reason_SonKey:costItemID}
            PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, reduceGold,
                                   ChConfig.Def_Cost_BuyStoreItem, infoDict, unCostCnt)
            GameWorld.DebugLog("        扣除消耗钻石: unCostCnt=%s,perGold=%s,reduceGold=%s"
                               % (unCostCnt, itemGold, reduceGold), curPlayer.GetPlayerID())
    # 增加当日采集次数
    if collLimitInfo:
        updCollTime = todayCollTime + successCnt
        updCollTime = todayCollTime + collectCnt
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
        SyncCollNPCTime(curPlayer, npcIDList=[npcID])
        SyncCollNPCTime(curPlayer, [npcID])
        GameWorld.DebugLog("        增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime))
    giveItemList = collectNPCIpyData.GetCollectAward()
    if giveItemList:
        itemID, itemCount, isBind = giveItemList
        ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isBind, [IPY_GameWorld.rptItem])
    #采集成就
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, successCnt, [npcID])
    SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
    #DataRecordPack.DR_CollectNPCOK(curPlayer, npcID, addMoney, addExp, addZhenQi, giveItemInfoList)
    return True
def __DoGiveCollectionNPCSingleAward(curPlayer, mapID, npcID, setBind, pieRandomList, randomAllInfoList, besureInfoList):
    # 单次采集NPC箱子奖励
    giveItemInfoList = [] # 最终会给到玩家身上的物品列表
    #GameWorld.DebugLog("    给物品几率列表giveItemRateList=%s" % giveItemInfoList)
    # 先随机饼图概率物品
    if pieRandomList:
        pieRandomItemInfo = GameWorld.GetResultByRandomList(pieRandomList)
        giveItemInfoList.append(pieRandomItemInfo)
    #GameWorld.DebugLog("    饼图物品giveItemInfoList=%s" % giveItemInfoList)
    # 再处理各自概率的物品
    if randomAllInfoList:
        maxRandomCnt, randomInfoList = randomAllInfoList
        randomInfoListEx = []
        for itemInfo in randomInfoList:
            giveRate = itemInfo[0]
            appendItemInfo = itemInfo[1:]
            # 最大概率必出,不受maxRandomCnt影响
            if giveRate == ShareDefine.Def_MaxRateValue:
                giveItemInfoList.append(appendItemInfo)
                maxRandomCnt -= 1
                continue
            if not GameWorld.CanHappen(giveRate, ShareDefine.Def_MaxRateValue):
                continue
            # 先加到待出列表里,再按需要出的个数随机
            randomInfoListEx.append(appendItemInfo)
        #GameWorld.DebugLog("    maxRandomCnt=%s,randomInfoListEx=%s" % (maxRandomCnt, randomInfoListEx))
        #GameWorld.DebugLog("    giveItemInfoList=%s" % giveItemInfoList)
        if maxRandomCnt > 0 and randomInfoListEx:
            getRandomCnt = min(maxRandomCnt, len(randomInfoListEx))
            giveItemInfoList.extend(random.sample(randomInfoListEx, getRandomCnt))
    # 必出物品
    if besureInfoList:
        collTotalCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTotalCnt % npcID)
        besureCnt, besureItemInfo = besureInfoList
        if collTotalCnt == besureCnt:
            giveItemInfoList = [besureItemInfo] # 必出时设定只给必出的物品
            GameWorld.DebugLog("    此次必出物品, npcID=%s,besureCnt=%s,collTotalCnt=%s" % (npcID, besureCnt, collTotalCnt))
        if collTotalCnt <= besureCnt:
            # 目前只在小于等于的时候才增加次数,为以后如果需要做多个必出配置时,老玩家不用再管key的值
            collTotalCnt += 1
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTotalCnt % npcID, collTotalCnt)
            GameWorld.DebugLog("    更新采集总次数: %s" % collTotalCnt)
    GameWorld.DebugLog("    最终可得到物品giveItemInfoList=%s" % giveItemInfoList)
    syncItemInfoList = [] # 同步的采集到的物品信息列表
    for itemID, itemCnt, isBind in giveItemInfoList:
        if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
            break
        isBind = setBind or isBind
        getItemObj = ItemControler.GetOutPutItemObj(itemID)
#        elif itemType == 1:
#            itemDictData = ItemControler.GetAppointItemDictData(itemID, isBind)
#            getItemObj = ItemControler.GetItemByData(itemDictData)
#        elif itemType == 2:
#            quality = ItemCommon.GetRandEquipQualityByTable(itemID, "CollectEquipRandQuality")
#            if quality == 0:
#                isBroadcast = False
#                getItemObj = ItemCommon.RandNormalEquip(curPlayer, itemID, isBind, "CollectNormalEquip")
#            else:
#                getItemObj, isBroadcast = ItemCommon.RandGreateEquip(curPlayer, itemID, isBind, "CollectGreateEquip", quality)
#            if getItemObj == None:
#                continue
#
#            itemID = getItemObj.GetItemTypeID()
        userData = getItemObj.GetUserData()
        getItemObj.SetCount(itemCnt)
        getItemObj.SetIsBind(isBind)
        ItemCommon.NotifyItemDropByKill(curPlayer, getItemObj, npcID)
        #SendGameServerGoodItemRecord(mapID, npcID, curPlayer.GetPlayerName(), curPlayer.GetPlayerID(), itemID)
        #可以放入背包
        if not ItemControler.DoLogic_PutItemInPack(curPlayer, getItemObj, True, True,
                                                   event=["CollectNPC", False, {"npcID":npcID}]):
            break
        syncItemInfoList.append([itemID, itemCnt, isBind, userData])
    return syncItemInfoList
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, collectCnt, [npcID])
    #SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
    return
## 采集结果同步
#  @param None
#  @param None
def SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, syncItemInfoList, collectNPCID=0):
    return #暂不同步
    if addExp <= 0 and addMoney <= 0 and addZhenQi <= 0 and not syncItemInfoList:
def SyncCollNPCTime(curPlayer, npcIDList=[]):
    ## 同步采集NPC功能号采集次数
    isSyncAll = False
    if not npcIDList:
        isSyncAll = True
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in xrange(ipyDataMgr.GetCollectNPCCount()):
            ipyData = ipyDataMgr.GetCollectNPCByIndex(index)
            if ipyData.GetMaxCollectCount():
                npcIDList.append(ipyData.GetNPCID())
    if not npcIDList:
        return
    
    collItemInfo = ChPyNetSendPack.tagMCCollectionItemInfo()
    collItemInfo.Clear()
    collItemInfo.NPCID = collectNPCID
    collItemInfo.Exp = addExp
    collItemInfo.SilverMoney = addMoney
    collItemInfo.ZhenQi = addZhenQi
    collItemInfo.CollItemList = []
    for syncItemInfo in syncItemInfoList:
        itemType, itemID, itemCnt, isBind, itemInfo = 0, 0, 0, 0, ""
        if len(syncItemInfo) == 3:
            itemID, itemCnt, isBind = syncItemInfo
        elif len(syncItemInfo) == 4:
            itemType, itemID, itemCnt, isBind = syncItemInfo
        elif len(syncItemInfo) == 5:
            itemType, itemID, itemCnt, isBind, itemInfo = syncItemInfo
        if itemID <= 0:
    syncList = []
    for npcID in npcIDList:
        collCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
        if isSyncAll and not collCount:
            continue
        collCntInfo = ChPyNetSendPack.tagMCNPCIDCollectionCnt()
        collCntInfo.Clear()
        collCntInfo.NPCID = npcID
        collCntInfo.CollectionCnt = collCount
        syncList.append(collCntInfo)
        
        collItem = ChPyNetSendPack.tagMCCollectionItem()
        collItem.Clear()
        collItem.ItemType = itemType
        collItem.ItemID = itemID
        collItem.ItemCnt = itemCnt
        collItem.IsBind = isBind
        collItem.ItemInfoLen = len(itemInfo)
        collItem.ItemInfo = itemInfo
        collItemInfo.CollItemList.append(collItem)
    if not syncList:
        return
    
    collItemInfo.CollItemIDCnt = len(collItemInfo.CollItemList)
    NetPackCommon.SendFakePack(curPlayer, collItemInfo)
    npcIDCollInfo = ChPyNetSendPack.tagMCNPCIDCollectionCntInfo()
    npcIDCollInfo.Clear()
    npcIDCollInfo.NPCCollCntList = syncList
    npcIDCollInfo.CollNPCCnt = len(npcIDCollInfo.NPCCollCntList)
    NetPackCommon.SendFakePack(curPlayer, npcIDCollInfo)
    return
## 给采集物品信息列表
#  @param curPlayer:玩家实例
#  @param awardItemInfoDict:奖励物品配置字典
#  @return None
def __GetGiveCollectItemInfo(curPlayer, lvModeIDDict):
    if not lvModeIDDict:
        return [[], []]
    modeID = ""
    playerLV = curPlayer.GetLV()
    for lvKey, mIDStr in lvModeIDDict.items():
        if lvKey[0] <= playerLV <= lvKey[1]:
            modeID = mIDStr
            break
    if not modeID:
        return [[], []]
    collectItemInfoDict = ReadChConfig.GetEvalChConfig('CollectItemInfo_%s' % modeID)
    if not collectItemInfoDict:
        return [[], []]
    infoKey = () # 默认key
    job = curPlayer.GetJob()
    for key in collectItemInfoDict.keys():
        # 如果玩家职业在配置的key里,则取指定的key信息
        if job in key:
            infoKey = key
            break
    if infoKey not in collectItemInfoDict:
        GameWorld.ErrLog('CollectItemInfo_%s.txt can not find key=%s!' % (modeID, infoKey))
        return [[], []]
    GameWorld.DebugLog("    __GetGiveCollectItemInfo job=%s,modeID=%s,key=%s,itemList=%s"
                       % (job, modeID, infoKey, collectItemInfoDict[infoKey]))
    return collectItemInfoDict[infoKey]
## 同步采集NPC功能号采集次数
#  @param curPlayer:采集玩家实例
#  @param funcType:功能号,默认为0,即同步配表中全部
#  @return None
def SyncCollNPCTime(curPlayer, funcTypeList=[], npcIDList=[]):
    if not npcIDList:
        collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
        for npcIDTuple in collectNPCIDTimeLimit.keys():
            npcIDList += list(npcIDTuple)
    if npcIDList:
        npcIDCollInfo = ChPyNetSendPack.tagMCNPCIDCollectionCntInfo()
        npcIDCollInfo.Clear()
        npcIDCollInfo.NPCCollCntList = []
        for npcID in npcIDList:
            collCntInfo = ChPyNetSendPack.tagMCNPCIDCollectionCnt()
            collCntInfo.Clear()
            collCntInfo.NPCID = npcID
            collCntInfo.CollectionCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
            npcIDCollInfo.NPCCollCntList.append(collCntInfo)
        npcIDCollInfo.CollNPCCnt = len(npcIDCollInfo.NPCCollCntList)
        NetPackCommon.SendFakePack(curPlayer, npcIDCollInfo)
    return
## 采集NPCOnDay处理
#  @param curPlayer:玩家实例
#  @return None
def CollNPCTimeOnDay(curPlayer, funcTypeList=[]):
    collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
    for npcIDTuple, collCntInfo in collectNPCIDTimeLimit.items():
        isResetOnDay = collCntInfo[1]
        if not isResetOnDay:
def CollNPCTimeOnDay(curPlayer):
    ## 采集NPCOnDay处理
    resetNPCIDList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetCollectNPCCount()):
        ipyData = ipyDataMgr.GetCollectNPCByIndex(index)
        npcID = ipyData.GetNPCID()
        if not ipyData.GetMaxCollectCount():
            continue
        for npcID in npcIDTuple:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)
    SyncCollNPCTime(curPlayer)
        if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID):
            continue
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)
        resetNPCIDList.append(npcID)
    if resetNPCIDList:
        SyncCollNPCTime(curPlayer, resetNPCIDList)
    return
@@ -6004,38 +5696,6 @@
#  @param None None
#  @return None
def OnBuyCollectionCnt(index, clientData, tick):
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#
#    if not curPlayer:
#        return
#
#    funcType = clientData.FuncType
#    #buyCnt = clientData.BuyCnt # 暂时默认购买一次
#
#    playerID = curPlayer.GetPlayerID()
#    CollectNPCFuncTimeBuyCostDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeBuyCost')
#    if funcType not in CollectNPCFuncTimeBuyCostDict:
#        GameWorld.Log("采集功能次数限制类型,不能购买!funcType=%s" % funcType, playerID)
#        return
#
#    buyTimeKey = ChConfig.Def_PDict_CollNpcBuyTime % funcType
#    alreadyBuyCnt = curPlayer.NomalDictGetProperty(buyTimeKey)
#    costFormat = CollectNPCFuncTimeBuyCostDict[funcType]
#    costGold = eval(costFormat)
#
#    if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold):
#        return
#
#    isOK = PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGold,
#                                  ShareDefine.Def_GoldCostType_BuyCollectionTime, alreadyBuyCnt)
#
#    if not isOK:
#        return
#
#    # 增加购买次数
#    PlayerControl.NomalDictSetProperty(curPlayer, buyTimeKey, alreadyBuyCnt + 1)
#    SyncCollNPCTime(curPlayer, [funcType])
#    GameWorld.Log("购买采集次数:funcType=%s,alreadyBuyCnt=%s,costGold=%s" % (funcType, alreadyBuyCnt, costGold), playerID)
    return
#// A5 0A 购买可击杀boss次数 #tagCMBuyKillBossCnt
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py
@@ -96,11 +96,9 @@
    
    #先设置对象,任务可采集得到对象NPC
    curPlayer.SetActionObj(curNPC)
    if curNPC.GetNPCID() in ReadChConfig.GetEvalChConfig("CollectNPCLostHP"):
        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
    
    # 自定义的采集NPC
    if NPCCommon.DoCollectNPCBegin(curPlayer, curNPC):
    if NPCCommon.OnCollectNPCBegin(curPlayer, curNPC, tick):
        return
    
    EventShell.EventRespons_MisCollectTime(curPlayer, curNPC)
@@ -146,13 +144,10 @@
    if not ChNPC.OnCollectEnd(curPlayer, curNPC):
        return
    
    PlayerState.DoCollectingLostHP(curPlayer, npcID, tick, True)
    # 自定义的采集NPC
    if NPCCommon.DoCollectNPCOK(curPlayer, npcID):
        EventShell.EventRespons_MisCollectSuccess(curPlayer, curNPC) # 先直接写这边触发一下,自定义采集的不再处理后面的代码
        FBLogic.OnCollectOK(curPlayer, npcID, GameWorld.GetGameWorld().GetTick())
        return
    NPCCommon.DoCollectNPCOK(curPlayer, npcID, tick)
    
    EventShell.EventRespons_MisCollectSuccess(curPlayer, curNPC)
    return
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -593,16 +593,20 @@
    if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:
        return
    curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())
    DoCollectingLostHP(curPlayer, curNPC.GetNPCID(), tick, False)
    if not curNPC:
        return
    FBLogic.OnCollecting(curPlayer, tick)
    npcID = curNPC.GetNPCID()
    collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
    if collectNPCIpyData:
        DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, False)
    return
def DoCollectingLostHP(curPlayer, npcID, tick, isEnd):
def DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, isEnd):
    ## 执行采集掉血
    CollectNPCLostHPCfg = ReadChConfig.GetEvalChConfig("CollectNPCLostHP")
    if npcID not in CollectNPCLostHPCfg:
    if not collectNPCIpyData.GetLostHPPer():
        return
    lostSecond, lostHPPer = CollectNPCLostHPCfg[npcID]
    lostSecond, lostHPPer = collectNPCIpyData.GetLostHPPer()
    lastTick = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CollectLostHPTick)
    lostTime = (tick - lastTick) / (lostSecond * 1000.0) # 掉血次数
    if isEnd:
@@ -616,6 +620,7 @@
    lostValue = int(GameObj.GetMaxHP(curPlayer) * lostHPPer / 100.0) * lostTime
    skillTypeID, buffOwner = 0, None
    SkillCommon.SkillLostHP(curPlayer, skillTypeID, buffOwner, lostValue, tick)
    GameWorld.DebugLog("采集掉血: npcID=%s,lostHPPer=%s,lostTime=%s,lostValue=%s" % (collectNPCIpyData.GetNPCID(), lostHPPer, lostTime, lostValue))
    return
@@ -656,8 +661,6 @@
    
    if not curNPC:
        return
    DoCollectingLostHP(curPlayer, curNPC.GetNPCID(), tick, True)
    
    result = FBLogic.OnCanCollect(curPlayer, curNPC, tick)
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_ClientServerReceiveMsg.py
@@ -17,6 +17,7 @@
import GameWorld
import ShareDefine
import NPCCommon
import ChPlayer
#------------------------------------------------------------------------------ 
@@ -41,6 +42,9 @@
    if msgType == ShareDefine.CrossServerMsg_RebornRet:
        ChPlayer.CrossServerMsg_RebornRet(curPlayer, msgData, tick)
        
    elif msgType == ShareDefine.CrossServerMsg_CollectNPCOK:
        NPCCommon.CrossServerMsg_CollectNPCOK(curPlayer, msgData)
    return
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossServerReceiveMsg.py
@@ -17,6 +17,7 @@
import GameWorld
import ShareDefine
import EventShell
import ChPlayer
#------------------------------------------------------------------------------ 
@@ -41,6 +42,9 @@
    if msgType == ShareDefine.ClientServerMsg_Reborn:
        ChPlayer.ClientServerMsg_Reborn(curPlayer, msgData, serverGroupID, tick)
        
    elif msgType == ShareDefine.ClientServerMsg_CollectNPC:
        EventShell.ClientServerMsg_CollectNPC(curPlayer, msgData, serverGroupID, tick)
    return