xdh
2019-01-22 b61fe6ed796dfeb1a7ed718d8099d6edb05f36f6
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
@@ -2067,7 +2068,7 @@
    if ChConfig.IsGameBoss(curNPC): 
        # 通知GameServer boss状态 封魔坛在副本里单独处理
        ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcid)
        if ipyData and ipyData.GetMapID() != ChConfig.Def_FBMapID_SealDemon:
        if ipyData and ipyData.GetMapID() not in [ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss]:
            GameServe_GameWorldBossState(npcid, 0)
            #GameWorld.GetGameWorld().SetGameWorldDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
            #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典
@@ -2094,13 +2095,13 @@
                   curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID))
    return
def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True):
def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):
    dataMapID = GameWorld.GetGameWorld().GetMapID()
    realMapID = GameWorld.GetGameWorld().GetRealMapID()
    copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
    killMsg = str([bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID])
    killMsg = str([bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID, killerIDList])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'KillGameWorldBoss', killMsg, len(killMsg))
    GameWorld.DebugLog("Boss被击杀: bossID=%s,dataMapID=%s,realMapID=%s,copyMapID=%s" % (bossID, dataMapID, realMapID, copyMapID))
    GameWorld.DebugLog("Boss被击杀: bossID=%s,dataMapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s" % (bossID, dataMapID, realMapID, copyMapID, killerIDList))
    return
def GameServe_GameWorldBossState(bossID, isAlive):
@@ -2125,6 +2126,44 @@
            GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 0)
    return
def OnPlayerKillBoss(curPlayer, npcID, mapID, isCrossServer):
    killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
    limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
    if limitIndex != None:
        #今日杀怪次数+1
        key = ChConfig.Def_PDict_Boss_KillCnt % limitIndex
        newCnt = curPlayer.NomalDictGetProperty(key, 0) + 1
        PlayerControl.NomalDictSetProperty(curPlayer, key, newCnt)
        BossHurtMng.NotifyAttackBossCnt(curPlayer, limitIndex)
        GameWorld.DebugLog("今日杀怪次数  playerID=%s, newCnt=%s" % (curPlayer.GetPlayerID(), newCnt))
        dataDict = {"objID":npcID, "bossID":npcID, "touchCnt":newCnt,
                    "AccID":curPlayer.GetAccID(), "PlayerID":curPlayer.GetPlayerID()}
        DataRecordPack.SendEventPack("AddKillBossCnt", dataDict, curPlayer)
    if isCrossServer:
        return
    if limitIndex == ShareDefine.Def_Boss_Func_World:
        # 世界BOSS击杀成就
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillWorldBoss, 1)
        # 每日活动
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_WorldBOSS, 1)
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1)
        PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_WorldBOSS, 1)
    if mapID == ChConfig.Def_FBMapID_BossHome:
        #BOSS之家
        # BOSS之家BOSS击杀成就
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
        # 每日活动
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)
        PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_BOSSHome, 1)
    return
#################################################
## NPC控制定义
#
@@ -2144,6 +2183,7 @@
        self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致
        self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者
        self.__FeelPlayerList = [] # 所有摸怪玩家列表,处理任务及某些逻辑用
        self.__ownerPlayerList = [] # 归属者列表
        
        self.__OwnerHurtType = 0
        self.__OwnerHurtID = 0
@@ -3949,7 +3989,8 @@
            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
                killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID)
            #KillerJob = 0 if not self.__Killer else self.__Killer.GetJob()
            GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0)
            killerIDList = [player.GetPlayerID() for player in self.__ownerPlayerList]
            GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0, True, killerIDList)
        #===========================================================================================
        # # 暗金boss
        # if curNPC.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark:
@@ -4447,7 +4488,8 @@
                    dropPlayer = curPlayer
                self.__KilledByPlayerSetPrize(curPlayer)
                ownerPlayerList.append(curPlayer)
            self.__ownerPlayerList = ownerPlayerList
            #调用物品掉落
            self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)
@@ -4889,6 +4931,7 @@
            
            self.__DoNormalTeamExp(curPlayer)
            self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, True)
        self.__ownerPlayerList = ownerPlayerList
            
        #调用物品掉落
        self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)
