From d0f5f9922f17f5bff4288173f18a9ed827d95db8 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期六, 22 六月 2019 15:00:13 +0800 Subject: [PATCH] 1 装备评分增加装备掉率参数固定值 DropEquipPer --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 691 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 570 insertions(+), 121 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py index 4ec130c..75f9138 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -50,6 +50,7 @@ import PlayerBossReborn import PlayerFairyCeremony import PlayerNewFairyCeremony +import GameLogic_CrossGrassland import PlayerWeekParty import PlayerActLogin import FamilyRobBoss @@ -94,8 +95,6 @@ #初始化处理间隔 curNPC.SetIsNeedProcess(False) - #设定致命一击伤害百分比 - curNPC.SetSuperHit(ChConfig.Def_SuperHitPercent) #初始化这个NPC的时钟 curNPC.SetTickTypeCount(ChConfig.TYPE_NPC_Tick_Count) return @@ -166,6 +165,15 @@ randMaxLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV) strengthenLV = random.randint(randMinLV, randMaxLV) + # 木桩怪最大、平均成长等级处理,直接取归属玩家等级 + if lvStrengthenType in [1, 2] and curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]: + owner = None + summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID) + if summonPlayerID: + owner = GameWorld.GetObj(summonPlayerID, IPY_GameWorld.gotPlayer) + if owner: + strengthenLV = owner.GetLV() + if strengthenIpyData.GetCmpNPCBaseLV(): strengthenLV = max(strengthenLV, curNPC.GetLV()) @@ -398,7 +406,7 @@ return attrDict def GiveKillNPCDropPrize(curPlayer, mapID, npcCountDict, exp_rate=None, mailTypeKey=None, isMail=False, - extraItemList=[], prizeMultiple=1, dropItemMapInfo=[], curGrade=0): + extraItemList=[], prizeMultiple=1, dropItemMapInfo=[], curGrade=0, isVirtualDrop=False): '''给玩家击杀NPC掉落奖励 @param mapID: 击杀的NPC所在地图ID,注意次地图并不一定是玩家当前地图 @param npcCountDict: 执行单次时所击杀的npc数量字典 {npcID:count, ...} @@ -407,6 +415,9 @@ @param isMail: 是否强制发送邮件,若是则不考虑背包空间,否的话只在背包空间不足时才发送邮件 @param extraItemList: 固定附加物品列表,如果需执行多次,则此固定产出列表需在外层处理好,内层不做多次执行处理。[[itemID, itemCount, isAuctionItem], ...] @param prizeMultiple: 奖励倍值, 对所有奖励有效,等于击杀多次NPC,多倍附加物品 + @param dropItemMapInfo: 掉落地板信息 [dropPosX, dropPosY, 是否仅自己可见, 堆叠物品是否散开] + @param curGrade: 评级 + @param isVirtualDrop: 是否给物品虚拟掉落表现 ''' if not exp_rate: exp_rate = PlayerControl.GetPlayerExpRate(curPlayer) @@ -494,7 +505,7 @@ if ItemCommon.GetIsEquip(itemData): for _ in xrange(itemCount): - curItem = ItemControler.GetOutPutItemObj(itemID) + curItem = ItemControler.GetOutPutItemObj(itemID, 1, isAuctionItem, curPlayer=curPlayer) if curItem: needSpace += 1 prizeItemList.append(curItem) @@ -509,45 +520,15 @@ ## 直接掉地板上 if dropItemMapInfo: - dropPosX, dropPosY, isOnlySelfSee = dropItemMapInfo[:3] + dropPosX, dropPosY = dropItemMapInfo[:2] + isOnlySelfSee = dropItemMapInfo[2] if len(dropItemMapInfo) > 2 else False # 是否仅自己可见 isDropDisperse = dropItemMapInfo[3] if len(dropItemMapInfo) > 3 else False # 堆叠的物品是否散开掉落 - if isDropDisperse: - dropItemList = [] - for itemInfo in prizeItemList: - if isinstance(itemInfo, list): - itemID, itemCount, isAuctionItem = itemInfo - for _ in xrange(itemCount): - dropItemList.append([itemID, 1, isAuctionItem]) - else: - dropItemList.append(itemInfo) + ## 虚拟掉落表现 + if isVirtualDrop: + DoGiveItemByVirtualDrop(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse, mailTypeKey) else: - dropItemList = prizeItemList - index = 0 - playerID = curPlayer.GetPlayerID() - gameMap = GameWorld.GetMap() - for posX, posY in ChConfig.Def_DropItemAreaMatrix: - resultX = dropPosX + posX - resultY = dropPosY + posY + DoMapDropPrizeItem(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse, isOnlySelfSee) - if not gameMap.CanMove(resultX, resultY): - #玩家不可移动这个点 - continue - - if index > len(dropItemList) - 1: - break - - curItem = dropItemList[index] - index += 1 - if isinstance(curItem, list): - itemID, itemCount, isAuctionItem = curItem - curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem) - - if not curItem: - continue - - ChItem.AddMapDropItem(resultX, resultY, curItem, ownerInfo=[ChConfig.Def_NPCHurtTypePlayer, playerID], - dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee) - ## 发邮件 或 背包空间不足 elif isMail or needSpace > ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace): mailItemList = [] @@ -584,25 +565,115 @@ #GameWorld.DebugLog(" totalExp=%s,totalMoney=%s,needSpace=%s,jsonItemList=%s" % (totalExp, totalMoney, needSpace, jsonItemList)) return jsonItemList, totalExp, totalMoney -def DoVirtualItemDrop(curPlayer, dropItemList, dropPosX, dropPosY): - ##前端假掉落表现 - gameMap = GameWorld.GetMap() +def DoMapDropPrizeItem(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse=True, isOnlySelfSee=True): + ## 奖励物品真实掉落地图,先拆开分散再掉落 + + if isDropDisperse: + dropItemList = [] + for itemInfo in prizeItemList: + if isinstance(itemInfo, list): + itemID, itemCount, isAuctionItem = itemInfo + for _ in xrange(itemCount): + dropItemList.append([itemID, 1, isAuctionItem]) + else: + dropItemList.append(itemInfo) + else: + dropItemList = prizeItemList index = 0 + playerID = curPlayer.GetPlayerID() + gameMap = GameWorld.GetMap() for posX, posY in ChConfig.Def_DropItemAreaMatrix: resultX = dropPosX + posX resultY = dropPosY + posY + if not gameMap.CanMove(resultX, resultY): #玩家不可移动这个点 continue + if index > len(dropItemList) - 1: break - itemInfo = dropItemList[index] + + curItem = dropItemList[index] index += 1 - itemID, itemCount, isAuctionItem = itemInfo - curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem) + if isinstance(curItem, list): + itemID, itemCount, isAuctionItem = curItem + curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer) + + if not curItem: + continue + + ChItem.AddMapDropItem(resultX, resultY, curItem, ownerInfo=[ChConfig.Def_NPCHurtTypePlayer, playerID], + dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee) + return + +def DoGiveItemByVirtualDrop(curPlayer, giveItemList, npcID, dropPosX=0, dropPosY=0, isDropDisperse=True, mailTypeKey="ItemNoPickUp"): + ## 给物品并且做假掉落表现,直接先堆叠给物品,再拆开做虚假掉落表现 + + mapID = PlayerControl.GetCustomMapID(curPlayer) + lineID = PlayerControl.GetCustomLineID(curPlayer) + if not mapID: + mapID = GameWorld.GetGameWorld().GetMapID() + + playerID = curPlayer.GetPlayerID() + giveItemObjList = [] + virtualItemDropList = [] + itemControl = ItemControler.PlayerItemControler(curPlayer) + for itemInfo in giveItemList: + if isinstance(itemInfo, list): + itemID, itemCount, isAuctionItem = itemInfo + curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer) + if not curItem: + continue + else: + curItem = itemInfo + itemID = curItem.GetItemTypeID() + itemCount = curItem.GetCount() + isAuctionItem = ItemControler.GetIsAuctionItem(curItem) dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem) + giveItemObjList.append(curItem) + + # 散开掉落 + if isDropDisperse: + for _ in xrange(itemCount): + virtualItemDropList.append([itemID, dropItemDataStr]) + else: + virtualItemDropList.append([itemID, dropItemDataStr]) + + # 先通知掉落,再给物品,因为前端表现弹框需要这个顺序需求 + gameMap = GameWorld.GetMap() + index = 0 + for posX, posY in ChConfig.Def_DropItemAreaMatrix: + if dropPosX or dropPosY: + resultX = dropPosX + posX + resultY = dropPosY + posY + if not gameMap.CanMove(resultX, resultY): + #玩家不可移动这个点 + continue + else: + resultX, resultY = 0, 0 + if index > len(virtualItemDropList) - 1: + break + itemID, dropItemDataStr = virtualItemDropList[index] + index += 1 SendVirtualItemDrop(curPlayer, itemID, resultX, resultY, dropItemDataStr) - curItem.Clear() + + # 再给物品 + mailItemList = [] + for itemObj in giveItemObjList: + itemID = itemObj.GetItemTypeID() + mailItem = ItemCommon.GetMailItemDict(itemObj) + equipInfo = [itemObj.GetEquipPlace(), ItemCommon.GetItemClassLV(itemObj), itemObj.GetItemColor(), + itemObj.GetSuiteID(), itemObj.GetUserData()] + packIndex = ChConfig.GetItemPackType(itemObj.GetType()) + if not itemControl.PutInItem(packIndex, itemObj, event=[ChConfig.ItemGive_Pickup, False, {"NPCID":npcID}]): + mailItemList.append(mailItem) + + if npcID: + SendGameServerGoodItemRecord(curPlayer, mapID, lineID, npcID, itemID, equipInfo) + + # 放不下的发邮件 + if mailItemList: + PlayerControl.SendMailByKey(mailTypeKey, [playerID], mailItemList, [mapID]) return ################################### NPC掉落 ################################### @@ -942,6 +1013,10 @@ colorMaxDropCntDict = ipyDrop.GetEquipColorMaxDropCount() # {颜色:上限数量,...} colorSuitRateDict = ipyDrop.GetEquipColorSuitInfo() # 装备颜色对应套装概率 {颜色:套装概率, ...} colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...} + colorSuitPartOptimization = ipyDrop.GetColorSuitPartOptimization() # 部位颜色套评分优选掉落,十位代表颜色,个位代表套装 + optColor, optIsSuit = colorSuitPartOptimization / 10, colorSuitPartOptimization % 10 + optPlace = None # 优选部位 + for dropEquipInfo in dropEquipInfoList: classLV, color = dropEquipInfo[:2] if color in colorMaxDropCntDict: @@ -969,11 +1044,20 @@ GameWorld.ErrLog("未配置颜色是否套装对应部位集合key! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit)) continue placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey] + # 掉落优选部位处理 + if color == optColor and isSuit == optIsSuit and placeKey in placeKeyListDict and optPlace == None: + optPlace = __GetOptimizationEquipPlace(dropPlayer, classLV, optColor, optIsSuit, placeKeyListDict[placeKey]) jobList = itemJobList if placeKey not in placeKeyListDict: GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) continue - placeList = placeKeyListDict[placeKey] + if optPlace > 0: + GameWorld.DebugLog(" 最终优选部位: %s" % optPlace) + placeList = [optPlace] + jobList = [dropPlayer.GetJob()] + optPlace = 0 # 只有一次性的,置为0 + else: + placeList = placeKeyListDict[placeKey] randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, jobList) if not randEquipIDList: continue @@ -1042,6 +1126,42 @@ elif ChConfig.IsGameBoss(npcData): GameWorld.ErrLog("Boss没有掉落物品,NPCID=%s" % (npcID), dropPlayer.GetPlayerID()) return dropIDList, auctionIDList, dropMoneyCnt, moneyValue + +def __GetOptimizationEquipPlace(dropPlayer, classLV, optColor, optIsSuit, optPlaceList): + ''' 获取掉落优选部位 + 几个默认规则 + 1. 颜色大于指定优选颜色的,无论是否套装都不计算在内 + 2. 颜色小于指定优选颜色的,无论是否套装都计算在内 + ''' + #GameWorld.DebugLog("处理优选部位掉落: classLV=%s,optColor=%s,optIsSuit=%s,optPlaceList=%s" % (classLV, optColor, optIsSuit, optPlaceList)) + minGSPlace = None + minGS = None + equipPack = dropPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip) + for optPlace in optPlaceList: + ipyData = IpyGameDataPY.GetIpyGameData('EquipPlaceIndexMap', classLV, optPlace) + if not ipyData: + continue + equipIndex = ipyData.GetGridIndex() + curEquip = equipPack.GetAt(equipIndex) + if not curEquip or curEquip.IsEmpty(): + #GameWorld.DebugLog(" 没穿装备,直接默认返回该部位: optPlace=%s" % optPlace) + return optPlace + curColor = curEquip.GetItemColor() + curIsSuit = 1 if curEquip.GetSuiteID() else 0 + if curColor > optColor: + # 超过优选指定颜色的不算,无论是否有套装 + #GameWorld.DebugLog(" 颜色超过优选颜色,不算该部位: optPlace=%s,curColor=%s,curIsSuit=%s" % (optPlace, curColor, curIsSuit)) + continue + if curColor == optColor and curIsSuit >= optIsSuit: + # 与优选指定颜色相同,且满足是否套装的不算 + #GameWorld.DebugLog(" 颜色套装满足优选,不算该部位: optPlace=%s,curColor=%s,curIsSuit=%s" % (optPlace, curColor, curIsSuit)) + continue + curGS = ItemCommon.GetEquipGearScore(curEquip) + if minGS == None or curGS < minGS: + minGS = curGS + minGSPlace = optPlace + + return minGSPlace def __GetNPCDropDoCountChange(doCount, doCountRate, doCountAdd): ## 获取掉落执行次数变更结果,可能增加 或 减少 @@ -1223,7 +1343,7 @@ itemData = GameWorld.GetGameData().GetItemByTypeID(itemID) if not itemData: continue - itemJob = itemData.GetJobLimit() / 100 + itemJob = itemData.GetJobLimit() if itemJob and itemJob != curPlayer.GetJob(): # 非本职业可用,不掉落 GameWorld.DebugLog("全服击杀次数必掉,非本职业可用,不掉落! itemID=%s" % itemID) @@ -1237,7 +1357,7 @@ itemData = GameWorld.GetGameData().GetItemByTypeID(rItemID) if not itemData: continue - itemJob = itemData.GetJobLimit() / 100 + itemJob = itemData.GetJobLimit() if itemJob and itemJob != curPlayer.GetJob(): # 非本职业可用,不掉落 GameWorld.DebugLog("全服击杀次数必掉随机,非本职业可用,不掉落! rItemID=%s" % rItemID) @@ -1251,7 +1371,7 @@ return dropItemIDList -def __GetEquipIDList(npcID, classLV, color, isSuit, placeList, itemJobList): +def __GetEquipIDList(findID, classLV, color, isSuit, placeList, itemJobList, findType="NPC"): #存一个满足要求的所有的物品的列表 然后从当中随机选一个 #注: 阶、颜色、套装ID、职业、部位,这5个条件可确认唯一一件装备 key = "%s_%s" % (classLV, color) @@ -1276,7 +1396,7 @@ if itemData.GetItemColor() != color: continue suiteID = itemData.GetSuiteID() - itemJob = itemData.GetJobLimit() / 100 + itemJob = itemData.GetJobLimit() itemPlace = itemData.GetEquipPlace() itemID = itemData.GetItemTypeID() if itemPlace not in filterItemIDDict: @@ -1284,7 +1404,7 @@ placeItemList = filterItemIDDict[itemPlace] placeItemList.append([itemJob, suiteID, itemID]) PyGameData.g_filterEquipDict[key] = filterItemIDDict - GameWorld.Log("缓存掉落装备ID: classLV_color=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict)) + GameWorld.Log("缓存产出装备ID: classLV_color=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict)) itemIDList = [] for itemPlace, placeItemList in filterItemIDDict.items(): @@ -1300,8 +1420,8 @@ itemIDList.append(itemID) if not itemIDList: - GameWorld.ErrLog("找不到可掉落的装备ID: npcID=%s,classLV=%s,color=%s,isSuit=%s,placeList=%s,itemJobList=%s" - % (npcID, classLV, color, isSuit, placeList, itemJobList)) + GameWorld.ErrLog("找不到可产出的装备ID: %sID=%s,classLV=%s,color=%s,isSuit=%s,placeList=%s,itemJobList=%s" + % (findType, findID, classLV, color, isSuit, placeList, itemJobList)) return itemIDList def __GetNPCPieRateEquipDrop(ipyDrop, doCnt, equipDropPlus): @@ -1402,7 +1522,7 @@ if not itemData: GameWorld.ErrLog("掉落物品ID不存在, dropItemID=%s" % dropItemID) continue - itemJob = itemData.GetJobLimit() / 100 + itemJob = itemData.GetJobLimit() if isJobLimit and itemJob and itemJob != curPlayer.GetJob(): # 非本职业可用,不掉落 #GameWorld.DebugLog("非本职业可用,不掉落! dropItemID=%s" % dropItemID) @@ -1941,6 +2061,114 @@ return +#// B4 0F 回收私有专属木桩怪 #tagCMRecyclePriWoodPile +# +#struct tagCMRecyclePriWoodPile +#{ +# tagHead Head; +# DWORD ObjID; +#}; +def OnRecyclePriWoodPile(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + objID = clientData.ObjID + curNPC = GameWorld.FindNPCByID(objID) + if not curNPC: + return + if curNPC.GetType() not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]: + return + summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID) + if curPlayer.GetPlayerID() != summonPlayerID: + #GameWorld.DebugLog("非玩家私有木桩...") + return + SetDeadEx(curNPC) + return + +#// B4 0C 召唤私有专属木桩怪 #tagCMSummonPriWoodPile +# +#struct tagCMSummonPriWoodPile +#{ +# tagHead Head; +# DWORD NPCID; +# BYTE Count; //默认1个,最多5个 +# DWORD HP; //默认0取最大值,其中一个血量数值大于0则用指定血量 +# DWORD HPEx; //默认0取最大值,其中一个血量数值大于0则用指定血量 +#}; +def OnSummonPriWoodPile(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + npcID = clientData.NPCID + count = clientData.Count + hp = clientData.HP + hpEx = clientData.HPEx + SummonPriWoodPile(curPlayer, npcID, count, hp, hpEx) + return + +def SummonPriWoodPile(curPlayer, npcID, count, hp=0, hpEx=0): + ''' 召唤私有专属木桩怪 + ''' + + mapID = PlayerControl.GetCustomMapID(curPlayer) + lineID = PlayerControl.GetCustomLineID(curPlayer) + if mapID: + if not FBLogic.OnCanSummonPriWoodPile(curPlayer, mapID, lineID, npcID, count): + GameWorld.ErrLog("无法召唤木桩怪!mapID=%s,lineID=%s,npcID=%s,count=%s" % (mapID, lineID, npcID, count)) + return + + if count != 1: + hp, hpEx = 0, 0 # 指定血量的暂仅适用于单只的 + + playerID = curPlayer.GetPlayerID() + if playerID not in PyGameData.g_playerPriWoodPileNPCDict: + PyGameData.g_playerPriWoodPileNPCDict[playerID] = [] + playerPriWoodNPCList = PyGameData.g_playerPriWoodPileNPCDict[playerID] + maxCount = 3 + nowCount = len(playerPriWoodNPCList) + summonCount = min(count, maxCount - nowCount) + GameWorld.DebugLog("召唤木桩: npcID=%s,count=%s,maxCount=%s,nowCount=%s,summonCount=%s,hp=%s,hpEx=%s" + % (npcID, count, maxCount, nowCount, summonCount, hp, hpEx)) + if summonCount <= 0: + return + + npcManager = GameWorld.GetNPCManager() + for _ in xrange(summonCount): + #summonNPC = curPlayer.SummonNewNPC() + summonNPC = npcManager.AddPlayerSummonNPC() + + #设置召唤兽基础信息 + summonNPC.SetNPCTypeID(npcID) + summonNPC.SetSightLevel(curPlayer.GetSightLevel()) + #初始化 + InitNPC(summonNPC) + + #玩家召唤兽列表添加召唤兽,召唤兽添加主人 + #summonNPC.SetOwner(curPlayer) + summonNPC.SetDict(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID, playerID) + + #将召唤兽召唤出来 + #玩家周围随机出生点 + #技能召唤坐标 ChConfig.Def_SummonAppearDist + summonPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), 3) + summonNPC.Reborn(summonPos.GetPosX(), summonPos.GetPosY(), False) + NPCControl(summonNPC).ResetNPC_Init(isReborn=True) + if hp or hpEx: + summonNPC.SetHP(hp) + summonNPC.SetHPEx(hpEx) + summonNPC.NotifyAppear() # 最终统一通知NPC出现 + playerPriWoodNPCList.append(summonNPC) + + return + +def ClearPriWoodPile(curPlayer): + ## 清除私有木桩 + playerID = curPlayer.GetPlayerID() + if playerID not in PyGameData.g_playerPriWoodPileNPCDict: + return + playerPriWoodNPCList = PyGameData.g_playerPriWoodPileNPCDict.pop(playerID) + for summonNPC in playerPriWoodNPCList: + if not summonNPC: + continue + SetDeadEx(summonNPC) + return + ## 设置npc死亡及自身处理(请不要将游戏逻辑加在此函数中) # @param curNPC:npc实例 # @return @@ -1988,6 +2216,16 @@ lineRobotJobDict.pop(curNPC.GetID(), 0) PyGameData.g_fbRobotJobDict[lineID] = lineRobotJobDict + priWoodPilePlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID) + if priWoodPilePlayerID > 0 and priWoodPilePlayerID in PyGameData.g_playerPriWoodPileNPCDict: + priWoodPileNPCList = PyGameData.g_playerPriWoodPileNPCDict[priWoodPilePlayerID] + for priWoodNPC in priWoodPileNPCList: + if priWoodNPC and priWoodNPC.GetID() == curNPC.GetID(): + priWoodPileNPCList.remove(priWoodNPC) + if not priWoodPileNPCList: + PyGameData.g_playerPriWoodPileNPCDict.pop(priWoodPilePlayerID) + break + # C++设置npc死亡 curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason), curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerType), @@ -1995,31 +2233,34 @@ return def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]): - dataMapID = GameWorld.GetGameWorld().GetMapID() + mapID = GameWorld.GetGameWorld().GetMapID() realMapID = GameWorld.GetGameWorld().GetRealMapID() copyMapID = GameWorld.GetGameWorld().GetCopyMapID() - killMsg = str([bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID, killerIDList]) + killMsg = str([bossID, killPlayerName, hurtValue, isNotify, mapID, realMapID, copyMapID, killerIDList]) GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'KillGameWorldBoss', killMsg, len(killMsg)) - GameWorld.DebugLog("Boss被击杀: bossID=%s,dataMapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s" % (bossID, dataMapID, realMapID, copyMapID, killerIDList)) + GameWorld.DebugLog("Boss被击杀: bossID=%s,mapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s" % (bossID, mapID, realMapID, copyMapID, killerIDList)) return def GameServe_GameWorldBossState(bossID, isAlive): - dataMapID = GameWorld.GetGameWorld().GetMapID() + mapID = GameWorld.GetGameWorld().GetMapID() realMapID = GameWorld.GetGameWorld().GetRealMapID() copyMapID = GameWorld.GetGameWorld().GetCopyMapID() - stateMsg = str([bossID, isAlive, dataMapID, realMapID, copyMapID]) + stateMsg = str([bossID, isAlive, mapID, realMapID, copyMapID]) GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', '%s' % stateMsg, len(stateMsg)) - GameWorld.DebugLog("Boss状态变更: bossID=%s,isAlive=%s,dataMapID=%s,realMapID=%s,copyMapID=%s" - % (bossID, isAlive, dataMapID, realMapID, copyMapID)) + GameWorld.DebugLog("Boss状态变更: bossID=%s,isAlive=%s,mapID=%s,realMapID=%s,copyMapID=%s" + % (bossID, isAlive, mapID, realMapID, copyMapID)) if not isAlive: - if dataMapID in ChConfig.Def_CrossZoneMapTableName: - tableName = ChConfig.Def_CrossZoneMapTableName[dataMapID] + if mapID in ChConfig.Def_CrossZoneMapTableName: + tableName = ChConfig.Def_CrossZoneMapTableName[mapID] realMapID = GameWorld.GetGameWorld().GetRealMapID() copyMapID = GameWorld.GetGameWorld().GetCopyMapID() - zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID) + zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, mapID, copyMapID) if not zoneIpyData: return zoneID = zoneIpyData.GetZoneID() + GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0) + elif mapID in ChConfig.Def_CrossDynamicLineMap: + zoneID = FBCommon.GetCrossDynamicLineMapZoneID() GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0) else: GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 0) @@ -3281,7 +3522,8 @@ #得到范围内随机一个点, 普通小怪走法 PosMap = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) - + if not PosMap: + return moveArea = min(curNPC.GetMoveArea(), 2) posX = curNPC.GetPosX() @@ -3553,14 +3795,13 @@ def DoHPPerLogic(self, dropType, ownerID): curNPC = self.__Instance curNPCID = curNPC.GetNPCID() - hpPerLogicNPCIDList = ReadChConfig.GetEvalChConfig('HPPerLogicNPCIDList') - if curNPCID not in hpPerLogicNPCIDList: + + hpPerLogicNPCIDDict = IpyGameDataPY.GetFuncEvalCfg('BossHPInformation', 1, {}) + hpPerLogicList = GameWorld.GetDictValueByKey(hpPerLogicNPCIDDict, curNPCID) + if not hpPerLogicList: return - - hpPerLogicDict = ReadChConfig.GetEvalChConfig('HPPerLogic_%s' % curNPCID) - - hpPerList = sorted(hpPerLogicDict.keys(), reverse=True) - + hpPerList, sysMark = hpPerLogicList + hpPerList = sorted(hpPerList, reverse=True) nowHPPer = GameObj.GetHP(curNPC) * 100 / GameObj.GetMaxHP(curNPC) # 当前百分比 hpPerLogicMark = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_HPPerLogicMark) logicHPPerList = hpPerList[hpPerLogicMark:] @@ -3573,16 +3814,12 @@ #GameWorld.DebugLog("DoHPPerLogic npcID=%s,hpPerLogicDict=%s,nowHPPer=%s,hpPerLogicMark=%s,logicHPPerList=%s" # % (curNPCID, str(hpPerLogicDict), nowHPPer, hpPerLogicMark, str(logicHPPerList))) - isNotify, dropItemTemplate, addPrestigeFormat = hpPerLogicDict[hpPer] - if isNotify: - PlayerControl.WorldNotify(0, "FB_liubo_0", [GameWorld.GetMap().GetMapID(), curNPCID, hpPer]) + + PlayerControl.WorldNotify(0, sysMark, [curNPCID, hpPer]) # if dropItemTemplate > 0: # self.__DropItemByTemplate(dropItemTemplate, dropType, ownerID) # PlayerControl.WorldNotify(0, "GeRen_admin_481766", [GameWorld.GetMap().GetMapID(), curNPCID, curNPCID]) - - if addPrestigeFormat != '': - self.__GiveNearbyPlayerPrestige(addPrestigeFormat, ChConfig.Def_Matrix_Six) hpPerLogicMark += 1 #GameWorld.DebugLog("DoHPPerLogic update hpPerLogicMark=%s" % (hpPerLogicMark)) @@ -3707,7 +3944,6 @@ ############################################ #初始化状态 curNPC.SetSpeed(curNPC.GetOrgSpeed()) - curNPC.SetSuperHit(ChConfig.Def_SuperHitPercent) curNPC.SetAtkInterval(curNPC.GetBaseAtkInterval()) # #先清空异常 @@ -3893,11 +4129,11 @@ #杀死NPC, 触发任务 self.__EventKillNpc() - #mapID = GameWorld.GetMap().GetMapID() + mapID = GameWorld.GetMap().GetMapID() killerName = "" if not self.__Killer else self.__Killer.GetPlayerName() # 记录boss击杀信息的NPC bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID) - if bossIpyData: + if bossIpyData and mapID not in [ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_SealDemon]: if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID) #KillerJob = 0 if not self.__Killer else self.__Killer.GetJob() @@ -4097,14 +4333,18 @@ if not dropPlayer: return curNPC = self.__Instance + if curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]: + GameWorld.DebugLog("木桩怪,不掉落物品!") + return npcID = curNPC.GetNPCID() mapID = GameWorld.GetMap().GetMapID() mapID = FBCommon.GetRecordMapID(mapID) isGameBoss = ChConfig.IsGameBoss(curNPC) + if mapID in [ChConfig.Def_FBMapID_MunekadoTrial, ChConfig.Def_FBMapID_DemonKing, ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss]: + GameWorld.DebugLog("该地图不走直接掉落物品逻辑!mapID=%s" % mapID) + return if isGameBoss: GameWorld.Log("NPC开始掉落: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID()) - if mapID == ChConfig.Def_FBMapID_MunekadoTrial: - return ipyDrop = GetNPCDropIpyData(npcID) if not ipyDrop: if isGameBoss: @@ -4779,10 +5019,13 @@ #if self.__GetIsLog(): # GameWorld.Log("玩家增加个人经验,npcID=%s,addExp=%s" % (curNPC.GetNPCID(), add_Exp), curPlayer.GetPlayerID()) - + addSkillID = 0 + if curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID) == curPlayer.GetID(): + addSkillID = curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason) + #设定人物获得经验 playerControl = PlayerControl.PlayerControl(curPlayer) - playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC) + playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC, addSkillID=addSkillID) self.__KillNPCFuncEx(curPlayer, curNPC, curPlayer.GetPlayerID(), False) @@ -4993,8 +5236,11 @@ return #GameWorld.Log("普通队伍杀死怪物,队伍分享人数 = %s,个人经验增加 玩家 = %s, 增加 = %s"%(playerCount, curPlayer.GetPlayerID(), add_Exp)) #设定人物获得经验 + addSkillID = 0 + if curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID) == curPlayer.GetID(): + addSkillID = curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason) playerControl = PlayerControl.PlayerControl(curPlayer) - playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC) + playerControl.AddExp(add_Exp, ShareDefine.Def_ViewExpType_KillNPC, addSkillID=addSkillID) return #--------------------------------------------------------------------- @@ -5109,7 +5355,7 @@ tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) elif dropOwnerType == ChConfig.DropOwnerType_Family: - ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(curNPC, tick, refreshInterval) + ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval) if ownerInfo: tagObj, ownerFamilyID = ownerInfo ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID @@ -5486,21 +5732,6 @@ return max(value / pow(10, nlen), 1) -Def_CollNPCCfg_Len = 10 -( -Def_CollNPCCfg_CanTogether, # 是否允许同时采集 -Def_CollNPCCfg_SysMsgMark, # 不可同时采集提示 -Def_CollNPCCfg_CostItemInfo, # 采集消耗物品信息 -Def_CollNPCCfg_PrepareTime, # 采集时间毫秒 -Def_CollNPCCfg_ExpFormat, # 获得经验公式 -Def_CollNPCCfg_MoneyFormat, # 获得金币公式 -Def_CollNPCCfg_ZhenQi, # 获得的真气/魔魂 -Def_CollNPCCfg_GiveItemModeID, # 获得的物品信息模板编号 -Def_CollNPCCfg_NotCostItemNotify, # 消耗品不足提示 -Def_CollNPCCfg_LimitSysMsgMark, #采集上限提示 -) = range(Def_CollNPCCfg_Len) - - def CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData): # 根据NPCID判断是否可以采集 @@ -5536,9 +5767,13 @@ def OnCollectNPCBegin(curPlayer, curNPC, tick): ## 采集NPC开始采集 npcID = curNPC.GetNPCID() - collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID) + collectNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CollectNPC", npcID) if not collectNPCIpyData: - GameWorld.DebugLog("非特定采集NPC...") + #GameWorld.DebugLog("非特定采集NPC...") + return False + + if collectNPCIpyData.GetIsMissionCollectNPC(): + #GameWorld.DebugLog("任务采集物暂不处理") return False if not CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData): @@ -5641,6 +5876,10 @@ GameWorld.DebugLog(" 非特定采集NPC...npcID=%s" % npcID) return + if collectNPCIpyData.GetIsMissionCollectNPC(): + #GameWorld.DebugLog("任务采集物暂不处理") + return + PlayerState.DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, True) if GameWorld.IsCrossServer(): @@ -5666,33 +5905,116 @@ DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData) return +#// A2 34 自定义场景中获取采集奖励 #tagCMGetCustomSceneCollectAward +# +#struct tagCMGetCustomSceneCollectAward +#{ +# tagHead Head; +# DWORD NPCID; //采集的NPCID +#}; +def OnGetCustomSceneCollectAward(index, clientData, tick): + curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) + playerID = curPlayer.GetPlayerID() + npcID = clientData.NPCID + if not curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene): + GameWorld.ErrLog("非自定义场景中,无法获取定义采集奖励!", playerID) + return + mapID = PlayerControl.GetCustomMapID(curPlayer) + lineID = PlayerControl.GetCustomLineID(curPlayer) + GameWorld.Log("前端场景采集: mapID=%s,lineID=%s,npcID=%s" % (mapID, lineID, npcID), playerID) + if not mapID: + GameWorld.ErrLog("无自定义场景地图ID,不允许采集!", playerID) + return + + if not FBLogic.OnCustomSceneCollectOK(curPlayer, mapID, lineID, npcID): + GameWorld.ErrLog("自定义场景地图不允许采集! mapID=%s,lineID=%s,npcID=%s" % (mapID, lineID, npcID), playerID) + return + + collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID) + if collectNPCIpyData: + DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData) + return + def DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, collectCnt=1): GameWorld.DebugLog("给采集奖励: npcID=%s,collectCnt=%s" % (npcID, collectCnt)) if collectCnt <= 0: return + + if collectNPCIpyData.GetIsMissionCollectNPC(): + #GameWorld.DebugLog("任务采集物暂不处理") + return + isMaxTime = False # 是否达到了采集最大次数 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)) + GameWorld.DebugLog(" 该NPC已达到最大采集次数: npcID=%s,todayCollTime=%s,limitMaxTime=%s" % (npcID, todayCollTime, limitMaxTime)) return - updCollTime = todayCollTime + collectCnt + curCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID) + updCollTime = curCollTime + collectCnt PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime) SyncCollNPCTime(curPlayer, [npcID]) - GameWorld.DebugLog(" 增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime)) - - giveItemList = collectNPCIpyData.GetCollectAward() - if giveItemList: - itemID, itemCount, isAuctionItem = giveItemList - ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]) + GameWorld.DebugLog(" 增加采集次数: npcID=%s,todayCollTime=%s,curCollTime=%s,updCollTime=%s" % (npcID, todayCollTime, curCollTime, updCollTime)) + isMaxTime = todayCollTime + collectCnt >= limitMaxTime + + awardItemList = [] + collectAwardCfg = collectNPCIpyData.GetCollectAward() + collectAppointAwardCfg = collectNPCIpyData.GetCollectAppointAward() + if collectAppointAwardCfg: + #缥缈草园的采集定制由缥缈寻访次数决定 + if collectNPCIpyData.GetCollectResetType() in [12, 14]: + fairyDomainVisitCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FairyDomainVisitCnt) + grasslandCollectAppointCfg = collectAppointAwardCfg.get(fairyDomainVisitCnt, {}) + curCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID) + if curCollTime in grasslandCollectAppointCfg: + awardItemList.append(grasslandCollectAppointCfg[curCollTime]) + GameWorld.DebugLog(" 草园采集定制奖励: fairyDomainVisitCnt=%s,curCollTime=%s,awardItemList=%s" % (fairyDomainVisitCnt, curCollTime, awardItemList)) + else: + collTotalTime = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID) + 1, ChConfig.Def_UpperLimit_DWord) + if collTotalTime in collectAppointAwardCfg: + awardItemList.append(collectAppointAwardCfg[collTotalTime]) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID, collTotalTime) + GameWorld.DebugLog(" 采集次数定制奖励: collTotalTime=%s,awardItemList=%s" % (collTotalTime, awardItemList)) + + if not awardItemList: + alchemyDiffLV = collectNPCIpyData.GetAlchemyDiffLV() + giveItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(curPlayer, collectAwardCfg, alchemyDiffLV) + GameWorld.DebugLog(" 常规采集物品权重列表: alchemyDiffLV=%s,collectAwardCfg=%s,giveItemWeightList=%s" % (alchemyDiffLV, collectAwardCfg, giveItemWeightList)) + giveItemInfo = GameWorld.GetResultByWeightList(giveItemWeightList) + if giveItemInfo: + awardItemList.append(giveItemInfo) + + GameWorld.DebugLog(" 最终采集奖励: awardItemList=%s" % awardItemList) + if awardItemList: + for itemID, itemCount, isAuctionItem in awardItemList: + ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]) + if collectNPCIpyData.GetNotifyCollectResult(): + awardPack = ChPyNetSendPack.tagMCCollectAwardItemInfo() + awardPack.CollectNPCID = npcID + for itemID, itemCount, isAuctionItem in awardItemList: + awardItem = ChPyNetSendPack.tagMCCollectAwardItem() + awardItem.ItemID = itemID + awardItem.Count = itemCount + awardItem.IsAuctionItem = isAuctionItem + awardPack.AwardItemList.append(awardItem) + awardPack.Count = len(awardPack.AwardItemList) + NetPackCommon.SendFakePack(curPlayer, awardPack) + GameLogic_CrossGrassland.RecordGrasslandAward(curPlayer, awardItemList) + else: + GameWorld.ErrLog("采集物品没有奖励!npcID=%s" % (npcID)) #采集成就 PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, collectCnt, [npcID]) #SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID) + + GameLogic_CrossGrassland.DecCustomSceneNPCCount(curPlayer, npcID) + if isMaxTime: + GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer) + return ## 采集结果同步 @@ -5739,11 +6061,20 @@ def CollNPCTimeOnDay(curPlayer): ## 采集NPCOnDay处理 + DoResetCollectNPCTimeByType(curPlayer, [1]) + return + +def DoResetCollectNPCTimeByType(curPlayer, resetTypeList=[]): + '''重置采集物采集次数 + 重置类型: 0-不重置,1-每日5点,12-灵草园重置,14-仙草园重置 + ''' resetNPCIDList = [] ipyDataMgr = IpyGameDataPY.IPY_Data() for index in xrange(ipyDataMgr.GetCollectNPCCount()): ipyData = ipyDataMgr.GetCollectNPCByIndex(index) npcID = ipyData.GetNPCID() + if resetTypeList and ipyData.GetCollectResetType() not in resetTypeList: + continue if not ipyData.GetMaxCollectCount(): continue if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID): @@ -5752,6 +6083,7 @@ resetNPCIDList.append(npcID) if resetNPCIDList: + #GameWorld.DebugLog("重置采集次数: resetTypeList=%s,resetNPCIDList=%s" % (resetTypeList, resetNPCIDList), curPlayer.GetPlayerID()) SyncCollNPCTime(curPlayer, resetNPCIDList) return @@ -5901,7 +6233,7 @@ NetPackCommon.SendFakePack(curPlayer, npcInfoPack) return -def SendGameServerGoodItemRecord(mapID, npcID, playerName, playerID, itemID, equipInfo=[], serverGroupID=0): +def SendGameServerGoodItemRecord(curPlayer, mapID, lineID, npcID, itemID, equipInfo=[]): # @param equipInfo: [equipPlace, itemClassLV, itemColor, itemQuality, itemUserData] # GameWorld.DebugLog("检查物品是否发送GameServer: mapID=%s, npcID=%s, playerName=%s, itemID=%s" # % (mapID, npcID, playerName, itemID)) @@ -5921,18 +6253,21 @@ needRecord = True weightValue = recSpecialItemIDList.index(itemID) + 10000 else: - equipPlace, itemClassLV, itemColor, itemQuality, itemUserData = equipInfo - weightValue = itemColor*1000+itemQuality*100+itemClassLV + equipPlace, itemClassLV, itemColor, suiteID, itemUserData = equipInfo + isSuit = 1 if suiteID else 0 + weightValue = itemColor*1000+isSuit*100+itemClassLV recordCondition = GameWorld.GetDictValueByKey(recDropEquipInfoDict, equipPlace) if recordCondition: - needClassLV, needItemColor, needItemQuality = recordCondition - if itemClassLV >= needClassLV and itemColor >= needItemColor and itemQuality >= needItemQuality: + needClassLV, needItemColor, needItemSuite = recordCondition + if itemClassLV >= needClassLV and itemColor >= needItemColor and isSuit >= needItemSuite: needRecord = True if not needRecord: return - - dropEquipMsg = str([playerID, playerName, mapID, npcID, itemID, itemUserData, weightValue, serverGroupID]) + playerID = curPlayer.GetID() + playerName = curPlayer.GetName() + serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer) + dropEquipMsg = str([playerID, playerName, mapID, lineID, npcID, itemID, itemUserData, weightValue, serverGroupID, curPlayer.GetLV()]) GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'BossDropGoodItem', dropEquipMsg, len(dropEquipMsg)) GameWorld.DebugLog("发送GameServer记录拾取掉落好物品: %s" % dropEquipMsg, playerID) return @@ -6044,3 +6379,117 @@ sendPack.Value = speed curNPC.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength()) return + +def UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount=0): + ## 更新玩家攻击NPC次数 + if not npcID: + return + GameWorld.DebugLog("更新玩家攻击NPC次数: npcID=%s,attackCount=%s,maxCount=%s" % (npcID, attackCount, maxCount)) + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCAttackCount % npcID, attackCount) + + if GameWorld.IsCrossServer(): + serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer) + msgInfo = {"PlayerID":curPlayer.GetPlayerID(), "NPCID":npcID, "AttackCount":attackCount, "MaxCount":maxCount} + GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_NPCAttackCount, msgInfo, [serverGroupID]) + else: + SyncNPCAttackCount(curPlayer, [npcID]) + if attackCount and attackCount >= maxCount: + GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer) + return + +def CrossServerMsg_NPCAttackCount(curPlayer, msgData): + ## 收到跨服服务器同步的攻击NPC次数 + npcID = msgData["NPCID"] + attackCount = msgData["AttackCount"] + maxCount = msgData["MaxCount"] + UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount) + return + +def SyncNPCAttackCount(curPlayer, npcIDList): + ## 同步NPC攻击次数 + if not npcIDList: + return + + clientPack = ChPyNetSendPack.tagMCNPCAttackCountInfo() + for npcID in npcIDList: + attackCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCAttackCount % npcID) + atkCountObj = ChPyNetSendPack.tagMCNPCAttackCount() + atkCountObj.NPCID = npcID + atkCountObj.AttackCount = attackCount + clientPack.NPCAttackCountList.append(atkCountObj) + clientPack.Count = len(clientPack.NPCAttackCountList) + NetPackCommon.SendFakePack(curPlayer, clientPack) + return + + +def OnNPCAttacked(atkObj, curNPC, skill, tick): + ## NPC被攻击 + __OnAttackedDropItem(atkObj, curNPC) + return + +## 每次被攻击掉落物品 +# @param atkObj 攻击发起者 +# @param curNPC 被攻击NPC +# @return None +def __OnAttackedDropItem(atkObj, curNPC): + attackPlayer, npcObjType = AttackCommon.GetAttackPlayer(atkObj) + if npcObjType: + return + if not attackPlayer: + return + npcID = curNPC.GetNPCID() + ipyData = IpyGameDataPY.GetIpyGameDataNotLog("TreasureNPC", npcID) + if not ipyData: + return + attackCountDropWeightInfo = ipyData.GetAttackCountDropWeightInfo() + attackDropWeightList = ipyData.GetAttackDropWeightList() + attackDropWeightListEx = ipyData.GetAttackDropWeightListEx() + dropCountEx = ipyData.GetDropCountEx() + alchemyDiffLV = ipyData.GetAlchemyDiffLV() + + mainItemWeightList = [] + if attackCountDropWeightInfo: + maxCount = max(attackCountDropWeightInfo) + attackCount = attackPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCAttackCount % npcID) + 1 + if attackCount <= maxCount: + if attackCount in attackCountDropWeightInfo: + mainItemWeightList = attackCountDropWeightInfo[attackCount] + UpdateNPCAttackCount(attackPlayer, npcID, attackCount, maxCount) + + if mainItemWeightList: + mainItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, mainItemWeightList, alchemyDiffLV) + elif attackDropWeightList: + mainItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, attackDropWeightList, alchemyDiffLV) + + mainItemInfo = GameWorld.GetResultByWeightList(mainItemWeightList) + + if not mainItemInfo: + notDropNotify = ipyData.GetNotDropNotify() + if notDropNotify: + PlayerControl.NotifyCode(attackPlayer, notDropNotify) + return + + dropItemList = [] + if mainItemInfo: + dropItemList.append(mainItemInfo) + + if attackDropWeightListEx and dropCountEx: + weightListEx = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, attackDropWeightListEx, alchemyDiffLV) + for _ in xrange(dropCountEx): + itemInfo = GameWorld.GetResultByWeightList(weightListEx) + if itemInfo: + dropItemList.append(itemInfo) + + if not dropItemList: + return + + mapID = PlayerControl.GetCustomMapID(attackPlayer) + if mapID: + DoGiveItemByVirtualDrop(attackPlayer, dropItemList, npcID) + GameLogic_CrossGrassland.RecordGrasslandAward(attackPlayer, dropItemList) + else: + dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() + ChItem.DoMapDropItem(attackPlayer, dropItemList, npcID, dropPosX, dropPosY, isOnlySelfSee=False) + return + + \ No newline at end of file -- Gitblit v1.8.0