From 63f6f44ec2a38eaec9f39bbe26edb07daed49b49 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期二, 16 九月 2025 17:36:50 +0800 Subject: [PATCH] 129 【战斗】战斗系统-服务端(王元姬技能,弹射待处理;支持被动变更伤害倍值;) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 2292 ++-------------------------------------------------------- 1 files changed, 91 insertions(+), 2,201 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 44004d6..5059b04 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -20,7 +20,6 @@ import PlayerControl import GameMap import ChConfig -import EventShell import SkillShell import BuffSkill import BaseAttack @@ -43,20 +42,12 @@ import FBCommon import PlayerActivity import PlayerSuccess -import BossHurtMng import PlayerPrestigeSys import GY_Query_BossFirstKill -import GameLogic_FamilyInvade -import GameLogic_GatherSoul import FormulaControl import PlayerBossReborn -import PlayerFairyCeremony import PlayerCrossYaomoBoss import PlayerActCollectWords -import PlayerNewFairyCeremony -import GameLogic_CrossGrassland -import PlayerActGarbageSorting -import PlayerActBossTrial import PlayerTongTianLing import CrossPlayerData import PlayerFeastWish @@ -64,18 +55,14 @@ import PlayerGoldInvest import PlayerWeekParty import NPCRealmRefresh -import NPCHurtManager import PlayerActLogin import PlayerActTask import PlayerZhanling -import FamilyRobBoss import IpyGameDataPY import PlayerGubao import PlayerState +import TurnAttack import PyGameData -import PlayerTeam -import NPCHurtMgr -import PlayerVip import GameObj import ChNPC @@ -129,12 +116,12 @@ return realmNPCIpyData.GetLV() return curNPC.GetLV() -def GetNPCDataEx(npcID): - ## 获取NPC扩展数据表,可热更 - npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPCEx", npcID) +def GetNPCDataPy(npcID): + ## 获取NPC数据表,py自定义的表,可热更 + npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPC", npcID) if not npcDataEx: if False: # 不可能成立的条件,只为了 . 出代码提示 - npcDataEx = IpyGameDataPY.IPY_NPCEx() + npcDataEx = IpyGameDataPY.IPY_NPC() return npcDataEx return npcDataEx @@ -142,15 +129,13 @@ def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV) # NPC表中此字段含义改成境界等级 def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # 风防代表是否等级压制 def GetFightPowerLackAtkLimit(curNPC): # 战力不足限制攻击,默认不限制 - npcDataEx = GetNPCDataEx(curNPC.GetNPCID()) - return npcDataEx.GetFightPowerLackAtkLimit() if npcDataEx else 0 -def GetSuppressFightPower(curNPC): - npcDataEx = GetNPCDataEx(curNPC.GetNPCID()) - return npcDataEx.GetSuppressFightPower() if npcDataEx else curNPC.GetThunderDef() # 雷防代表压制战力 + return 0 +def GetSuppressFightPower(curNPC): # 压制战力 + return 0 def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord)) def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # 火防代表推荐战力 def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # 雷攻代表掉落归属类型 -def GetFaction(curNPC): return curNPC.GetCountry() +def GetFaction(curNPC): return GameObj.GetFaction(curNPC) def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率 def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果 def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果 @@ -158,122 +143,6 @@ def GetNPCSeries(curNPC): return curNPC.GetPoisionDef() # 毒防字段代表NPC系,按二进制位区分 def DoNPCAttrStrengthen(curNPC, isReborn, isDyn=False): - '''NPC属性增强, NPC属性成长由两个因素决定 - 1.NPC成长等级,成长等级决定成长属性,与成长表结合使用 - 可设置地图NPC等级动态成长,但是已经刷新出来的NPC等级不变,动态等级变更后刷新的NPC等级才会使用最新等级 - - 2.玩家人数因素,决定NPC属性的额外成长系数,可单独使用,或者和1一起使用 - 可设置马上刷新NPC属性 - 除血量外,其他属性会根据动态因素直接变更 - 血量会根据血量百分比动态变更至相应的百分比 - ''' - npcID = curNPC.GetNPCID() - strengthenIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCStrengthen", npcID) - if not strengthenIpyData: - #GameWorld.DebugLog("该NPC属性不成长!npcID=%s" % npcID) - return - - strengthenLV = 0 - strengthenPlayerCnt = 0 - - gameFB = GameWorld.GetGameFB() - - if strengthenIpyData.GetIsStrengthenByPlayerCount(): - if FamilyRobBoss.IsHorsePetRobBoss(npcID): - strengthenPlayerCnt = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_HorsePetRobBossPlayerCount) - else: - strengthenPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt) - if not strengthenPlayerCnt: - GameWorld.ErrLog("NPC配置了按玩家人数成长类型,但是无法获取到对应的玩家人数!npcID=%s" % (npcID)) - return - - lvStrengthenType = strengthenIpyData.GetLVStrengthenType() - # 根据世界等级 - if lvStrengthenType == 3: - strengthenLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv) - # 根据最大等级 - elif lvStrengthenType == 2: - strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV) - # 根据平均等级 - elif lvStrengthenType == 1: - strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenAverageLV) - # 根据按成长等级的上下限随机 - elif lvStrengthenType == 4: - randMinLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMinLV) - randMaxLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV) - strengthenLV = random.randint(randMinLV, randMaxLV) - # 根据境界难度 - elif lvStrengthenType == 5: - realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel()) - realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) - if realmNPCIpyData: - strengthenLV = realmNPCIpyData.GetLV() - else: - lvStrengthenType = 0 - - # 木桩怪最大、平均成长等级处理,直接取归属玩家等级 - 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()) - - if lvStrengthenType in [1, 2] and not strengthenLV: - GameWorld.ErrLog("NPC配置了成长等级类型,但是无法获取到对应的成长等级值!npcID=%s,lvStrengthenType=%s" % (npcID, lvStrengthenType)) - return - - # 副本特殊指定 - npcFBAttrDict = FBLogic.GetFBNPCStrengthenAttr(curNPC, isReborn) - if "LV" in npcFBAttrDict: - strengthenLV = npcFBAttrDict["LV"] - - attrDict = GetNPCStrengthenAttrDict(npcID, strengthenLV, strengthenPlayerCnt, strengthenIpyData) - attrDict.update(npcFBAttrDict) # 如果副本有指定属性,则以副本为主 - if not attrDict: - return - - # 成长等级只在重生的时候设置一次 - if isReborn and curNPC.GetCurLV() != strengthenLV: - curNPC.SetCurLV(strengthenLV, False) # 重生的不通知等级变更,属性成长刷新后由NPC出现包通知 - - befMaxHP = GameObj.GetMaxHP(curNPC) - befHP = GameObj.GetHP(curNPC) - #GameWorld.DebugLog("NPC属性成长刷新,isReborn=%s,npcID=%s,LV=%s,curLV=%s,befMaxHP=%s,befHP=%s,attrDict=%s" - # % (isReborn, npcID, curNPC.GetLV(), curNPC.GetCurLV(), befMaxHP, befHP, attrDict)) - for attrKey, strengthenValue in attrDict.items(): - if not hasattr(curNPC, "Set%s" % attrKey): - if attrKey == "FightPower": - SetSuppressFightPower(curNPC, strengthenValue) - continue - - if attrKey == "MaxHP": - GameObj.SetMaxHP(curNPC, strengthenValue) - else: - strengthenValue = min(strengthenValue, ChConfig.Def_UpperLimit_DWord) - getattr(curNPC, "Set%s" % attrKey)(strengthenValue) - #GameWorld.DebugLog(" %s=%s" % (attrKey, strengthenValue)) - - aftMaxHP = GameObj.GetMaxHP(curNPC) - if befMaxHP != aftMaxHP: - if isReborn: - GameObj.SetHP(curNPC, aftMaxHP) - elif isDyn: - # 动态刷新属性的,血量按百分比继承 - aftHP = int(aftMaxHP * befHP / befMaxHP) - GameObj.SetHP(curNPC, aftHP) - curNPC.Notify_HP() - curNPC.Notify_MaxHP() - #GameWorld.DebugLog(" aftHP=%s,aftMaxHP=%s" % (aftHP, aftMaxHP)) - - # 机器人复活初始化给技能 - if isReborn and curNPC.GetType() == ChConfig.ntRobot: - __OnFBRobotReborn(curNPC, strengthenLV) - return def __OnFBRobotReborn(curNPC, npcLV): @@ -300,151 +169,6 @@ FBLogic.OnRandomRobotJob(curNPC, lineRobotJobDict) return - -def __DoGiveVSPlayerNPCSkill(curNPC, job, npcLV): - skillManager = curNPC.GetSkillManager() - jobSkillDict = IpyGameDataPY.GetFuncEvalCfg("XMZZRobotSkill", 1) - if job not in jobSkillDict: - return - skillInfoDict = jobSkillDict[job] - #{1:{(100, 101, 102, 103):1, 50000:100, 50100:200, 50400:300}, 2:{(200, 201, 202, 203):1, 55000:100, 55100:200, 55200:300}} - skillIDList = [] - for skillInfo, needLV in skillInfoDict.items(): - if npcLV < needLV: - continue - if isinstance(skillInfo, int): - skillIDList.append(skillInfo) - else: - skillIDList += list(skillInfo) - GameWorld.DebugLog("给NPC技能: job=%s,npcLV=%s, %s" % (job, npcLV, skillIDList)) - for skillID in skillIDList: - skillManager.LearnSkillByID(skillID) - return - -def GetNPCStrengthenAttrDict(npcID, strengthenLV=0, strengthenPlayerCnt=0, strengthenIpyData=None): - if not strengthenLV and not strengthenPlayerCnt: - return {} - npcData = GameWorld.GetGameData().FindNPCDataByID(npcID) - if not npcData: - return {} - - attrStrengthenInfo = ReadChConfig.GetEvalChConfig("NPCAttrStrengthen") - if not attrStrengthenInfo: - return {} - - attrDict = {} - paramDict = attrStrengthenInfo[NPCAttr_ParamDict] # 过程参数公式字典 - attrStrengthenDict = attrStrengthenInfo[NPCAttr_AttrStrengthenList] # 属性成长公式字典 - playerCntCoefficient = attrStrengthenInfo[NPCAttr_PlayerCntCoefficient] # 人数系数 - npcIDPlayerCntCoefficient = attrStrengthenInfo[NPCAttr_NPCPlayerCntCoefficient] # 特殊NPC人数系数 - baseMaxHP = GameObj.GetHP(npcData) # NPCData 没有提供Max接口,对应使用GetHP - - if strengthenLV: - if not strengthenIpyData: - strengthenIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCStrengthen", npcID) - if not strengthenIpyData: - return {} - - playerCurLVIpyData = PlayerControl.GetPlayerLVIpyData(strengthenLV) # 取增强怪物等级对应此等级的玩家参考属性值 - if not playerCurLVIpyData: - return {} - - # NPC表可用参数 - SkillAtkRate = GetSkillAtkRate(npcData) # 技能伤害 - FinalHurt = GetFinalHurt(npcData) - - # 参考玩家属性参数 - ReMaxHP = playerCurLVIpyData.GetReMaxHP() # 最大生命值 - ReAtk = playerCurLVIpyData.GetReAtk() # 攻击(最小、最大攻击) - ReDef = playerCurLVIpyData.GetReDef() # 防御 - ReHit = playerCurLVIpyData.GetReHit() # 命中 - ReMiss = playerCurLVIpyData.GetReMiss() # 闪避 - ReAtkSpeed = playerCurLVIpyData.GetReAtkSpeed() # 攻击速度 - ReSkillAtkRate = playerCurLVIpyData.GetReSkillAtkRate() # 技能伤害比例 - ReDamagePer = playerCurLVIpyData.GetReDamagePer() # 增加伤害 - ReDamReduce = playerCurLVIpyData.GetReDamReduce() # 减少伤害 - ReIgnoreDefRate = playerCurLVIpyData.GetReIgnoreDefRate() # 无视防御比例 - ReLuckyHitRate = playerCurLVIpyData.GetReLuckyHitRate() # 会心一击率 - ReLuckyHit = playerCurLVIpyData.GetReLuckyHit() # 会心一击伤害 - ReBleedDamage = playerCurLVIpyData.GetReBleedDamage() # 流血伤害增加 - ReIceAtk = playerCurLVIpyData.GetReIceAtk() # 真实伤害 - ReIceDef = playerCurLVIpyData.GetReIceDef() # 真实抵御 - RePetAtk = playerCurLVIpyData.GetRePetAtk() # 灵宠攻击 - RePetSkillAtkRate = playerCurLVIpyData.GetRePetSkillAtkRate() # 灵宠技能 - RePetDamPer = playerCurLVIpyData.GetRePetDamPer() # 灵宠伤害增加 - ReFinalHurt = playerCurLVIpyData.GetReFinalHurt() # 固定伤害增加 - ReFinalHurtReduce = playerCurLVIpyData.GetReFinalHurtReduce() # 固定伤害减少 - RePotionReply = playerCurLVIpyData.GetRePotionReply() # 血瓶恢复量 - RePotionCD = playerCurLVIpyData.GetRePotionCD() # 血瓶CD - ReFightPower = playerCurLVIpyData.GetReFightPower() # 战斗力 - - # 增加NPC属性参数 - HitTime = strengthenIpyData.GetHitTime() # 怪物受击次数 - DefCoefficient = strengthenIpyData.GetDefCoefficient() # 人物防御系数 - AtkCoefficient = strengthenIpyData.GetAtkCoefficient() # 人物攻击系数 - AdjustCoefficient = strengthenIpyData.GetAdjustCoefficient() # 调整系数比例 - AtkInterval = strengthenIpyData.GetAtkInterval() # 怪物攻击间隔 - HitRate = strengthenIpyData.GetHitRate() # 对人物的命中率 - MissRate = strengthenIpyData.GetMissRate() # 对人物的闪避率 - MonterNum = strengthenIpyData.GetMonterNum() # 怪物数 - IceAtkCoefficient = strengthenIpyData.GetIceAtkCoefficient() # 元素攻击比例 - IceDefCoefficient = strengthenIpyData.GetIceDefCoefficient() # 元素抗性比例 - MaxEnduranceTime = strengthenIpyData.GetMaxEnduranceTime() # 玩家最大承受伤害时间 - FightPowerCoefficient = strengthenIpyData.GetFightPowerCoefficient() # 压制战斗力系数 - - # 过程参数 - AtkReplyCoefficient = eval(FormulaControl.GetCompileFormula("NPCParam_AtkReplyCoefficient", - paramDict["AtkReplyCoefficient"])) # 怪物攻击回复调整值 - MonterHurt = eval(FormulaControl.GetCompileFormula("NPCParam_MonterHurt", paramDict["MonterHurt"])) # 怪物固定伤害 - LostHPPerSecond = eval(FormulaControl.GetCompileFormula("NPCParam_LostHPPerSecond", paramDict["LostHPPerSecond"])) # 玩家每秒掉血量 - LVStrengthenMark = strengthenIpyData.GetLVStrengthenMark() - attrStrengthenList = attrStrengthenDict.get(LVStrengthenMark, []) - for attrKey, strengthenFormat in attrStrengthenList: - strengthenValue = int(eval(FormulaControl.GetCompileFormula("NPCStrengthen_%s_%s" % (attrKey,LVStrengthenMark), strengthenFormat))) - #GameWorld.DebugLog(" %s=%s" % (attrKey, strengthenValue)) - locals()[attrKey] = strengthenValue # 创建该属性局部变量作为参数提供给后面属性计算时用 - attrDict[attrKey] = strengthenValue - - # 当战力系数为0时,NPC战力默认为NPC表压制战力 - if FightPowerCoefficient: - attrDict["FightPower"] = int(ReFightPower * FightPowerCoefficient / 10000.0) - - if strengthenPlayerCnt: - mapID = GameWorld.GetMap().GetMapID() - dataMapID = FBCommon.GetRecordMapID(mapID) - formulaKey = "MapCoefficient_%s" % mapID - playerCntAttrCoefficient = playerCntCoefficient.get(mapID, {}) - if not playerCntAttrCoefficient and dataMapID in playerCntCoefficient: - playerCntAttrCoefficient = playerCntCoefficient[dataMapID] - formulaKey = "MapCoefficient_%s" % dataMapID - if npcID in npcIDPlayerCntCoefficient: - playerCntAttrCoefficient = npcIDPlayerCntCoefficient[npcID] - formulaKey = "NPCCoefficient_%s" % npcID - for attrKey, coefficientDict in playerCntAttrCoefficient.items(): - if attrKey in attrDict: - attrValue = attrDict[attrKey] - elif attrKey == "MaxHP": - attrValue = baseMaxHP - else: - attrFuncName = "Get%s" % attrKey - if not hasattr(npcData, attrFuncName): - continue - attrValue = getattr(npcData, attrFuncName)() - # 按字典配置 - if isinstance(coefficientDict, dict): - coefficient = GameWorld.GetDictValueByRangeKey(coefficientDict, strengthenPlayerCnt, 1) - # 按公式配置 - elif isinstance(coefficientDict, str): - formulaKey = "%s_%s" % (formulaKey, attrKey) - coefficient = eval(FormulaControl.GetCompileFormula(formulaKey, coefficientDict)) - else: - coefficient = 1 - attrDict[attrKey] = int(attrValue * coefficient) - - #GameWorld.DebugLog("计算NPC属性成长: npcID=%s,strengthenLV=%s,strengthenPlayerCnt=%s,baseMaxHP=%s,attrDict=%s" - # % (npcID, strengthenLV, strengthenPlayerCnt, baseMaxHP, attrDict)) - return attrDict - def GiveKillNPCDropPrize(curPlayer, mapID, npcCountDict, exp_rate=None, mailTypeKey=None, isMail=False, extraItemList=[], prizeMultiple=1, dropItemMapInfo=[], curGrade=0, isVirtualDrop=False): '''给玩家击杀NPC掉落奖励 @@ -459,1156 +183,19 @@ @param curGrade: 评级 @param isVirtualDrop: 是否给物品虚拟掉落表现 ''' - if not exp_rate: - exp_rate = PlayerControl.GetPlayerExpRate(curPlayer) - - npcID = 0 totalExp = 0 totalMoney = 0 - itemCountDict = {} - auctionItemIDList = [] - - if prizeMultiple > 1: - hadDropItemKeyList, hadDropItemPlaceList = [], [] # 已经掉落过的物品集合key列表, 已经掉落过的装备部位列表 - mPrizeItemIDList = IpyGameDataPY.GetFuncEvalCfg("SealDemonDoubleDrop", 1) # 允许多倍奖励的物品ID列表 - mPrizePlaceList = IpyGameDataPY.GetFuncEvalCfg("SealDemonDoubleDrop", 2) # 允许多倍奖励的装备部位 - mPrizeItemKeyList = IpyGameDataPY.GetFuncEvalCfg("SealDemonDoubleDrop", 3) # 允许多倍奖励的物品ID集合 - - itemKeyDict = IpyGameDataPY.GetFuncEvalCfg("JobItemDropSets") # {物品ID集合key:[职业顺序物品ID列表], ...} - itemIDKeyDict = {} - for itemKey, itemIDList in itemKeyDict.items(): - for itemID in itemIDList: - itemIDKeyDict[itemID] = itemKey - - for npcID, count in npcCountDict.items(): - baseExp = GetNPCExp(curPlayer, npcID) - addExp = int(baseExp * exp_rate / float(ChConfig.Def_MaxRateValue)) # 基础加成 - totalCount = count * prizeMultiple - totalExp += (addExp * totalCount) - - # 掉落有概率因素,需多次执行 - for dCount in xrange(1, totalCount + 1): - isKillCountDrop = dCount == 1 # 同一只NPC一次处理中多次击杀的情况,只算一次附加装备处理 - dropInfo = GetNPCDropInfo(curPlayer, mapID, npcID, isKillCountDrop=isKillCountDrop, curGrade=curGrade) - if not dropInfo: - continue - dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo - totalMoney += (dropMoneyCnt * moneyValue) - - for itemID in dropIDList: - if prizeMultiple > 1: - itemData = GameWorld.GetGameData().GetItemByTypeID(itemID) - if not itemData: - continue - itemPlace = itemData.GetEquipPlace() - itemKey = itemIDKeyDict.get(itemID) - - # 超过指定最大只数时,代表多倍奖励,多倍奖励的物品只允许给指定规则内的物品,只对已经掉过的物品有限制 - if dCount > count: - if ItemCommon.GetIsEquip(itemData): - if itemPlace in hadDropItemPlaceList and itemPlace not in mPrizePlaceList: - GameWorld.DebugLog(" 多倍奖励不能给的物品部位: itemID=%s,itemPlace=%s" % (itemID, itemPlace)) - continue - elif itemKey != None: - if itemKey in hadDropItemKeyList and itemKey not in mPrizeItemKeyList: - GameWorld.DebugLog(" 多倍奖励不能给的物品ID集合: itemID=%s,itemKey=%s" % (itemID, itemKey)) - continue - else: - if itemID in itemCountDict and itemID not in mPrizeItemIDList: - GameWorld.DebugLog(" 多倍奖励不能给的物品ID: itemID=%s" % (itemID)) - continue - - if itemPlace and itemPlace not in hadDropItemPlaceList: - hadDropItemPlaceList.append(itemPlace) - if itemKey != None and itemKey not in hadDropItemKeyList: - hadDropItemKeyList.append(itemKey) - - itemCountDict[itemID] = itemCountDict.get(itemID, 0) + 1 - if itemID in auctionIDList and itemID not in auctionItemIDList: - auctionItemIDList.append(itemID) - - # 固定附加物品 - for itemID, itemCount, isAuctionItem in extraItemList: - itemCountDict[itemID] = itemCountDict.get(itemID, 0) + itemCount * prizeMultiple - if isAuctionItem and itemID not in auctionItemIDList: - auctionItemIDList.append(itemID) - - needSpace = 0 - prizeItemList = [] jsonItemList = [] - for itemID, itemCount in itemCountDict.items(): - itemData = GameWorld.GetGameData().GetItemByTypeID(itemID) - if not itemData: - continue - - isAuctionItem = itemID in auctionItemIDList - - if ItemCommon.GetIsEquip(itemData): - for _ in xrange(itemCount): - curItem = ItemControler.GetOutPutItemObj(itemID, 1, isAuctionItem, curPlayer=curPlayer) - if curItem: - needSpace += 1 - prizeItemList.append(curItem) - jsonItemList.append(ItemCommon.GetJsonItem(curItem)) - else: - needSpace += ItemControler.GetItemNeedPackCount(IPY_GameWorld.rptItem, itemData, itemCount, isAuctionItem) - prizeItemList.append([itemID, itemCount, isAuctionItem]) - jsonItemList.append(ItemCommon.GetJsonItem([itemID, itemCount, isAuctionItem])) - #成就 - if not dropItemMapInfo: - PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_PickUpItem, itemCount, [itemID]) - - ## 直接掉地板上 - if dropItemMapInfo: - dropPosX, dropPosY = dropItemMapInfo[:2] - isOnlySelfSee = dropItemMapInfo[2] if len(dropItemMapInfo) > 2 else False # 是否仅自己可见 - isDropDisperse = dropItemMapInfo[3] if len(dropItemMapInfo) > 3 else False # 堆叠的物品是否散开掉落 - ## 虚拟掉落表现 - if isVirtualDrop: - DoGiveItemByVirtualDrop(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse, mailTypeKey) - else: - DoMapDropPrizeItem(curPlayer, prizeItemList, npcID, dropPosX, dropPosY, isDropDisperse, isOnlySelfSee) - - ## 发邮件 或 背包空间不足 - elif isMail or needSpace > ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace): - mailItemList = [] - for prizeItem in prizeItemList: - if isinstance(prizeItem, list): - mailItemList.append(prizeItem) - else: - mailItemList.append(ItemCommon.GetMailItemDict(prizeItem)) - prizeItem.Clear() # 发邮件已经创建的物品实例要清空, 不然会导致内存泄露 - #if totalExp: - # expItemID = 0 - # mailItemList.append([expItemID, totalExp, 1]) - PlayerControl.SendMailByKey(mailTypeKey, [curPlayer.GetPlayerID()], mailItemList, silver=totalMoney) - - ## 直接放入背包 - else: - event = [ChConfig.ItemGive_NPCDrop, False, {"NPCID":npcID}] - for prizeItem in prizeItemList: - if isinstance(prizeItem, list): - itemID, itemCount, isAuctionItem = prizeItem - ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem], - event=event) - else: - ItemControler.DoLogic_PutItemInPack(curPlayer, prizeItem, event=event) - - if totalExp: - PlayerControl.PlayerControl(curPlayer).AddExp(totalExp) - - if totalMoney: - PlayerControl.GiveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, totalMoney) - - #GameWorld.DebugLog("给玩家击杀NPC掉落奖励: mapID=%s,npcCountDict=%s,exp_rate=%s,mailTypeKey=%s,isMail=%s,extraItemList=%s" - # % (mapID, npcCountDict, exp_rate, mailTypeKey, isMail, extraItemList)) - #GameWorld.DebugLog(" totalExp=%s,totalMoney=%s,needSpace=%s,jsonItemList=%s" % (totalExp, totalMoney, needSpace, jsonItemList)) return jsonItemList, totalExp, totalMoney - -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() - sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer) - 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 - - curItem = dropItemList[index] - index += 1 - 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, sightLevel=sightLevel) - return def DoGiveItemByVirtualDrop(curPlayer, giveItemList, npcID, dropPosX=0, dropPosY=0, isDropDisperse=True, mailTypeKey="ItemNoPickUp", extraVirtualItemList=[]): ## 给物品并且做假掉落表现,直接先堆叠给物品,再拆开做虚假掉落表现 - - if not giveItemList: - return - - 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) or isinstance(itemInfo, tuple): - itemID, itemCount, isAuctionItem = itemInfo - curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer) - if not curItem: - continue - elif hasattr(itemInfo, "GetItemTypeID"): - curItem = itemInfo - itemID = curItem.GetItemTypeID() - itemCount = curItem.GetCount() - isAuctionItem = ItemControler.GetIsAuctionItem(curItem) - else: - continue - dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem) - giveItemObjList.append(curItem) - - # 散开掉落 - if isDropDisperse: - for _ in xrange(itemCount): - virtualItemDropList.append([itemID, dropItemDataStr]) - else: - virtualItemDropList.append([itemID, dropItemDataStr]) - - # 先通知掉落,再给物品,因为前端表现弹框需要这个顺序需求 - if extraVirtualItemList: #只显示假掉落 - for itemInfo in extraVirtualItemList: - itemID, itemCount, isAuctionItem = itemInfo - curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer) - if not curItem: - continue - dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem) - # 散开掉落 - if isDropDisperse: - for _ in xrange(itemCount): - virtualItemDropList.append([itemID, dropItemDataStr]) - else: - virtualItemDropList.append([itemID, dropItemDataStr]) - curItem.Clear() - - 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) - - # 再给物品 - 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) - 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掉落 ################################### Def_NPCMaxDropRate = 1000000 # NPC掉落相关的最大概率, 数值设定 -def GetNPCDropIpyData(npcID): - ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("NPCDropItem", npcID) - if not ipyDataList: - GameWorld.DebugLog("该NPC没配置掉落!npcID=%s" % npcID) - return - ipyDrop = None - maxWorldLV = 0 - curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv) - if len(ipyDataList) == 1: - ipyDrop = ipyDataList[0] - maxWorldLV = ipyDrop.GetMaxWorldLV() - if maxWorldLV and curWorldLV > maxWorldLV: - GameWorld.DebugLog("该NPC当前世界等级无法掉落物品!npcID=%s,curWorldLV(%s) > maxWorldLV(%s)" % (npcID, curWorldLV, maxWorldLV)) - return - else: - for ipyData in ipyDataList: - maxWorldLV = ipyData.GetMaxWorldLV() - if curWorldLV <= maxWorldLV: - ipyDrop = ipyData - break - if not ipyDrop: - GameWorld.DebugLog("该NPC当前世界等级无法掉落物品!npcID=%s,curWorldLV=%s,maxWorldLV=%s" % (npcID, curWorldLV, maxWorldLV)) - return - return ipyDrop - -def GetNPCDropInfoTJG(dropPlayer, mapID, npcID, killCount): - '''脱机挂杀怪掉落专用函数 - 只算: 1.饼图装备掉落 + 2.指定物品ID掉落 + 3.金币掉落 - ''' - ipyDrop = GetNPCDropIpyData(npcID) - if not ipyDrop: - return - - realmNPCIpyData = None - realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1) - realmDifficulty = PlayerControl.GetRealmDifficulty(dropPlayer) - if mapID in realmMapIDList and realmDifficulty: - realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty) - realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) - #if realmNPCIpyData: - # maxDropLV = realmNPCIpyData.GetMaxDrapLV() - - #脱机暂不限制最大等级掉落 - #playerLV = dropPlayer.GetLV() - #maxDropLV = ipyDrop.GetMaxDropLV() - #if maxDropLV and playerLV > maxDropLV: - # GameWorld.DebugLog("超过最大可掉落等级,不掉落物品!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV)) - # return - - playerID = dropPlayer.GetPlayerID() - npcData = GameWorld.GetGameData().FindNPCDataByID(npcID) - if not npcData: - return - - dropIDList = [] # 掉落的ID列表 - itemJobList = [dropPlayer.GetJob()] if ipyDrop.GetIsDropJobSelf() else IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # 掉落装备职业列表 - - equipDropRatePlus = PlayerControl.GetDropEquipPer(dropPlayer) - equipDropDoCountPlus = PlayerControl.GetDropEquipDoCount(dropPlayer) - - dropRatePlusValue = ipyDrop.GetCanDropRatePlus() - if not dropRatePlusValue & pow(2, 0): - equipDropRatePlus = 0 - - if not dropRatePlusValue & pow(2, 1): - equipDropDoCountPlus = 0 - - doCountAdd = 0 - doCountRate = ChConfig.Def_MaxRateValue - - GameWorld.DebugLog("脱机挂杀怪掉落: npcID=%s,killCount=%s,itemJobList=%s,dropRatePlusValue=%s,equipDropRatePlus=%s,equipDropDoCountPlus=%s" - % (npcID, killCount, itemJobList, dropRatePlusValue, equipDropRatePlus, equipDropDoCountPlus), playerID) - - dropEquipInfoList = [] # [(阶,颜色, 件数), ...] - # 1.装备只算饼图概率 - pieRateDoCnt = ipyDrop.GetPieRateDoCnt() - if pieRateDoCnt and ipyDrop.GetPieRateDrop(): - pieRateDoCnt = __GetNPCDropDoCountChange(pieRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd) - pieRateDoCnt *= killCount - pieRateDropList = ipyDrop.GetPieRateDrop() # [(概率,0),(概率,(阶,颜色)),...] - if equipDropRatePlus: - dropRateList = GameWorld.GetPlusPieList(pieRateDropList, equipDropRatePlus) - GameWorld.DebugLog(" 装备配置饼图: %s,equipDropRatePlus=%s" % (pieRateDropList, equipDropRatePlus), playerID) - else: - dropRateList = pieRateDropList - preRate = 0 - maxRate = dropRateList[-1][0] - GameWorld.DebugLog(" 装备掉落饼图: %s,maxRate=%s" % (dropRateList, maxRate), playerID) - for rateInfo in dropRateList: - rate, equipInfo = rateInfo - curRate = rate - preRate - if not curRate: - break - preRate = rate - if not equipInfo: - continue - classLV, color = equipInfo - totalRate = curRate * pieRateDoCnt # 总概率 - dropCount = totalRate / maxRate # 可掉落件数 - rateEx = totalRate % maxRate # 剩余概率 - if GameWorld.CanHappen(rateEx, maxRate): - dropCount += 1 - GameWorld.DebugLog(" 装备掉率: curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,classLV=%s,color=%s" - % (curRate, totalRate, rateEx, dropCount, classLV, color), playerID) - if not dropCount: - continue - dropEquipInfoList.append([classLV, color, dropCount]) - GameWorld.DebugLog(" 装备掉落结果: killCount=%s,[阶,颜色,件数]=%s" % (killCount, dropEquipInfoList), playerID) - - colorSuitRateDict = ipyDrop.GetEquipColorSuitInfo() # 装备颜色对应套装概率 {颜色:套装概率, ...} - colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...} - dropEquipIDDict = {} - for classLV, color, dropCount in dropEquipInfoList: - if realmNPCIpyData: - classLV = realmNPCIpyData.GetEquipClassLV() - GameWorld.DebugLog(" 脱机掉落对应难度境界装备: classLV=%s" % classLV, playerID) - suitCountDict = {} # {套装:件数, ...} - if color in colorSuitRateDict: - suitRate = colorSuitRateDict[color] - for _ in xrange(dropCount): - isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate) - suitCountDict[isSuit] = suitCountDict.get(isSuit, 0) + 1 - else: - suitCountDict[0] = dropCount - - for isSuit, curDropCount in suitCountDict.items(): - colorSuitKey = (color, isSuit) - if colorSuitKey not in colorSuitPlaceKeyInfoDict: - GameWorld.ErrLog("未配置颜色是否套装对应部位集合key! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit)) - continue - placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey] - placeList = GetEquipPlaceByPlaceKey(placeKey) - if not placeList: - GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) - continue - randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, itemJobList) - if not randEquipIDList: - continue - for _ in xrange(curDropCount): - randItemID = random.choice(randEquipIDList) - dropIDList.append(randItemID) - dropEquipIDDict[randItemID] = [color, placeKey] - GameWorld.DebugLog(" 掉落装备: npcID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,itemJobList=%s,randEquipIDList=%s" - % (npcID, randItemID, classLV, color, isSuit, placeKey, itemJobList, randEquipIDList), playerID) - - # 2. 指定物品ID库 - itemIDDropRateDict = ipyDrop.GetItemIDDropRate() # {物品ID:概率, ...} - itemIDDropMaxCntDict = ipyDrop.GetItemIDMaxDropCount() # {物品ID:最大掉落个数,...} - for itemID, dropRate in itemIDDropRateDict.items(): - - if not dropRate: - continue - - doCnt = itemIDDropMaxCntDict.get(itemID, 1) # 默认1个 - doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd) - doCnt *= killCount - - totalRate = dropRate * doCnt - dropCount = totalRate / Def_NPCMaxDropRate # 可掉落件数 - rateEx = totalRate % Def_NPCMaxDropRate # 剩余概率 - if GameWorld.CanHappen(rateEx, Def_NPCMaxDropRate): - dropCount += 1 - dropIDList += [itemID] * dropCount - GameWorld.DebugLog(" 指定物品掉落: itemID=%s,dropRate=%s,doCnt=%s,totalRate=%s,dropCount=%s" - % (itemID, dropRate, doCnt, totalRate, dropCount), playerID) - - # 检查掉落互斥ID组 - dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1)) - - # 掉落金币 - dropMoneyDoCnt = ipyDrop.GetDropMoneyDoCnt() - dropMoneyRate = ipyDrop.GetDropMoneyRate() - moneyTotalRate = dropMoneyRate * dropMoneyDoCnt * killCount - dropMoneyCnt = moneyTotalRate / ChConfig.Def_NPCMapDropRate - if GameWorld.CanHappen(moneyTotalRate % ChConfig.Def_NPCMapDropRate, ChConfig.Def_NPCMapDropRate): - dropMoneyCnt += 1 - dropMoney = 0 - if dropMoneyCnt: - dropMoney = __GetDropMoneyValue(dropPlayer, ipyDrop, realmNPCIpyData) * dropMoneyCnt - GameWorld.DebugLog(" 金币掉率: dropMoneyRate=%s,moneyTotalRate=%s,dropMoneyCnt=%s,dropMoney=%s" - % (dropMoneyRate, moneyTotalRate, dropMoneyCnt, dropMoney), playerID) - dropIDCountDict = {} - for dropID in dropIDList: - dropIDCountDict[dropID] = dropIDCountDict.get(dropID, 0) + 1 - - # 集字掉落 - dropWordsCountDict = PlayerActCollectWords.OnGetDropWordsItemDict(dropPlayer, npcData, killCount) - for dropID, dropCount in dropWordsCountDict.items(): - dropIDCountDict[dropID] = dropIDCountDict.get(dropID, 0) + dropCount - - # 垃圾分类 - giveGarbageItemList = PlayerActGarbageSorting.AddActGarbageTaskProgress(dropPlayer, ChConfig.Def_GarbageTask_KillNPC, killCount, isTJG=True) - for dropID, dropCount, _ in giveGarbageItemList: - dropIDCountDict[dropID] = dropIDCountDict.get(dropID, 0) + dropCount - - auctionIDList = [] - if ipyDrop.GetAucionItemCanSell(): - for dropID in dropIDCountDict.keys(): - if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropID): - auctionIDList.append(dropID) - - if dropIDCountDict: - GameWorld.DebugLog(" 最终掉落: npcID=%s,killCount=%s,dropIDCountDict=%s,auctionIDList=%s,dropMoney=%s" - % (npcID, killCount, dropIDCountDict, auctionIDList, dropMoney), playerID) - return dropIDCountDict, auctionIDList, dropMoney - -def GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList=[], ipyDrop=None, isSingle=True, isKillCountDrop=True, curGrade=0): - '''获取NPC掉落信息, 击杀及扫荡通用,调用该函数获得掉落信息,然后再看掉落地板上还是直接放入背包 - @param dropPlayer: 用于判断调用相关用的玩家示例,该玩家并不一定是击杀者,只是按一定规则设定的掉落判断依据的玩家 - 如队伍,取等级最大的玩家,该玩家并不一定是击杀者 - @param mapID: 掉落物品所属地图,注意此地图并不一定是当前地图,如扫荡时需使用目标副本地图 - @param npcID: 掉落物品的NPCID - @param ownerPlayerList: 有归属的玩家列表 - @param isSingle: 是否只处理单独玩家掉落逻辑,一般都默认True,目前只有场景杀怪掉落需要考虑摸怪的情况下才为False(外层特殊处理) - @return: dropIDList, auctionIDList, dropMoneyCnt, moneyValue - None-没有掉落 - --------------- - dropIDList - 掉落的物品ID列表, 同个itemID可能在列表中有多个 [itemID, itemID, ...] - auctionIDList - 掉落的拍品物品ID列表, [itemID, itemID, ...] - dropMoneyCnt - 掉落金币位置数 - moneyValue - 每个位置的金币数量 - ''' - if not ipyDrop: - ipyDrop = GetNPCDropIpyData(npcID) - if not ipyDrop: - return - - if not ownerPlayerList: - ownerPlayerList = [dropPlayer] - - playerID = dropPlayer.GetPlayerID() - playerLV = dropPlayer.GetLV() - maxDropLV = ipyDrop.GetMaxDropLV() - - realmNPCIpyData = None - realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1) - realmDifficulty = PlayerControl.GetRealmDifficulty(dropPlayer) - if mapID in realmMapIDList and realmDifficulty: - realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty) - realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV) - if realmNPCIpyData: - maxDropLV = realmNPCIpyData.GetMaxDrapLV() - - if maxDropLV and playerLV > maxDropLV: - GameWorld.DebugLog("超过最大可掉落等级,不掉落物品!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV)) - return - - npcData = GameWorld.GetGameData().FindNPCDataByID(npcID) - if not npcData: - GameWorld.ErrLog("获取NPC掉落配置错误!表不存在该NPCID=%s" % npcID, playerID) - return - - tianxuanState = False # 是否有天玄额外掉落状态 - tianxuanBuff = SkillCommon.FindBuffByID(dropPlayer, ChConfig.Def_SkillID_TianxuanBuff)[0] - curGrade = curGrade if curGrade else GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade) - - dropIDList = [] # 掉落的ID列表 - auctionIDList = [] - dropMoneyCnt, moneyValue = 0, 0 - itemJobList = [dropPlayer.GetJob()] if ipyDrop.GetIsDropJobSelf() else IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # 掉落装备职业列表 - - # 通用掉率相关 - gameFB = GameWorld.GetGameFB() - doCountAdd = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_DropDoCountAdd) - doCountRate = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_DropDoCountRate) # 直接覆盖基值, 无值时取默认值 - if not doCountRate: - doCountRate = ChConfig.Def_MaxRateValue - - # 归属者相关信息 - tagJob = 0 - dropEquipKillCountPub = 0 # 装备附加掉落综合击杀次数,取次数最大的那个,至少第一次 - dropItemIDKillCountPub = 0 # 物品ID附加掉落综合击杀次数,取次数最大的那个,至少第一次 - equipDropRatePlus = 0 # 装备掉落概率提升 - equipDropDoCountPlus = 0 # 装备掉落执行次数提升 - for ownerPlayer in ownerPlayerList: - killCountValue = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) - equipPubKillCount = killCountValue % 100 + 1 - itemIDPubKillCount = killCountValue % 10000 / 100 + 1 - - if dropEquipKillCountPub < equipPubKillCount: - dropEquipKillCountPub = equipPubKillCount - tagJob = ownerPlayer.GetJob() - - if dropItemIDKillCountPub < itemIDPubKillCount: - dropItemIDKillCountPub = itemIDPubKillCount - - equipDropRatePlus = max(equipDropRatePlus, PlayerControl.GetDropEquipPer(ownerPlayer)) - equipDropDoCountPlus = max(equipDropDoCountPlus, PlayerControl.GetDropEquipDoCount(ownerPlayer)) - - dropRatePlusValue = ipyDrop.GetCanDropRatePlus() - if not dropRatePlusValue & pow(2, 0): - equipDropRatePlus = 0 - - if not dropRatePlusValue & pow(2, 1): - equipDropDoCountPlus = 0 - - #GameWorld.DebugLog("NPC掉落: npcID=%s,itemJobList=%s,dropRatePlusValue=%s,equipDropRatePlus=%s,equipDropDoCountPlus=%s,doCountRate=%s,doCountAdd=%s" - # % (npcID, itemJobList, dropRatePlusValue, equipDropRatePlus, equipDropDoCountPlus, doCountRate, doCountAdd), playerID) - - dropEquipInfoList = [] # [(阶,颜色), ...] - # 1. 装备库 - 饼图概率 - pieRateDoCnt = ipyDrop.GetPieRateDoCnt() - if pieRateDoCnt: - pieRateDoCnt = __GetNPCDropDoCountChange(pieRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd) - dropEquipInfoList += __GetNPCPieRateEquipDrop(ipyDrop, pieRateDoCnt, equipDropRatePlus) - - # 2. 装备库 - 独立概率 - indepRateDoCnt = ipyDrop.GetIndepRateDoCnt() - if indepRateDoCnt: - indepRateDoCnt = __GetNPCDropDoCountChange(indepRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd) - dropEquipInfoList += __GetNPCIndepRateEquipDrop(mapID, ipyDrop, indepRateDoCnt, equipDropRatePlus, curGrade) - #GameWorld.DebugLog("阶,颜色 key,dropEquipInfoList=%s" % (dropEquipInfoList)) - - # 天玄丹 - tianxuanEquipRateList = ipyDrop.GetTianxuanEquipRateList() - if tianxuanBuff and tianxuanEquipRateList: - tianxuanState = True - dropInfo = GameWorld.GetResultByRandomList(tianxuanEquipRateList) - if dropInfo: - dropEquipInfoList.append(dropInfo) - - # 3. 第x次击杀, 归属者公共附加掉落,所有归属者都增加击杀次数; - tagClassLV, tagColor, tagIsSuit, tagPlaceKey = 0, 0, 0, 0 - killCountDropEquipPub = ipyDrop.GetKillCountDropEquipPub() # 第x次击杀附加必掉装备 {次数:[阶,颜色,是否套装,部位集合key], ...} - killCountDropItemPub = ipyDrop.GetKillCountDropPub() # 击杀次数必掉(公共){击杀次数:[[物品ID, ...], [随机物品ID, ...]], ...} - maxRecordDropEquipKillCountPub = 0 if not killCountDropEquipPub else max(killCountDropEquipPub) # 需要记录的最大击杀次数, 超过此击杀次数后暂时不累加记录 - maxRecordDropItemIDKillCountPub = 0 if not killCountDropItemPub else max(killCountDropItemPub) - #GameWorld.DebugLog("maxRecordDropEquipKillCountPub=%s,maxRecordDropItemIDKillCountPub=%s" % (maxRecordDropEquipKillCountPub, maxRecordDropItemIDKillCountPub)) - #GameWorld.DebugLog("dropEquipKillCountPub=%s,dropItemIDKillCountPub=%s" % (dropEquipKillCountPub, dropItemIDKillCountPub)) - if isKillCountDrop and killCountDropEquipPub and dropEquipKillCountPub in killCountDropEquipPub: - tagClassLV, tagColor, tagIsSuit, tagPlaceKey = killCountDropEquipPub[dropEquipKillCountPub] - if (tagClassLV, tagColor) not in dropEquipInfoList: - dropEquipInfoList.insert(0, (tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob)) - else: - tagIndex = dropEquipInfoList.index((tagClassLV, tagColor)) - dropEquipInfoList[tagIndex] = (tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob) - GameWorld.DebugLog("第%s次击杀掉落指定目标装备信息: npcID=%s,tagClassLV=%s,tagColor=%s,tagIsSuit=%s,tagPlaceKey=%s,tagJob=%s,dropEquipInfoList=%s" - % (dropEquipKillCountPub, npcID, tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob, dropEquipInfoList), playerID) - elif isKillCountDrop and killCountDropItemPub and dropItemIDKillCountPub in killCountDropItemPub: - killCountItemIDList, killCountRandItemIDList = killCountDropItemPub[dropItemIDKillCountPub] - if killCountItemIDList: - dropIDList += killCountItemIDList - if killCountRandItemIDList: - klllCountRandItemID = random.choice(killCountRandItemIDList) - dropIDList.append(klllCountRandItemID) - GameWorld.DebugLog("第%s次击杀掉落指定目标物品信息: npcID=%s,killCountItemIDList=%s,killCountRandItemIDList=%s,dropIDList=%s" - % (dropItemIDKillCountPub, npcID, killCountItemIDList, killCountRandItemIDList, dropIDList), playerID) - - for ownerPlayer in ownerPlayerList: - # 增加击杀次数 - killCountValue = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) - equipPubKillCount = killCountValue % 100 - itemIDPubKillCount = killCountValue % 10000 / 100 - isUpd = False - if equipPubKillCount < maxRecordDropEquipKillCountPub: - equipPubKillCount += 1 - isUpd = True - if itemIDPubKillCount < maxRecordDropItemIDKillCountPub: - itemIDPubKillCount += 1 - isUpd = True - - if isUpd: - itemIDPriKillCount = killCountValue / 10000 - updKillCountValue = itemIDPriKillCount * 10000 + itemIDPubKillCount * 100 + equipPubKillCount - PlayerControl.NomalDictSetProperty(ownerPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, updKillCountValue) - GameWorld.DebugLog("更新玩家击杀次数值: npcID=%s,killCountValue=%s,updKillCountValue=%s" % (npcID, killCountValue, updKillCountValue), ownerPlayer.GetPlayerID()) - - gradeColorSuitRateDict = {} - fbGradeColorSuitRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 2) # 评级影响颜色套装概率 {npcID:{颜色:[D级影响概率, ..., S级影响概率], ...}, ...} - if npcID in fbGradeColorSuitRateDict: - gradeColorSuitRateDict = fbGradeColorSuitRateDict[npcID] - - equipColorDropLimitDay = IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 1, {}) # 每日个人掉落装备个数限制 {品质:每日掉落个数, ...} - colorDropCntDict = {} # 装备颜色已经掉落数 {颜色:数量, ...} - 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 realmNPCIpyData: - classLV = realmNPCIpyData.GetEquipClassLV() - GameWorld.DebugLog("掉落对应难度境界装备: classLV=%s" % classLV, playerID) - - colorCountToday = 0 - if color in equipColorDropLimitDay: - colorCountMax = equipColorDropLimitDay[color] - colorCountToday = dropPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropColorToday % color) - if colorCountToday >= colorCountMax: - GameWorld.DebugLog("已超过该颜色装备今日最大掉落数,不掉!color=%s,colorCountMax=%s" % (color, colorCountMax), playerID) - continue - - if color in colorMaxDropCntDict: - maxCount = colorMaxDropCntDict[color] - dropCount = colorDropCntDict.get(color, 0) - if dropCount >= maxCount: - GameWorld.DebugLog("已超过该颜色装备最大掉落数,不掉!color=%s,maxCount=%s" % (color, maxCount), playerID) - continue - - if len(dropEquipInfo) == 5: - isSuit, placeKey, tagJob = dropEquipInfo[2:] - jobList = [tagJob] - else: - isSuit = 0 - if color in colorSuitRateDict: - suitRate = colorSuitRateDict[color] - # 评级对套装率的影响 - if color in gradeColorSuitRateDict: - suitRateEffList = gradeColorSuitRateDict[color] - suitRateEff = 10000 if (curGrade <= 0 or curGrade > len(suitRateEffList)) else suitRateEffList[curGrade - 1] - suitRate = int(suitRate * suitRateEff / 10000.0) - isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate) - colorSuitKey = (color, isSuit) - if colorSuitKey not in colorSuitPlaceKeyInfoDict: - GameWorld.ErrLog("未配置颜色是否套装对应部位集合key! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit)) - continue - placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey] - # 掉落优选部位处理 - if color == optColor and isSuit == optIsSuit and optPlace == None: - allEquipPlaceList = GetAllEquipPlaceByPlaceKey(placeKey) - #GameWorld.DebugLog(" 所有可优选部位: %s" % allEquipPlaceList) - if allEquipPlaceList: - optPlace = __GetOptimizationEquipPlace(dropPlayer, classLV, optColor, optIsSuit, allEquipPlaceList) - jobList = itemJobList - if optPlace > 0: - GameWorld.DebugLog(" 最终优选部位: %s" % optPlace) - placeList = [optPlace] - jobList = [dropPlayer.GetJob()] - optPlace = 0 # 只有一次性的,置为0 - else: - placeList = GetEquipPlaceByPlaceKey(placeKey) - if not placeList: - GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) - continue - randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, jobList) - if not randEquipIDList: - continue - if color in equipColorDropLimitDay: - colorCountToday += 1 - PlayerControl.NomalDictSetProperty(dropPlayer, ChConfig.Def_PDict_DropColorToday % color, colorCountToday) - if color in colorMaxDropCntDict: - colorDropCntDict[color] = dropCount + 1 - if isSuit and len(jobList) > 1: - randItemID = __GetRandDropSuitEquipID(dropPlayer, randEquipIDList) - else: - randItemID = random.choice(randEquipIDList) - dropIDList.append(randItemID) - GameWorld.DebugLog("掉落装备: npcID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,jobList=%s,randEquipIDList=%s" - % (npcID, randItemID, classLV, color, isSuit, placeKey, jobList, randEquipIDList), playerID) - if colorCountToday: - GameWorld.DebugLog(" 更新掉落特殊品质装备今日次数: color=%s,colorCountToday=%s" % (color, colorCountToday), playerID) - - # 4. 指定物品ID库 - dropIDList += __GetAppointDropItemIDList(dropPlayer, npcID, ipyDrop, doCountRate, doCountAdd, tianxuanBuff) - if tianxuanBuff and (ipyDrop.GetTianxuanItemKeyRate() or ipyDrop.GetTianxuanItemIDRate()): - tianxuanState = True - - # 5. 私有掉落 - if isSingle: - # 击杀次数掉落 - killCountDropInfo = ipyDrop.GetKillCountDropPri() - if killCountDropInfo: - needKillCount, killDropItemList = killCountDropInfo[:2] - killCountDropIDList = GetKillCountDropItemList(dropPlayer, npcID, needKillCount, killDropItemList) - for kDropItemID in killCountDropIDList: - dropIDList.append(kDropItemID) # 单独玩家掉落处理的,直接加到掉落列表里,不考虑是否放入背包或掉落的情况,由使用的功能自行处理 - #GameWorld.DebugLog("击杀次数掉落: kDropItemID=%s,needKillCount=%s" % (kDropItemID, needKillCount)) - - # 固定产出,所有掉落归属者每人一份,默认绑定,不区分职业 - fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3) - if npcID in fbGradePriItemIDDropDict: - gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID] - priDropInfoList = gradePriItemIDDropDict.get(curGrade, []) - priDropIDList = [] - for priItemID, priItemCount in priDropInfoList: - priDropIDList += [priItemID] * priItemCount - else: - priDropIDList = ipyDrop.GetPriItemIDDrop() - for priDropID in priDropIDList: - dropIDList.append(priDropID) - #GameWorld.DebugLog("私有物品掉落: priDropID=%s" % priDropID) - - # 6. 地图评级额外掉落 - fbGradeDropItemExDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate2", 2) # 地图评级额外物品掉落 {"mapID":{"评级":[[物品ID,个数], ...], ...}} - if curGrade and str(mapID) in fbGradeDropItemExDict: - gradeItemExDict = fbGradeDropItemExDict[str(mapID)] - gradeItemExList = gradeItemExDict.get(str(curGrade), []) - #GameWorld.DebugLog("评级额外掉落物品: curGrade=%s,gradeItemExList=%s" % (curGrade, gradeItemExList)) - for gItemExID, gItemExCount in gradeItemExList: - dropIDList += [gItemExID] * gItemExCount - - # 7.相关活动掉落 - feastWishDropIDList = PlayerFeastWish.GetFeastWishDropItemIDList(dropPlayer, npcData) - if feastWishDropIDList: - dropIDList.extend(feastWishDropIDList) - - #boss凭证 - killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1) - if mapID == ChConfig.Def_FBMapID_PersonalBoss: - limitIndex = ChConfig.Def_FBMapID_PersonalBoss - else: - limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID) - if limitIndex != None: - bossTrialDrop = PlayerActBossTrial.GetBossTrialDropItemIDList(dropPlayer, limitIndex) - if bossTrialDrop: - bossTrialItemID, bossTrialItemCount = bossTrialDrop - GameWorld.DebugLog("掉落boss凭证: bossTrialItemID=%s, bossTrialItemCount=%s" % (bossTrialItemID, bossTrialItemCount)) - dropIDList += [bossTrialItemID] * bossTrialItemCount - - # 检查掉落互斥ID组 - dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1)) - - # 掉落金币 - dropMoneyDoCnt = ipyDrop.GetDropMoneyDoCnt() - dropMoneyRate = ipyDrop.GetDropMoneyRate() - if dropMoneyRate == ChConfig.Def_NPCMapDropRate: - dropMoneyCnt = dropMoneyDoCnt - else: - dropMoneyCnt = 0 - for _ in xrange(dropMoneyDoCnt): - if GameWorld.CanHappen(dropMoneyRate, ChConfig.Def_NPCMapDropRate): - dropMoneyCnt += 1 - - #GameWorld.DebugLog("NPCID=%s,金币掉率: %s, 执行次数=%s, 掉落金币数=%s" % (npcID, dropMoneyRate, dropMoneyDoCnt, dropMoneyCnt)) - if dropMoneyCnt: - moneyValue = __GetDropMoneyValue(dropPlayer, ipyDrop, realmNPCIpyData) - #GameWorld.DebugLog(" 掉落金币value=%s" % (moneyValue)) - - if dropIDList: - if ipyDrop.GetAucionItemCanSell(): - for dropID in dropIDList: - if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropID): - auctionIDList.append(dropID) - GameWorld.DebugLog("最终掉落物品: npcID=%s,dropIDList=%s" % (npcID, dropIDList), playerID) - GameWorld.DebugLog(" auctionIDList=%s" % (auctionIDList), playerID) - elif ChConfig.IsGameBoss(npcData): - GameWorld.ErrLog("Boss没有掉落物品,NPCID=%s" % (npcID), dropPlayer.GetPlayerID()) - - if tianxuanBuff and tianxuanState: - GameWorld.DebugLog(" 去除天玄丹buff: Layer=%s" % tianxuanBuff.GetLayer(), playerID) - BuffSkill.SetBuffLayer(dropPlayer, tianxuanBuff, max(tianxuanBuff.GetLayer() - 1, 0), True, ChConfig.Def_SkillID_TianxuanBuff, isSync=True) - - return dropIDList, auctionIDList, dropMoneyCnt, moneyValue - -def __GetRandDropSuitEquipID(curPlayer, randEquipIDList): - ## 获取随机掉落的套装ID,为了玩家掉落体验, 当非本职业套装时可至多重新随机X次 - randItemID = 0 - suitRandCountEx = IpyGameDataPY.GetFuncCfg("EquipSuitDrop", 1) + 1 - for _ in xrange(suitRandCountEx): - randItemID = random.choice(randEquipIDList) - itemData = GameWorld.GetGameData().GetItemByTypeID(randItemID) - if not itemData: - continue - if ItemCommon.CheckJob(curPlayer, itemData): - break - return randItemID - -def GetAllEquipPlaceByPlaceKey(placeKey): - placeKeyRateListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 2, {}) # {集合数字key1:[[概率1,部位1],...],...} - if placeKey in placeKeyRateListDict: - return [rateInfo[1] for rateInfo in placeKeyRateListDict[placeKey]] - placeKeyListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 1, {}) # {集合数字key1:[部位1,部位2,...],...} - if placeKey in placeKeyListDict: - return placeKeyListDict[placeKey] - return [] - -def GetEquipPlaceByPlaceKey(placeKey): - ## 获取装备位集合对应的部位信息,集合ID重复时,优先饼图 - placeList = [] - placeKeyRateListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 2, {}) # {集合数字key1:[[概率1,部位1],...],...} - if placeKey in placeKeyRateListDict: - placeRateList = placeKeyRateListDict[placeKey] - place = GameWorld.GetResultByRandomList(placeRateList) - if place: - placeList = [place] - #GameWorld.DebugLog(" 掉落部位概率集合: placeKey=%s,placeRateList=%s,place=%s,placeList=%s" % (placeKey, placeRateList, place, placeList)) - - if not placeList: - placeKeyListDict = IpyGameDataPY.GetFuncEvalCfg("EquipDropPartSets", 1, {}) # {集合数字key1:[部位1,部位2,...],...} - if placeKey in placeKeyListDict: - placeList = placeKeyListDict[placeKey] - #GameWorld.DebugLog(" 掉落部位均衡集合: placeKey=%s,placeList=%s" % (placeKey, placeList)) - - return placeList - -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): - ## 获取掉落执行次数变更结果,可能增加 或 减少 - if doCountRate != ChConfig.Def_MaxRateValue: - doCount = max(1, int(doCount * doCountRate / 10000.0)) - if doCountAdd: - doCount = max(1, doCount + doCountAdd) # 支持正负,保底1,负值待扩展 - return doCount - -def __RemoveMutexDropID(dropIDList, mutexDropInfo): - ## 移除互斥的掉落物品,每组互斥的ID最多只能掉落一个,列表顺序为掉落优先级 [[互斥组1ID, ID, ...], [互斥组2ID, ID, ...], ...] - for mutexDropList in mutexDropInfo: - isMutex = False - for mutexID in mutexDropList: - if mutexID not in dropIDList: - continue - if not isMutex: - isMutex = True - curDropIDCnt = dropIDList.count(mutexID) - # 如果超过1个,则移除多余的,只保留一个 - if curDropIDCnt > 1: - for _ in xrange(curDropIDCnt - 1): - dropIDList.remove(mutexID) - continue - - # 已经是互斥的了,该ID不可掉落,全部移除 - while mutexID in dropIDList: - dropIDList.remove(mutexID) - - return dropIDList - -def __GetAppointDropItemIDList(curPlayer, npcID, ipyDrop, doCountRate, doCountAdd, tianxuanBuff): - ## 指定物品ID掉落 - - dropItemIDList = [] - - itemDropLimitDayInfo = IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 2, {}) # 每日个人掉落物品个数限制 {物品ID:每日掉落上限, ...} - # 1. 职业物品ID集合 - job = curPlayer.GetJob() - JobItemDropSets = IpyGameDataPY.GetFuncCfg("JobItemDropSets", 1) # {物品ID集合key:[职业顺序物品ID列表], ...} - itemDropSets = IpyGameDataPY.GetFuncCfg("JobItemDropSets", 2) # {物品ID集合key:[随机物品ID列表], ...} - itemDropRateSets = IpyGameDataPY.GetFuncCfg("JobItemDropSets", 3) # {物品ID集合key:[随机物品ID饼图列表], ...} - ItemKeyMaxDropCountDict = ipyDrop.GetItemKeyMaxDropCount() # {物品ID集合key:随机次数,...} - - # 1.1 只掉本职业的 - ItemKeyDropRateJobDict = ipyDrop.GetItemKeyDropRateJob() # {物品ID集合key:概率, ...}, 只掉本职业的,优先级高 - if ItemKeyDropRateJobDict: - for jobItemKey, dropRate in ItemKeyDropRateJobDict.items(): - if jobItemKey not in JobItemDropSets: - continue - jobItemList = JobItemDropSets[jobItemKey] - if len(jobItemList) < job: - GameWorld.ErrLog("职业物品集合key没有配置对应职业ID: npcID=%s,jobItemKey=%s,job=%s" % (npcID, jobItemKey, job)) - continue - mustDropCount = dropRate / Def_NPCMaxDropRate - dropRate = dropRate % Def_NPCMaxDropRate # 基础概率 - canDropCount = mustDropCount - doCnt = ItemKeyMaxDropCountDict.get(jobItemKey, 1) # 默认1个 - doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd) - for _ in xrange(doCnt): - if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate): - continue - canDropCount += 1 - - jobItemID = jobItemList[job - 1] - for _ in xrange(canDropCount): - dropItemIDList.append(jobItemID) - #GameWorld.DebugLog("掉落自身职业指定物品ID: jobItemKey=%s,jobItemID=%s" % (jobItemKey, jobItemID)) - - # 1.2 随机掉落一个 - ItemKeyDropRateDict = ipyDrop.GetItemKeyDropRate() # {物品ID集合key:概率, ...}, 随机掉一个,优先级低 - tianxuanItemKeyRateDict = ipyDrop.GetTianxuanItemKeyRate() # 天玄丹指定ID集合Key概率{物品ID集合key:概率, ...} - if tianxuanBuff and tianxuanItemKeyRateDict: - ItemKeyDropRateDict = copy.deepcopy(ItemKeyDropRateDict) - ItemKeyDropRateDict.update(tianxuanItemKeyRateDict) - - if ItemKeyDropRateDict: - GameWorld.DebugLog("ItemKeyDropRateDict:%s" % ItemKeyDropRateDict) - for itemKey, dropRate in ItemKeyDropRateDict.items(): - # 在只掉本职业里的不处理 - if itemKey in ItemKeyDropRateJobDict: - continue - mustDropCount = dropRate / Def_NPCMaxDropRate - dropRate = dropRate % Def_NPCMaxDropRate # 基础概率 - canDropCount = mustDropCount - doCnt = ItemKeyMaxDropCountDict.get(itemKey, 1) # 默认1个 - doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd) - for _ in xrange(doCnt): - if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate): - continue - canDropCount += 1 - - for _ in xrange(canDropCount): - if itemKey in itemDropRateSets: - randItemRateList = itemDropRateSets[itemKey] - randItemID = GameWorld.GetResultByRandomList(randItemRateList) - #GameWorld.DebugLog("掉落饼图物品ID: itemKey=%s,randItemRateList=%s,randItemID=%s" % (itemKey, randItemRateList, randItemID)) - elif itemKey in itemDropSets: - randItemList = itemDropSets[itemKey] - randItemID = random.choice(randItemList) - #GameWorld.DebugLog("掉落随机物品ID: itemKey=%s,randItemList=%s,randItemID=%s" % (itemKey, randItemList, randItemID)) - else: - continue - if not randItemID: - continue - if __dropIDCountLimitToday(curPlayer, randItemID, itemDropLimitDayInfo): - continue - dropItemIDList.append(randItemID) - #GameWorld.DebugLog("掉落随机指定物品ID: itemKey=%s,randItemID=%s" % (itemKey, randItemID)) - - # 2. 指定掉落ID处理, 受全局设定影响 - itemIDDropRateDict = ipyDrop.GetItemIDDropRate() # {物品ID:概率, ...} - itemIDDropMaxCntDict = ipyDrop.GetItemIDMaxDropCount() # {物品ID:最大掉落个数,...} - tianxuanItemIDRate = ipyDrop.GetTianxuanItemIDRate() # 天玄丹指定ID概率 {物品ID:概率, ...} - if tianxuanBuff and tianxuanItemIDRate: - itemIDDropRateDict = copy.deepcopy(itemIDDropRateDict) - itemIDDropRateDict.update(tianxuanItemIDRate) - - # 全局材料掉落控制 - globalDropCDDict = IpyGameDataPY.GetFuncCfg("GlobalDropCD", 1) # {物品ID:分钟, ...} - globalDropRateDict = IpyGameDataPY.GetFuncCfg("NPCGlobalDropRate", 1) # {物品ID:[[npcID列表], "概率公式"], ...} - gw = GameWorld.GetGameWorld() - - if itemIDDropRateDict: - GameWorld.DebugLog("itemIDDropRateDict=%s" % itemIDDropRateDict) - - for itemID, dropRate in itemIDDropRateDict.items(): - - if not dropRate: - continue - - # 根据击杀次数来的另外计算,不在此判断 - if itemID in globalDropRateDict: - continue - - doCnt = itemIDDropMaxCntDict.get(itemID, 1) # 默认1个 - - # 判断是否全局掉落CD中 - if itemID in globalDropCDDict: - curTime = int(time.time()) - lastDropTime = gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_LastDropTime % itemID) - cdTime = globalDropCDDict[itemID] * 60 - remainTime = cdTime - (curTime - lastDropTime) - if remainTime > 0: - GameWorld.DebugLog("该物品全局掉落CD中,不掉落!itemID=%s,cdTime=%s,curTime=%s,lastDrop=%s,remainTime=%s" - % (itemID, cdTime, curTime, lastDropTime, remainTime)) - continue - else: - doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd) - - #GameWorld.DebugLog(" 指定判断: itemID=%s, dropRate=%s, doCnt=%s" % (itemID, dropRate, doCnt)) - for _ in xrange(doCnt): - if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate): - continue - - if __dropIDCountLimitToday(curPlayer, itemID, itemDropLimitDayInfo): - continue - - dropItemIDList.append(itemID) - if itemID in globalDropCDDict: - # 通知GameServer记录 - msgInfo = str([itemID, curTime]) - GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalDropCD", msgInfo, len(msgInfo)) - DataRecordPack.DR_GlobalDropCD(curPlayer, npcID, itemID) - break - - # 3. 指定击杀次数全局掉率 - for itemID, dropInfo in globalDropRateDict.items(): - npcIDList, rateFormat = dropInfo - if npcID not in npcIDList: - continue - - killedCnt = gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DropNPCKilledCnt % itemID) - dropRate = eval(FormulaControl.GetCompileFormula("KilledCntDropRate_%s" % itemID, rateFormat)) - isDrop = GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate) - if isDrop: - dropItemIDList.append(itemID) - DataRecordPack.DR_GlobalDropRate(curPlayer, npcID, itemID, killedCnt, dropRate) - - # 通知GameServer记录 - updKilledCnt = 0 if isDrop else (killedCnt + 1) - msgInfo = str([itemID, updKilledCnt]) - GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalDropRate", msgInfo, len(msgInfo)) - - # 4. 指定全服击杀次数必掉,算额外掉落 - globalKillDropDict = IpyGameDataPY.GetFuncEvalCfg("GlobalDropCD", 2) # {NPCID:{击杀次数:[是否本职业, {物品ID:个数, ...}, [[随机物品ID,个数], ...]]}, ...} - if npcID in globalKillDropDict: - killCountDropDict = globalKillDropDict[npcID] - updNPCKilledCount = min(gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_NPCKilledCount % npcID) + 1, ShareDefine.Def_UpperLimit_DWord) - GameWorld.Log("更新全服击杀次数:npcID=%s, %s" % (npcID, updNPCKilledCount)) - # 通知GameServer记录 - msgInfo = str([npcID, updNPCKilledCount]) - GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalKillCount", msgInfo, len(msgInfo)) - if updNPCKilledCount in killCountDropDict: - isJobLimit, itemIDCountDict, randItemIDCountList = killCountDropDict[updNPCKilledCount] - for itemID, itemCount in itemIDCountDict.items(): - if isJobLimit: - itemData = GameWorld.GetGameData().GetItemByTypeID(itemID) - if not itemData: - continue - itemJob = itemData.GetJobLimit() - if itemJob and itemJob != curPlayer.GetJob(): - # 非本职业可用,不掉落 - GameWorld.DebugLog("全服击杀次数必掉,非本职业可用,不掉落! itemID=%s" % itemID) - continue - dropItemIDList += [itemID] * itemCount - GameWorld.Log("全服击杀次数必掉物品: itemID=%s,itemCount=%s" % (itemID, itemCount)) - if randItemIDCountList: - if isJobLimit: - randJobItemList = [] - for rItemID, rItemCount in randItemIDCountList: - itemData = GameWorld.GetGameData().GetItemByTypeID(rItemID) - if not itemData: - continue - itemJob = itemData.GetJobLimit() - if itemJob and itemJob != curPlayer.GetJob(): - # 非本职业可用,不掉落 - GameWorld.DebugLog("全服击杀次数必掉随机,非本职业可用,不掉落! rItemID=%s" % rItemID) - continue - randJobItemList.append([rItemID, rItemCount]) - randItemID, randItemCount = random.choice(randJobItemList) - else: - randItemID, randItemCount = random.choice(randItemIDCountList) - dropItemIDList += [randItemID] * randItemCount - GameWorld.Log("全服击杀次数必掉随机物品: randItemID=%s,randItemCount=%s" % (randItemID, randItemCount)) - - return dropItemIDList - -def __dropIDCountLimitToday(curPlayer, itemID, itemDropLimitDayInfo): - ## 处理今日掉落物品ID个数限制 - # @return: 是否限制 - if itemID not in itemDropLimitDayInfo: - return False - dropCountTodayMax = itemDropLimitDayInfo[itemID] - if not dropCountTodayMax: - return False - dropCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropCountToday % itemID) - if dropCountToday >= dropCountTodayMax: - GameWorld.DebugLog(" 物品ID今日掉落次数已达上限: itemID=%s,dropCountToday=%s" % (itemID, dropCountToday), curPlayer.GetPlayerID()) - return True - dropCountToday += 1 - PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DropCountToday % itemID, dropCountToday) - GameWorld.DebugLog(" 更新物品ID今日掉落次数: itemID=%s,dropCountToday=%s" % (itemID, dropCountToday), curPlayer.GetPlayerID()) - return False - -def __GetEquipIDList(findID, classLV, color, isSuit, placeList, itemJobList, findType="NPC"): +def __GetEquipIDList(findID, classLV=None, color=None, isSuit=None, placeList=None, itemJobList=None, findType="NPC"): #存一个满足要求的所有的物品的列表 然后从当中随机选一个 #注: 阶、颜色、套装ID、职业、部位,这5个条件可确认唯一一件装备 @@ -1633,9 +220,9 @@ if not itemData.GetCanNPCDrop(): continue - if ItemCommon.GetItemClassLV(itemData) != classLV: + if classLV != None and ItemCommon.GetItemClassLV(itemData) != classLV: continue - if itemData.GetItemColor() != color: + if color != None and itemData.GetItemColor() != color: continue suiteID = itemData.GetSuiteID() itemJob = itemData.GetJobLimit() @@ -1657,7 +244,7 @@ if itemJob and itemJobList and itemJob not in itemJobList: continue curIsSuit = suiteID > 0 - if curIsSuit != isSuit: + if isSuit != None and curIsSuit != isSuit: continue itemIDList.append(itemID) @@ -1666,128 +253,6 @@ % (findType, findID, classLV, color, isSuit, placeList, itemJobList)) return itemIDList -def __GetNPCPieRateEquipDrop(ipyDrop, doCnt, equipDropPlus): - ## 获取NPC饼图掉率装备掉落信息 - dropEquipInfoList = [] - pieRateDropList = ipyDrop.GetPieRateDrop() # 饼图概率掉落信息 [(概率,0),(概率,(阶,颜色)),...] - dropRateList = pieRateDropList if not equipDropPlus else GameWorld.GetPlusPieList(pieRateDropList, equipDropPlus) - #GameWorld.DebugLog("掉落饼图概率: %s, equipDropPlus=%s" % (pieRateDropList, equipDropPlus)) - #GameWorld.DebugLog("实际饼图概率: %s" % (dropRateList)) - for _ in xrange(doCnt): - dropInfo = GameWorld.GetResultByRandomList(dropRateList) - if dropInfo: - dropEquipInfoList.append(dropInfo) - #GameWorld.DebugLog("饼图装备掉落结果: doCnt=%s, %s" % (doCnt, dropEquipInfoList)) - return dropEquipInfoList - -def __GetNPCIndepRateEquipDrop(mapID, ipyDrop, doCnt, equipDropPlus, curGrade=0): - ## 获取NPC独立掉率装备掉落信息 - npcID = ipyDrop.GetNPCID() - indepRateDict = ipyDrop.GetIndepRateDrop() # 独立概率掉落信息 {(阶,颜色):概率,...} - #GameWorld.DebugLog("独立概率装备掉落处理: indepRateDict=%s,equipDropPlus=%s" % (indepRateDict, equipDropPlus)) - gradeColorRateDict = {} - fbGradeColorRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 1) #{npcID:{颜色:[D级影响概率, ..., S级影响概率], ...}, ...} - if npcID in fbGradeColorRateDict: - gradeColorRateDict = fbGradeColorRateDict[npcID] - - orangeEquipPer = 0 - fbGradeOrangeEquipPerDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate2", 1) # 地图评级影响橙装概率百分率 {"mapID":[D级影响概率, ..., S级影响概率], ..} - if str(mapID) in fbGradeOrangeEquipPerDict and curGrade: - orangeEquipPerList = fbGradeOrangeEquipPerDict[str(mapID)] - orangeEquipPer = 0 if (curGrade <= 0 or curGrade > len(orangeEquipPerList)) else orangeEquipPerList[curGrade - 1] - - #colorDropCntDict = {} # 装备颜色已经掉落数 {颜色:数量, ...} - dropEquipInfoList = [] - for _ in xrange(doCnt): - for dropInfo, rate in indepRateDict.iteritems(): - dropRate = rate - color = dropInfo[1] - if color in gradeColorRateDict: - colorRateList = gradeColorRateDict[color] - colorRate = 10000 if (curGrade <= 0 or curGrade > len(colorRateList)) else colorRateList[curGrade - 1] - dropRate = int(dropRate * colorRate / 10000.0) - #GameWorld.DebugLog(" 评级影响颜色概率: curGrade=%s,colorRate=%s,dropRate=%s" % (curGrade, colorRate, dropRate)) - - if color == ChConfig.Def_Quality_Orange and orangeEquipPer: - dropRate = int(dropRate * orangeEquipPer / 100.0) - #GameWorld.DebugLog("评级橙装掉率加成: orangeEquipPer=%s,dropRate=%s" % (orangeEquipPer, dropRate)) - - dropRate = dropRate if not equipDropPlus else (dropRate + int(dropRate * equipDropPlus / 10000.0)) - mustDropCount = dropRate / Def_NPCMaxDropRate - dropRate = dropRate % Def_NPCMaxDropRate # 基础概率 - #GameWorld.DebugLog(" dropInfo=%s,rate=%s,mustDropCount=%s,dropRate=%s" % (dropInfo, rate, mustDropCount, dropRate)) - curDropCount = mustDropCount - if GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate): - curDropCount += 1 - if not curDropCount: - continue - - for _ in xrange(curDropCount): - dropEquipInfoList.append(dropInfo) - #GameWorld.DebugLog("独立概率装备掉落结果: doCnt=%s, %s" % (doCnt, dropEquipInfoList)) - return dropEquipInfoList - -def __GetDropMoneyValue(curPlayer, ipyDrop, realmNPCIpyData): - baseMoney = FBLogic.OnGetNPCDropMoney(curPlayer) - if baseMoney <= 0: - # 获得掉落数量 - if realmNPCIpyData: - baseMoney = random.randint(realmNPCIpyData.GetDropMoneyMin(), realmNPCIpyData.GetDropMoneyMax()) - else: - baseMoney = random.randint(ipyDrop.GetDropMoneyMin(), ipyDrop.GetDropMoneyMax()) - - if baseMoney <= 0: - return 0 - - moneyValue = baseMoney - # 玩家金钱掉落加成 - if curPlayer != None: - - addRateEx = 0 - - addRate = float(curPlayer.GetGoldFoundRate() + addRateEx) / ShareDefine.Def_MaxRateValue - moneyValue = int(moneyValue + moneyValue * addRate) - #特殊地图杀怪金币外层加成 - outerMoneyRate = FBLogic.OnGetOuterMoneyRate(curPlayer) - if outerMoneyRate > 0: - moneyValue = int(moneyValue * outerMoneyRate / float(ShareDefine.Def_MaxRateValue)) - - if moneyValue >= 65535: - moneyValue = random.randint(65000, 65530) - return moneyValue - -def GetKillCountDropItemList(curPlayer, npcID, needKillCount, killDropItemList): - ## 获取击杀次数额外掉落 - killCountValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) - killCountPri = killCountValue / 10000 - if killCountPri >= needKillCount: - #GameWorld.DebugLog("杀掉次数已经掉落过! npcID=%s,killCountValue=%s,dropRecord=%s" % (npcID, killCountValue, dropRecord), curPlayer.GetPlayerID()) - return [] - - killCountPri += 1 - updRecordValue = killCountPri * 10000 + killCountValue % 10000 - - jobDropInfo = [] - if killCountPri >= needKillCount: - isJobLimit = 1 - #[itemID,...] - for dropItemID in killDropItemList: - itemData = GameWorld.GetGameData().GetItemByTypeID(dropItemID) - if not itemData: - GameWorld.ErrLog("掉落物品ID不存在, dropItemID=%s" % dropItemID) - continue - itemJob = itemData.GetJobLimit() - if isJobLimit and itemJob and itemJob != curPlayer.GetJob(): - # 非本职业可用,不掉落 - #GameWorld.DebugLog("非本职业可用,不掉落! dropItemID=%s" % dropItemID) - continue - jobDropInfo.append(dropItemID) - GameWorld.DebugLog("击杀次数必掉落! npcID=%s,needKillCount=%s,jobDropInfo=%s,killDropItemList=%s,updRecordValue=%s" - % (npcID, needKillCount, jobDropInfo, killDropItemList, updRecordValue), curPlayer.GetPlayerID()) - - PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, updRecordValue) - GameWorld.DebugLog("更新击杀次数比掉落值: killCountValue=%s,killCountPri=%s,updRecordValue=%s" % (killCountValue, killCountPri, updRecordValue), curPlayer.GetPlayerID()) - return jobDropInfo ###################################################################### #--------------------------------------------------------------------- #移动相关 @@ -2154,7 +619,7 @@ #=============================================================================== def GetDefaultMaxAngryNPCIDList(): - return GameLogic_FamilyInvade.GetDefaultMaxAngryNPCIDList() + return [] #--------------------------------------------------------------------- ##NPC进入战斗状态 @@ -2443,7 +908,9 @@ # @return def SetDeadEx(curNPC): summon_List = [] + objID = curNPC.GetID() npcid = curNPC.GetNPCID() + GameWorld.DebugLog("SetDeadEx objID=%s,npcID=%s" % (objID, npcid)) #将涉及到C++中列表删除的功能,统一改成 -> 复制Py列表后,然后进行删除逻辑 for index in range(curNPC.GetSummonCount()): curSummonNPC = curNPC.GetSummonNPCAt(index) @@ -2473,9 +940,7 @@ #GameWorld.GetGameWorld().SetGameWorldDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick()) #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典 GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick()) - - if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: - FamilyRobBoss.ClearFamilyOwnerBossHurt(curNPC) + ChNPC.OnNPCSetDead(curNPC) if npcid == IpyGameDataPY.GetFuncCfg("CrossYaomoBoss", 1): @@ -2483,10 +948,6 @@ # 清除队伍成员伤血列表 AttackCommon.ClearTeamPlayerHurtValue(curNPC) - # 清除自定义伤血列表 - #BossHurtMng.ClearHurtValueList(curNPC) - NPCHurtManager.DeletePlayerHurtList(curNPC) - NPCHurtMgr.DeletePlayerHurtList(curNPC) if curNPC.GetType() == ChConfig.ntRobot: lineID = GameWorld.GetGameWorld().GetLineID() lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {}) @@ -2504,9 +965,19 @@ break # C++设置npc死亡 + notifyClient = True + #tfMgr = TurnAttack.GetTurnFightMgr() + #turnFight = tfMgr.getNPCTurnFight(objID) + #if turnFight: + # notifyClient = False # 回合制战斗的由py自己通知 + # # //04 07 NPC消失#tagNPCDisappear 此处通知消失,与回合制死亡区分 + # clientPack = ChNetSendPack.tagNPCDisappear() + # clientPack.NPCID = [objID] + # clientPack.Count = len(clientPack.NPCID) + # turnFight.addBatPack(clientPack) curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason), curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerType), - curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID)) + curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID), notifyClient) return def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]): @@ -2557,14 +1028,12 @@ key = ChConfig.Def_PDict_Boss_KillCnt % limitIndex newCnt = curPlayer.NomalDictGetProperty(key, 0) + 1 PlayerControl.NomalDictSetProperty(curPlayer, key, newCnt) - BossHurtMng.NotifyAttackBossCnt(curPlayer, limitIndex) GameWorld.DebugLog("更新击杀Boss次数: index=%s, todayCnt=%s, totalCnt=%s" % (limitIndex, newCnt, totalCnt), curPlayer.GetPlayerID()) dataDict = {"objID":npcID, "bossID":npcID, "touchCnt":newCnt, "totalCnt":totalCnt, "AccID":curPlayer.GetAccID(), "PlayerID":curPlayer.GetPlayerID()} DataRecordPack.SendEventPack("AddKillBossCnt", dataDict, curPlayer) PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FeastRedPack_KillBoss, 1, [limitIndex]) - EventShell.EventRespons_KillBoss(curPlayer, limitIndex) PlayerState.SetBossStateExit(curPlayer) if isCrossServer: @@ -2577,8 +1046,6 @@ # 每日活动 PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS) PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_WorldBOSS, 1) - PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1) - PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1) PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_WorldBOSS, 1) PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_WorldBoss, 1) PlayerActLogin.AddLoginAwardActionCnt(curPlayer, ChConfig.Def_LoginAct_WorldBOSS, 1) @@ -2594,8 +1061,6 @@ # 每日活动 PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome) PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1) - PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1) - PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1) PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_BOSSHome, 1) PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_BossHome, 1) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_BossHome, 1) @@ -2613,11 +1078,7 @@ PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillCrossDemonLandBoss, 1) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_CrossDemonLandBoss, 1) if mapID in [ChConfig.Def_FBMapID_CrossPenglai, ChConfig.Def_FBMapID_CrossDemonLand]: - PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_CrossBoss) PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_CrossBoss, 1) - - if npcData.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark: - PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_KillBoss) # 个人首杀记录 ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", npcID) @@ -2922,10 +1383,6 @@ GameWorld.Log("curNPC = %s 查找对象, 获得对象实例失败" % (curNPC.GetNPCID())) return False - #守卫攻击镖车,仇恨特殊处理 - if self.__GuaedAttackTruck(seeObjDetail , tick): - return True - #小怪不可行进通道就当作看不见 if not AttackCommon.CanAttackByPath(curNPC, seeObjDetail): #GameWorld.DebugLog("有障碍 看见也不加仇恨") @@ -2945,37 +1402,6 @@ #GameWorld.Log("%s添加仇恨%s成功"%(curNPC.GetName(), seeObjDetail.GetName())) return True - #--------------------------------------------------------------------- - ##守卫攻击镖车,特殊处理 - # @param self 类实例 - # @param seeObj 视野中的对象 - # @param tick 时间戳 - # @return 返回值真, 可以添加这个对象 - # @remarks 守卫攻击镖车,特殊处理 - def __GuaedAttackTruck(self, seeObj, tick) : - curNPC = self.__Instance - - if curNPC.GetType() != IPY_GameWorld.ntGuard: - return - - if seeObj.GetGameObjType() != IPY_GameWorld.gotNPC or \ - seeObj.GetGameNPCObjType() != IPY_GameWorld.gnotTruck : - return - - #如果是远程的守卫,不考虑攻击距离,追击 - #不可移动的固定守卫,超出攻击距离,返回 - if curNPC.GetSpeed() == 0 and not BaseAttack.GetCanAttack(curNPC, seeObj, None, tick): - return - - relation = BaseAttack.GetTagRelation(curNPC, seeObj, None, tick)[0] - - if relation != ChConfig.Type_Relation_Enemy : - return - - return True - - - def GetIsBossView(self): # 主动视野情况,GetIsBoss 0 1 4 为普通NPC视野(有视野范围配置,但去除视野刷新),其他为BOSS类视野有刷新 curNPC = self.__Instance @@ -3118,8 +1544,8 @@ addAngry += useSkill.GetSkillAngry() # 玩家攻击增加额外仇恨 - if objDetel.GetGameObjType() == IPY_GameWorld.gotPlayer: - addAngry += PlayerControl.GetAddAngry(objDetel) + #if objDetel.GetGameObjType() == IPY_GameWorld.gotPlayer: + # addAngry += PlayerControl.GetAddAngry(objDetel) self.AddObjToAngryList(objDetel, addAngry) return @@ -3480,8 +1906,6 @@ #清除所有身上buff self.ClearAllBuff(isClearAuraBuff) curNPC = self.__Instance - NPCHurtManager.ClearPlayerHurtList(curNPC) - NPCHurtMgr.ClearPlayerHurtList(curNPC) return True #--------------------------------------------------------------------- @@ -3830,9 +2254,7 @@ ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', curNPCID) if ipyData: GameServe_GameWorldBossState(curNPCID, 1) - if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family: - FamilyRobBoss.FamilyOwnerBossOnReborn(curNPC) - + # 检查是否有光环, 在重生时处理,不然可能导致有些无战斗逻辑的怪物无法套上光环buff skillManager = curNPC.GetSkillManager() for index in xrange(skillManager.GetSkillCount()): @@ -3845,41 +2267,20 @@ GameWorld.DebugLog("NPC复活,套上光环: objID=%s,npcID=%s,skillID=%s" % (curNPC.GetID(), curNPC.GetNPCID(), useSkill.GetSkillID())) SkillShell.NPCUseSkill(curNPC, useSkill, tick) - curNPC.NotifyAppear() # 最终统一通知NPC出现 - self.NotifyNPCShow(curNPCID, tick) # 广播NPC秀 + self.__notifyAppear() # 最终统一通知NPC出现 return - def NotifyNPCShow(self, npcID, tick): - ## 广播NPC秀 - mapID = GameWorld.GetMap().GetMapID() - npcShowIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCShow", npcID, mapID) - if not npcShowIpyData: - #GameWorld.DebugLog("不需要NPC秀: npcID=%s" % npcID) - return - #if npcShowIpyData.GetBindMissionID(): - # #GameWorld.DebugLog("有绑定任务ID的,前端自己展示NPC秀!mapID=%s,npcID=%s" % (mapID, npcID)) + def __notifyAppear(self): + ## //04 06 NPC出现#tagNPCAppear,可能也有 04 08 玩家召唤NPC出现#tagPlayerSummonNPCAppear,卡牌先简化,只使用0406 + #curNPC = self.__Instance + #objID = curNPC.GetID() + #turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(objID) + #if not turnFight: + # # 非回合制怪保留原通知 + # curNPC.NotifyAppear() # return - if npcShowIpyData.GetShowType(): - #GameWorld.DebugLog("前端自己展示的NPC秀!mapID=%s,npcID=%s" % (mapID, npcID)) - return - endTick = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FBDict_NPCShowEndTick % npcID) - if endTick: - #GameWorld.DebugLog("已经存在同个NPCID的NPC秀,不重复展示!npcID=%s" % (npcID)) - return - endTick = tick + npcShowIpyData.GetProtectTime() - GameWorld.GetGameFB().SetGameFBDict(ChConfig.Def_FBDict_NPCShowEndTick % npcID, endTick) - # 广播地图内玩家展示NPC秀 - npcShowPack = ChPyNetSendPack.tagMCNPCShow() - npcShowPack.NPCID = npcID - playerManager = GameWorld.GetMapCopyPlayerManager() - for index in xrange(playerManager.GetPlayerCount()): - player = playerManager.GetPlayerByIndex(index) - if not player.GetPlayerID(): - continue - NetPackCommon.SendFakePack(player, npcShowPack) - - GameWorld.DebugLog("开始NPC秀: npcID=%s,tick=%s,endTick=%s" % (npcID, tick, endTick)) + # 回合制怪不通知,统一由 // B4 24 回合战斗初始化 #tagSCTurnFightInit return #--------------------------------------------------------------------- @@ -3936,48 +2337,6 @@ curNPC.SetDict(ChConfig.Def_NPC_Dict_HPPerLogicMark, hpPerLogicMark) return - - ## 给附近玩家加功勋 - # @param self 类实例 - # @param addPrestigeFormat 加功勋公式 - # @param matrix 范围大小 - # @return - def __GiveNearbyPlayerPrestige(self, addPrestigeFormat, matrix=ChConfig.Def_Matrix_Three): -# if addPrestigeFormat == '': -# return -# curNPC = self.__Instance -# npcPosX = curNPC.GetPosX() -# npcPosY = curNPC.GetPosY() -# npcLV = curNPC.GetLV() -# gameMap = GameWorld.GetMap() -# -# for curPos in matrix: -# -# #检查有没有对象在这一点上 -# mapObj = gameMap.GetPosObj(npcPosX + curPos[0], npcPosY + curPos[1]) -# -# if not mapObj: -# continue -# -# #遍历当前点对象 -# for i in range(0, mapObj.GetObjCount()): -# -# curObj = mapObj.GetObjByIndex(i) -# curObjType = curObj.GetGameObjType() -# -# #不是玩家,跳过 -# if curObjType != IPY_GameWorld.gotPlayer: -# continue -# -# curTag = GameWorld.GetObj(curObj.GetID(), curObjType) -# if not curTag: -# continue -# playerLV = curTag.GetLV() -# addPrestige = eval(addPrestigeFormat) -# PlayerPrestigeSys.AddPrestigeOffcialLV(curTag, addPrestige, ChConfig.Def_AddPrestige_NPC) - - return - #--------------------------------------------------------------------- ## NPC死的时候, 检查自己是否需要重生. 0: tick后仍然死亡 1: tick后可以重生 # @param self 类实例 @@ -4031,12 +2390,48 @@ # @return 返回值无意义 # @remarks 刷新NPC属性和行为状态 def RefreshNPCState(self, canSyncClient=True, isReborn=False): + curNPC = self.__Instance + if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo): + # 回合制怪走自己的刷属性规则 + self.RefreshTurnfightNPCAttr() + return + self.RefreshNPCAttrState(canSyncClient, isReborn) self.RefreshNPCActionState() - + def RefreshTurnfightNPCAttr(self): + curNPC = self.__Instance + lineupPlayerID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) + heroAttrDict = {} + if lineupPlayerID: + heroAttrDict.update({ + ChConfig.AttrID_Atk:500000000, + ChConfig.AttrID_Def:50000000, + ChConfig.AttrID_MaxHP:3000000000, + }) + else: + npcDataEx = GetNPCDataPy(curNPC.GetNPCID()) + if not npcDataEx: + return + heroAttrDict.update({ + ChConfig.AttrID_Atk:npcDataEx.GetAtk(), + ChConfig.AttrID_Def:npcDataEx.GetDef(), + ChConfig.AttrID_MaxHP:npcDataEx.GetMaxHP(), + }) + + GameWorld.DebugLog("heroAttrDict: ID:%s,NPCID:%s,%s" % (curNPC.GetID(), curNPC.GetNPCID(), heroAttrDict)) + # 重置属性状态 + GameObj.ClearBattleEffect(curNPC) + curNPC.ResetNPCBattleState() + # 设置属性 + curNPC.SetMinAtk(heroAttrDict.get(ChConfig.AttrID_Atk, 1)) + curNPC.SetMaxAtk(heroAttrDict.get(ChConfig.AttrID_Atk, 1)) + curNPC.SetDef(heroAttrDict.get(ChConfig.AttrID_Def, 1)) + GameObj.SetMaxHP(curNPC, heroAttrDict.get(ChConfig.AttrID_MaxHP, 1)) + return + ## 刷新NPC属性 # @param self 类实例 # @param canSyncClient 是否通知客户端刷新信息(宠物) @@ -4080,29 +2475,6 @@ return - def SetHelpBattleRobotRebornAttr(self, fightPower): - '''助战机器人只设置血量属性 - 血量算法,(助战玩家=助战机器人):每个副本配置伤害*(助战玩家战力/副本规定战力)*系数值 系数值暂定为50 - ''' - curNPC = self.__Instance - mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID()) - funcLineID = FBCommon.GetFBPropertyMark() - ipyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", mapID, funcLineID) - if not ipyData: - return - - SetSuppressFightPower(curNPC, fightPower) - fbFightPower = ipyData.GetFightPowerMin() - baseHurt = ipyData.GetRobotBaseHurt() - hpCoefficient = ipyData.GetRobotHPCoefficient() - maxHP = int(eval(IpyGameDataPY.GetFuncCompileCfg("HelpBattleRobot", 2))) - GameWorld.DebugLog("设置助战机器人属性: objID=%s,fightPower=%s,maxHP=%s" % (curNPC.GetID(), fightPower, maxHP)) - GameObj.SetMaxHP(curNPC, maxHP) - GameObj.SetHP(curNPC, maxHP) - curNPC.Notify_HP() - curNPC.Notify_MaxHP() - return - # NPC移动速度特殊处理,只处理百分比不能处理固定值 # 因为 ChConfig.TYPE_Calc_AttrSpeed 非服务端移动速度,偷懒处理法 def RefreshNPCSpeed(self, allAttrList): @@ -4116,9 +2488,6 @@ speed = int(curNPC.GetSpeed() * (ShareDefine.Def_MaxRateValue) / max(100.0, float(ShareDefine.Def_MaxRateValue + speedPer))) curNPC.SetSpeed(speed) curNPC.SetDict(ChConfig.Def_NPC_Dict_SpeedPer, speedPer) - if GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_GatherSoul: - #目前只在聚魂副本里通知 - NPCSpeedChangeNotify(curNPC, curNPC.GetSpeed()) return @@ -4220,14 +2589,6 @@ curNPC = self.__Instance npcID = curNPC.GetNPCID() #######################特殊NPC的处理 - #===================================================================================================== - # if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotTruck: - # #如果是骠车死亡, 调用骠车死亡逻辑 - # PlayerTruck.DoTruckDestroy(curNPC) - #===================================================================================================== - - #boss伤血排行榜击杀逻辑 - #BossHurtMng.BossOnKilled(curNPC) #掉落需要用到摸怪,所以在处理掉落奖励之前设置 self.__SetFeelNPCPlayerList() @@ -4243,29 +2604,12 @@ # 记录boss击杀信息的NPC bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID) 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() killerIDList = [player.GetPlayerID() for player in self.__ownerPlayerList] GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0, True, killerIDList) if npcID == IpyGameDataPY.GetFuncCfg("BossRebornServerBoss", 3): PlayerControl.WorldNotify(0, "BossRebornBossKilled", [curNPC.GetNPCID()]) - #=========================================================================================== - # # 暗金boss - # if curNPC.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark: - # #PlayerControl.WorldNotify(0, "Old_andyshao_861048", [curNPC.GetNPCID()]) - # if mapID == ChConfig.Def_MapID_DouHunTan: - # NPCCustomRefresh.DoRefreshNeutralBoss(npcID) - # - # # 周围玩家加威望 - # npcKilledAddPrestigeDict = ReadChConfig.GetEvalChConfig('NPCKilledAddPrestige') - # if npcID in npcKilledAddPrestigeDict: - # addPrestigeFormat = npcKilledAddPrestigeDict[npcID] - # self.__GiveNearbyPlayerPrestige(addPrestigeFormat, ChConfig.Def_Matrix_Six) - #=========================================================================================== - #清空NPC的仇恨 curNPC.GetNPCAngry().Clear() return @@ -4275,7 +2619,7 @@ curNPC = self.__Instance self.__FeelPlayerList = [] - npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC) + npcHurtList = [] #NPCHurtManager.GetPlayerHurtList(curNPC) if not npcHurtList: npcHurtList = curNPC.GetPlayerHurtList() #npcHurtList.Sort() #这里不排序,只要有伤害就算 @@ -4324,68 +2668,6 @@ self.__MissionOnKillNPC(eventPlayer, True) return - - #--------------------------------------------------------------------- - def __GetDropMoneyModelID(self, moneyValue): - ## 获取掉落金币模型ID - if not moneyValue: - return 0 - moneyItemList = IpyGameDataPY.GetFuncEvalCfg("GoldModel", 1) # 金币掉落数量对应模型-[(最大金币数,物品模型ID), ...] - if not moneyItemList: - return 0 - for count, moneyID in moneyItemList: - if moneyValue <= count: - return moneyID - return moneyItemList[-1][1] - - def __NPCSpecialDropItem(self, dropPlayer, ownerPlayerList, ipyDrop): - '''特殊掉落 (私有特殊掉落 + 击杀次数特殊掉落), 支持摸怪 - @return: None - @return: [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...] - ''' - curNPC = self.__Instance - npcID = curNPC.GetNPCID() - specDropItemList = [] - - #playerLV = dropPlayer.GetLV() - #maxDropLV = ipyDrop.GetMaxDropLV() - #if maxDropLV and playerLV > maxDropLV: - # GameWorld.DebugLog("超过最大可掉落等级,不掉落物品,特殊掉落!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV)) - # return specDropItemList - - auctionItemCanSell = ipyDrop.GetAucionItemCanSell() - # 击杀次数掉落算摸怪 - killCountDropInfo = ipyDrop.GetKillCountDropPri() - if killCountDropInfo: - for feelPlayer in self.__FeelPlayerList: - needKillCount, killDropItemList, isDropInItemPack = killCountDropInfo - killCountDropItemList = GetKillCountDropItemList(feelPlayer, npcID, needKillCount, killDropItemList) - for dropItemID in killCountDropItemList: - isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropItemID) else 0 - specDropItemList.append([feelPlayer, dropItemID, isAuctionItem, isDropInItemPack]) - GameWorld.DebugLog("击杀次数必掉(可摸怪): npcID=%s,dropItemID=%s,needKillCount=%s,isDropInItemPack=%s,isAuctionItem=%s" - % (npcID, dropItemID, needKillCount, isDropInItemPack, isAuctionItem), feelPlayer.GetPlayerID()) - - # 私有掉落 - isDropInItemPack = False - fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3) - if npcID in fbGradePriItemIDDropDict: - gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID] - curGrade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade) - priDropInfoList = gradePriItemIDDropDict.get(curGrade, []) - priDropIDList = [] - for priItemID, priItemCount in priDropInfoList: - priDropIDList += [priItemID] * priItemCount - else: - priDropIDList = ipyDrop.GetPriItemIDDrop() - for dropItemID in priDropIDList: - isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropItemID) else 0 - for ownerPlayer in ownerPlayerList: - specDropItemList.append([ownerPlayer, dropItemID, isAuctionItem, isDropInItemPack]) # 默认绑定 - #GameWorld.DebugLog("私有物品掉落: dropItemID=%s" % dropItemID, ownerPlayer.GetPlayerID()) - - return specDropItemList - ## 物品掉落 # @param self 类实例 # @param dropPlayer 掉落判断相关玩家 @@ -4393,106 +2675,6 @@ # @param HurtID 伤血ID # @return 返回值无意义 def __NPCDropItem(self, dropPlayer, hurtType, hurtID, ownerPlayerList=[], isOnlySelfSee=False): - if not dropPlayer: - return - curNPC = self.__Instance - PlayerActCollectWords.OnKillNPCDrop(dropPlayer, curNPC) - 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, - ChConfig.Def_FBMapID_KillDevil]: - GameWorld.DebugLog("该地图不走直接掉落物品逻辑!mapID=%s" % mapID) - return - if isGameBoss: - GameWorld.Log("NPC开始掉落: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID()) - ipyDrop = GetNPCDropIpyData(npcID) - if not ipyDrop: - if isGameBoss: - curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv) - GameWorld.ErrLog("取不到NPC掉落信息!npcID=%s,curWorldLV=%s" % (npcID, curWorldLV)) - return - - dropIDList, auctionIDList, dropMoneyCnt, moneyValue = [], [], 0, 0 - dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList, ipyDrop, False) - if dropInfo: - dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo - - moneyID = self.__GetDropMoneyModelID(moneyValue) - if moneyID and dropMoneyCnt: - dropIDList += [moneyID] * dropMoneyCnt - - specItemSign = "SpecItem" - playerSpecDropList = [] - if dropInfo: - playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...] 私有特殊掉落 + 击杀次数特殊掉落 - dropIDList += [specItemSign] * len(playerSpecDropList) - - if len(dropIDList) > 5: - #打乱物品顺序 - random.shuffle(playerSpecDropList) - random.shuffle(dropIDList) - - if not dropIDList and isGameBoss: - GameWorld.ErrLog("Boss没有掉落: dropPlayerLV=%s,ipyWorldLV=%s,maxDropLV=%s" - % (dropPlayer.GetLV(), ipyDrop.GetMaxWorldLV(), ipyDrop.GetMaxDropLV()), dropPlayer.GetPlayerID()) - - sightLevel = PlayerControl.GetMapRealmDifficulty(dropPlayer) - gameMap = GameWorld.GetMap() - dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # 以NPC为中心点开始掉落 - index = 0 - for posX, posY in ChConfig.Def_DropItemAreaMatrix: - resultX = dropPosX + posX - resultY = dropPosY + posY - - if not gameMap.CanMove(resultX, resultY): - #玩家不可移动这个点 - continue - - if index > len(dropIDList) - 1: - break - - isDropInItemPack = False - itemID = dropIDList[index] - index += 1 - if itemID == specItemSign: - if not playerSpecDropList: - continue - itemCnt = 1 - ownerPlayer, itemID, isAuctionItem, isDropInItemPack = playerSpecDropList[0] - ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, ownerPlayer.GetPlayerID() - playerSpecDropList = playerSpecDropList[1:] - else: - ownerPlayer = dropPlayer - ownerType, ownerID = hurtType, hurtID - itemCnt = moneyValue if itemID == moneyID else 1 - isAuctionItem = itemID in auctionIDList - - curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, isAuctionItem, dropPlayer) - if not curItem: - continue - - if mapID == ChConfig.Def_FBMapID_GatherSoul:#聚魂副本特殊处理 - GameLogic_GatherSoul.KillGatherSoulNPCDropAward(itemID, itemCnt, isAuctionItem) - dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem) - SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr) - curItem.Clear() - continue - - if isDropInItemPack: - curItem.SetUserAttr(ShareDefine.Def_IudetSource, ShareDefine.Item_Source_VirtualItemDrop) - dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem) - #可以放入背包 - if ItemControler.DoLogic_PutItemInPack(ownerPlayer, curItem, event=["NPCDrop", False, {"npcID":npcID}]): - #通知客户端 - SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr) - - else: - self.__MapCreateItem(curItem, resultX, resultY, ownerType, ownerID, isOnlySelfSee=isOnlySelfSee, sightLevel=sightLevel) return #--------------------------------------------------------------------- ## NPC被杀死逻辑处理 @@ -4513,10 +2695,6 @@ curNPC_GameNPCObjType = curNPC.GetGameNPCObjType() #---特殊死亡逻辑--- - #镖车不能通知死亡 - if curNPC_GameNPCObjType == IPY_GameWorld.gnotTruck: - return - #宠物死亡调用独立接口 if curNPC_GameNPCObjType == IPY_GameWorld.gnotPet: PetControl.SetPetDead(curNPC) @@ -4531,52 +2709,7 @@ #调用底层 -> 通知客户端死亡 SetDeadEx(curNPC) return - #--------------------------------------------------------------------- - ## 召唤兽死亡,替换仇恨 - # @param self 类实例 - # @return 返回值无意义 - # @remarks 召唤兽死亡,替换仇恨 - #=========================================================================== - # def __NPCReplaceAngry(self): - # curNPC = self.__Instance - # #仅处理宠物和召唤兽 - # if curNPC.GetGameNPCObjType() not in [IPY_GameWorld.gnotSummon, IPY_GameWorld.gnotPet]: - # return - # - # if curNPC.GetType() not in [IPY_GameWorld.ntSummon, IPY_GameWorld.ntElf, - # IPY_GameWorld.ntTrap, IPY_GameWorld.ntTruck, - # IPY_GameWorld.ntFairy]: - # return - # - # summonOwner = GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC) - # - # if summonOwner == None: - # summonOwner = GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC) - # - # #异常错误 - # if summonOwner == None: - # #GameWorld.Log("替换仇恨,查找召唤兽主人失败 curNPC = %s"%(curNPC.GetNPCID())) - # return - # - # #仇恨NPC列表 - # angryNPCList = list() - # for index in range(curNPC.GetAngryNPCCount()): - # angryNPC = curNPC.GetAngryNPCByIndex(index) - # #已经死亡 - # if GameObj.GetHP(angryNPC) <= 0: - # continue - # - # angryNPCList.append(angryNPC) - # - # #在ReplaceNPCAngryFromOldToNew的时候, 会删除仇恨, - # #改变 summonNPC.GetAngryNPCCount() 的长度, 所以必须先构建列表, - # #在替换仇恨 - # for angryListNPC in angryNPCList: - # #替换仇恨 - # ReplaceNPCAngryFromOldToNew(angryListNPC, curNPC, summonOwner) - # - # return - #=========================================================================== + #--------------------------------------------------------------------- ## NPC非战斗中回血 # @param self 类实例 @@ -4746,12 +2879,6 @@ return curNPC = self.__Instance - - # VIP杀怪加攻 - PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, GetNPCLV(curNPC)) - - # SP值 - PlayerControl.AddZhenQiByKillNPC(lastHurtPlayer, curNPC.GetSP()) return #--------------------------------------------------------------------- @@ -4865,13 +2992,6 @@ hurtID = killerDict.keys()[0] if isGameBoss: GameWorld.Log(" 归属默认玩家, npcID=%s,playerID=%s" % (npcID, hurtID)) - elif GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_GatherSoul: - player = FBCommon.GetCurSingleFBPlayer() - if player: - hurtID = player.GetPlayerID() - killerDict[hurtID] = player - hurtType = ChConfig.Def_NPCHurtTypePlayer - #GameWorld.Log(" 聚魂副本归属默认玩家, npcID=%s,playerID=%s" % (npcID, hurtID)) return killerDict, killTeam, hurtType, hurtID @@ -5195,10 +3315,9 @@ else: if GetNPCLV(curNPC) >= curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'): PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC) - PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_KillNPC) PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_KillNPC) PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FeastRedPack_KillSpecificNPC, 1, [npcID]) - PlayerPrestigeSys.AddRealmTaskValue(curPlayer, PlayerPrestigeSys.RealmTaskType_KillNPC, 1) + #PlayerPrestigeSys.AddRealmTaskValue(curPlayer, PlayerPrestigeSys.RealmTaskType_KillNPC, 1) if ChConfig.IsGameBoss(curNPC): OnPlayerKillBoss(curPlayer, npcID, mapID, False) @@ -5225,19 +3344,6 @@ return npcID = curNPC.GetNPCID() #GameWorld.DebugLog("__MissionOnKillNPC isFeel=%s" % (isFeel), curPlayer.GetPlayerID()) - killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1) - limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID) - isWorldBoos = limitIndex == ShareDefine.Def_Boss_Func_World - if isFeel: - #击杀NPC触发摸怪任务事件 - EventShell.EventRespons_OnKillByFeel(curPlayer, curNPC) - if isWorldBoos: - EventShell.EventRespons_KillWorldBossByFeel(curPlayer) - else: - #普通NPC击杀触发 - EventShell.EventRespons_OnKillById(curPlayer, curNPC) - if isWorldBoos: - EventShell.EventRespons_KillWorldBoss(curPlayer) #击杀特定NPC成就 PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID]) return @@ -5246,7 +3352,6 @@ ## 测试查错日志,临时用 ## 相关bug: 仙界秘境无经验、boss无掉落 return ChConfig.IsGameBoss(self.__Instance) - #return GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_BZZD or ChConfig.IsGameBoss(self.__Instance) #--------------------------------------------------------------------- ## 普通组队给经验 @@ -5389,19 +3494,14 @@ GameWorld.Log("检查Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s" % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType)) #if dropOwnerType == ChConfig.DropOwnerType_MaxHurt: - maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead, checkCanDead) - if not maxHurtInfo: - maxHurtInfo = NPCHurtMgr.RefreshHurtList(curNPC, tick, refreshInterval, isDead) - - if maxHurtInfo: - tagObj, ownerType, ownerID = maxHurtInfo + #maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead, checkCanDead) + # + #if maxHurtInfo: + # tagObj, ownerType, ownerID = maxHurtInfo elif dropOwnerType == ChConfig.DropOwnerType_Family: - ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval) - if ownerInfo: - tagObj, ownerFamilyID = ownerInfo - ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID - + pass + elif dropOwnerType == ChConfig.DropOwnerType_Contend: tagObj = self.__RefreshContendOwner() if tagObj: @@ -5525,7 +3625,7 @@ if isDead: GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID)) - hurtList = NPCHurtManager.GetPlayerHurtList(curNPC) + hurtList = [] #NPCHurtManager.GetPlayerHurtList(curNPC) # 刷新归属 if ownerType == ChConfig.Def_NPCHurtTypePlayer: curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer) @@ -5847,9 +3947,6 @@ # 采集耗时 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))) prepareType = IPY_GameWorld.pstCollecting if curNPC.GetType() == IPY_GameWorld.ntCollection else IPY_GameWorld.pstMissionCollecting PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, prepareType, prepareID=curNPC.GetID()) if collectNPCIpyData.GetLostHPPer(): @@ -5983,93 +4080,7 @@ return def DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, collectCnt=1, crossCollectOK=False, isSweep=False): - GameWorld.DebugLog("给采集奖励: npcID=%s,collectCnt=%s,crossCollectOK=%s" % (npcID, collectCnt, crossCollectOK)) - 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已达到最大采集次数: npcID=%s,todayCollTime=%s,limitMaxTime=%s" % (npcID, todayCollTime, limitMaxTime)) - return - - 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(" 增加采集次数: 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) - jsonItemList = [] - if awardItemList: - for itemID, itemCount, isAuctionItem in awardItemList: - if ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]): - jsonItemList.append(ItemCommon.GetJsonItem([itemID, itemCount, isAuctionItem])) - - if not isSweep: - 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]) - if crossCollectOK: - PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_CrossCollect) - #SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID) - - if not isSweep: - GameLogic_CrossGrassland.DecCustomSceneNPCCount(curPlayer, npcID) - if isMaxTime: - GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer) - - return jsonItemList + return ## 采集结果同步 # @param None @@ -6117,7 +4128,7 @@ def PlayerOnDay(curPlayer): #采集次数重置 CollNPCTimeOnDay(curPlayer) - itemDropLimitDayInfo = IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 2, {}) + itemDropLimitDayInfo = {} #IpyGameDataPY.GetFuncEvalCfg("ItemDropCountLimit", 2, {}) for itemID in itemDropLimitDayInfo.keys(): if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DropCountToday % itemID): PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DropCountToday % itemID, 0) @@ -6301,42 +4312,6 @@ return 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)) - recBossIDList = IpyGameDataPY.GetFuncEvalCfg('DropRecordBossID', 1) - if npcID not in recBossIDList: - return - recDropEquipInfoDict = IpyGameDataPY.GetFuncEvalCfg('DropRecordEquipment', 1, {}) - recSpecialItemIDList = IpyGameDataPY.GetFuncEvalCfg('DropRecordValue', 1) - recItemIDList = IpyGameDataPY.GetFuncEvalCfg('DropRecordNormal', 1) - # weightValue 珍惜度 数值越大越珍贵(用于排序) - needRecord = False - itemUserData = "" - if itemID in recItemIDList: - needRecord = True - weightValue = recItemIDList.index(itemID) - elif itemID in recSpecialItemIDList: - needRecord = True - weightValue = recSpecialItemIDList.index(itemID) + 10000 - else: - 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, needItemSuite = recordCondition - if itemClassLV >= needClassLV and itemColor >= needItemColor and isSuit >= needItemSuite: - needRecord = True - if not needRecord: - return - 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 #// A5 52 购买功能NPC采集次数 #tagCMBuyCollectionCnt @@ -6367,16 +4342,12 @@ buyTimesVIPPriID = IpyGameDataPY.GetFuncEvalCfg("KillBossCntLimit1", 1, {}).get(killBossMark) if not buyTimesVIPPriID: return - canBuyCnt = PlayerVip.GetPrivilegeValue(curPlayer, buyTimesVIPPriID) + canBuyCnt = 0 canBuyCnt += PlayerGoldInvest.GetAddBossBuyCnt(curPlayer, killBossMark) hasBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Boss_KillCntBuyCnt%killBossMark, 0) playerID = curPlayer.GetPlayerID() if hasBuyCnt >= canBuyCnt: GameWorld.DebugLog('购买BOSS可击杀次数, 已达到今日最大可购买次数,hasBuyCnt=%s, canBuyCnt=%s'%(hasBuyCnt, canBuyCnt), playerID) - return - canKillCnt, dayTimesLimit = BossHurtMng.GetCanKillBossCnt(curPlayer, killBossMark) - if canKillCnt >= dayTimesLimit: - GameWorld.DebugLog('购买BOSS可击杀次数, 剩余次数已满!,canKillCnt=%s'%(canKillCnt), playerID) return costGold = IpyGameDataPY.GetFuncEvalCfg("KillBossCntLimit1", 2, {}).get(killBossMark) @@ -6402,7 +4373,6 @@ return # 增加购买次数 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Boss_KillCntBuyCnt%killBossMark, hasBuyCnt + 1) - BossHurtMng.NotifyAttackBossCnt(curPlayer, killBossMark) CrossPlayerData.SendMergePlayerDataNow(curPlayer) return @@ -6451,32 +4421,10 @@ GameWorld.DebugLog("通知GameServer地图Boss分流信息: mapID=%s,lineID=%s,shuntPlayerDict=%s" % (mapID, lineID, shuntPlayerDict), lineID) return -def NPCSpeedChangeNotify(curNPC, speed): - ##通知NPC速度 - sendPack = ChNetSendPack.tagObjInfoRefresh() - sendPack.Clear() - sendPack.ObjID = curNPC.GetID() - sendPack.ObjType = curNPC.GetGameObjType() - sendPack.RefreshType = IPY_GameWorld.CDBPlayerRefresh_Speed - 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): @@ -6514,64 +4462,6 @@ # @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