@@ -4917,6 +4960,7 @@
                maxLV = curPlayerLV
                dropPlayer = player
            ownerPlayerList.append(player)
        self.__ownerPlayerList = ownerPlayerList
            
        if not ownerPlayerList:
            GameWorld.Log("奖励归属仙盟,但是不存在可获得该奖励的成员!npcID=%s,hurtType=%s,hurtID=%s" 
@@ -4957,48 +5001,31 @@
        defObjType = curNPC.GetGameObjType() 
        mapFBType = GameWorld.GetMap().GetMapFBType()
        mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
        playerID = curPlayer.GetPlayerID()
        #playerID = curPlayer.GetPlayerID()
        
        # 如果是NPC
        if defObjType == IPY_GameWorld.gotNPC:
        if defObjType != IPY_GameWorld.gotNPC:
            return
        # 跨服服务器处理
        if GameWorld.IsCrossServer():
            #掉落归属
            if mapFBType != IPY_GameWorld.fbtNull:
                FBLogic.DoFB_DropOwner(curPlayer , curNPC)
            else:
                if curNPC.GetLV()>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):
                    PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC)
                
            killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
            limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
            if limitIndex != None:
                #今日杀怪次数+1
                key = ChConfig.Def_PDict_Boss_KillCnt % limitIndex
                newCnt = curPlayer.NomalDictGetProperty(key, 0) + 1
                PlayerControl.NomalDictSetProperty(curPlayer, key, newCnt)
                BossHurtMng.NotifyAttackBossCnt(curPlayer, limitIndex)
                GameWorld.DebugLog("今日杀怪次数  playerID=%s, newCnt=%s" % (curPlayer.GetPlayerID(), newCnt))
                dataDict = {"objID":curNPC.GetID(), "bossID":npcID, "touchCnt":newCnt,
                            "AccID":curPlayer.GetAccID(), "PlayerID":curPlayer.GetPlayerID()}
                DataRecordPack.SendEventPack("AddKillBossCnt", dataDict, curPlayer)
                if limitIndex == 0:
                    # 世界BOSS击杀成就
                    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillWorldBoss, 1)
                    # 每日活动
                    PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS)
                    PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_WorldBOSS, 1)
                    PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1)
                    PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_WorldBOSS, 1)
            if ChConfig.IsGameBoss(curNPC) and mapID == ChConfig.Def_FBMapID_BossHome:
                #BOSS之家
                # BOSS之家BOSS击杀成就
                PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
                # 每日活动
                PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
                PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)
                PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)
                PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_BOSSHome, 1)
            if ChConfig.IsGameBoss(curNPC):
                OnPlayerKillBoss(curPlayer, npcID, mapID, True)
            return
        #掉落归属
        if mapFBType != IPY_GameWorld.fbtNull:
            FBLogic.DoFB_DropOwner(curPlayer , curNPC)
        else:
            if curNPC.GetLV()>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):
                PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC)
            
        if ChConfig.IsGameBoss(curNPC):
            OnPlayerKillBoss(curPlayer, npcID, mapID, False)
        return
        
    #---------------------------------------------------------------------
@@ -5024,7 +5051,7 @@
        #GameWorld.DebugLog("__MissionOnKillNPC isFeel=%s" % (isFeel), curPlayer.GetPlayerID())
        killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
        limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
        isWorldBoos = limitIndex == 0
        isWorldBoos = limitIndex == ShareDefine.Def_Boss_Func_World
        if isFeel:
            #击杀NPC触发摸怪任务事件
            EventShell.EventRespons_OnKillByFeel(curPlayer, curNPC)
@@ -5221,129 +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
    npcFuncType = curNPC.GetFunctionType()
    npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
    if npcFuncType in npcFuncCollectCntLimitDict:
        vipLV = curPlayer.GetVIPLv()
        limitMaxTime = eval(npcFuncCollectCntLimitDict[npcFuncType])
        todayBuyTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % npcFuncType)
        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % npcFuncType)
        limitMaxTime += todayBuyTime
        GameWorld.DebugLog("    vipLV=%s,maxTime=%s,todayTime=%s,todayBuyTime=%s" % (vipLV, limitMaxTime, todayCollTime, todayBuyTime))
    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
    if npcID in npcIDCollectCntLimitDict:
        limitMaxTime = npcIDCollectCntLimitDict[npcID][0]
        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
        GameWorld.DebugLog("    maxTime=%s,todayTime=%s" % (limitMaxTime, todayCollTime))
    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
## 设置玩家采集该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)
@@ -5396,424 +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
    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
    if npcID not in npcIDCollectCntLimitDict:
        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
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    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
    # 根据NPC功能号
    npcFuncType = curNPC.GetFunctionType()
    npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
    limitMaxTime = 0 # 0表示不限制次数
    todayCollTime = 0
    if npcFuncType in npcFuncCollectCntLimitDict:
        vipLV = curPlayer.GetVIPLv()
        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % npcFuncType)
        limitMaxTime = eval(npcFuncCollectCntLimitDict[npcFuncType])
    # 根据NPCID
    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
    if npcID in npcIDCollectCntLimitDict:
        limitMaxTime = npcIDCollectCntLimitDict[npcID][0]
        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
    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 limitMaxTime > 0:
        updCollTime = todayCollTime + successCnt
        npcFuncType = curNPC.GetFunctionType()
        npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
        if npcFuncType in npcFuncCollectCntLimitDict:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTime % npcFuncType, updCollTime)
            SyncCollNPCTime(curPlayer, [npcFuncType])
        if npcID in npcIDCollectCntLimitDict:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
            SyncCollNPCTime(curPlayer, npcIDList=[npcID])
        updCollTime = todayCollTime + collectCnt
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
        SyncCollNPCTime(curPlayer, [npcID])
        GameWorld.DebugLog("        增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime))
        #采集成就
        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)
    giveItemList = collectNPCIpyData.GetCollectAward()
    if giveItemList:
        itemID, itemCount, isBind = giveItemList
        ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isBind, [IPY_GameWorld.rptItem])
        
        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 funcTypeList:
        npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
        funcTypeList = npcFuncCollectCntLimitDict.keys()
    if not npcIDList:
        collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
        npcIDList = collectNPCIDTimeLimit.keys()
#    if funcTypeList:
#        collection = ChPyNetSendPack.tagMCFuncNPCCollectionCnt()
#        for fType in funcTypeList:
#            todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % fType)
#            collection.Clear()
#            collection.FuncType = fType
#            collection.CollectionCnt = todayCollTime
#            collection.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % fType)
#            NetPackCommon.SendFakePack(curPlayer, collection)
    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=[]):
    npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
    funcTypeList = npcFuncCollectCntLimitDict.keys() if not funcTypeList else funcTypeList
    for funcType in funcTypeList:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTime % funcType, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcBuyTime % funcType, 0)
    collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
    for npcID, 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
        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
@@ -5899,28 +5585,43 @@
#  @param queryNPCIDList:查询的NPCID列表
#  @param tick
#  @return {NPCID:cnt}
def GetNPCCntInfo(queryNPCIDList, tick):
def GetNPCCntInfo(queryNPCIDList, tick, copyMapID=None):
    npcCntDict = {}
    if not queryNPCIDList:
        return npcCntDict
    #if not queryNPCIDList:
    #    return npcCntDict
    
    gameNPCManager = GameWorld.GetNPCManager()
    GameWorld.DebugLog("GetNPCCntInfo...queryNPCIDList=%s" % (str(queryNPCIDList)))
    for index in xrange(gameNPCManager.GetNPCCount()):
        curNPC = gameNPCManager.GetNPCByIndex(index)
        curID = curNPC.GetID()
        if curID == 0:
            continue
        curNPCID = curNPC.GetNPCID()
        if curNPCID not in queryNPCIDList:
            continue
        if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
            continue
        npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
    if isinstance(copyMapID, int):
        for index in xrange(gameNPCManager.GetNPCCountByGWIndex(copyMapID)):
            curNPC = gameNPCManager.GetNPCByIndexByGWIndex(copyMapID, index)
            curID = curNPC.GetID()
            if curID == 0:
                continue
            curNPCID = curNPC.GetNPCID()
            if queryNPCIDList and curNPCID not in queryNPCIDList:
                continue
            if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
                continue
            npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
    else:
        for index in xrange(gameNPCManager.GetNPCCount()):
            curNPC = gameNPCManager.GetNPCByIndex(index)
            curID = curNPC.GetID()
            if curID == 0:
                continue
            curNPCID = curNPC.GetNPCID()
            if queryNPCIDList and curNPCID not in queryNPCIDList:
                continue
            if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
                continue
            npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
                
    GameWorld.DebugLog("    npcCntDict=%s" % (str(npcCntDict)))
    return npcCntDict
@@ -5995,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