| | |
| | | import BossHurtMng
|
| | | import PlayerSuperMarket
|
| | | import GameLogic_FamilyInvade
|
| | | #import GameLogic_MunekadoTrial
|
| | | import GameLogic_GatherSoul
|
| | | import FormulaControl
|
| | | import PlayerMagicWeapon
|
| | | import PlayerBossReborn
|
| | | import PlayerFairyCeremony
|
| | | import FamilyRobBoss
|
| | | import IpyGameDataPY
|
| | | import PyGameData
|
| | | import PlayerTeam
|
| | |
| | | NPCAttr_ParamDict, # 过程参数公式
|
| | | NPCAttr_AttrStrengthenList, # 等级成长属性公式
|
| | | NPCAttr_PlayerCntCoefficient, # 地图人数对应属性额外成长系数 {mapID:{"属性名":{组队进入人数:系数, ...}, ...}, ...}
|
| | | NPCAttr_NPCPlayerCntCoefficient, # NPC特殊成长人数对应属性额外成长系数 {npcID:{"属性名":{人数:系数, ...}, ...}, ...}, 优先级大于地图人数系数
|
| | | NPCAttr_DynNPCLVMap, # 动态等级的地图ID列表,默认已刷新出来的NPC等级不会再变更,下次刷出来的怪物等级变更 [地图ID, ...]
|
| | | NPCAttr_DynPCCoefficientMap, # 动态人数系数的地图ID {地图ID:是否马上刷新属性, ...}
|
| | | ) = range(5)
|
| | | ) = range(6)
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##NPC初始化->出生调用
|
| | |
| | | return curNPC.GetLV()
|
| | |
|
| | | def GetRealmLV(curNPC): return curNPC.GetMAtkMin() # NPC表中此字段含义改成境界等级
|
| | | def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV) # NPC表中此字段含义改成境界等级
|
| | | def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # 风防代表是否等级压制
|
| | | def GetSuppressFightPower(curNPC): return curNPC.GetThunderDef() # 雷防代表压制战力
|
| | | def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(value)
|
| | |
| | | def GetFaction(curNPC): return curNPC.GetCountry()
|
| | | def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率
|
| | | def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果
|
| | | def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果
|
| | | def GetSkillEnhance(curNPC): return curNPC.GetWindAtk() # 风攻代表NPC 《普攻》 的技能附加伤害固定值
|
| | | def GetNPCSeries(curNPC): return curNPC.GetPoisionDef() # 毒防字段代表NPC系,按二进制位区分
|
| | |
|
| | |
| | | gameFB = GameWorld.GetGameFB()
|
| | |
|
| | | if strengthenIpyData.GetIsStrengthenByPlayerCount():
|
| | | strengthenPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt)
|
| | | if not strengthenPlayerCnt:
|
| | | GameWorld.ErrLog("NPC配置了按玩家人数成长类型,但是无法获取到对应的玩家人数!npcID=%s" % (npcID))
|
| | | return
|
| | | |
| | | 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:
|
| | |
| | | # 根据平均等级
|
| | | 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)
|
| | |
|
| | | 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
|
| | |
| | | curNPC.Notify_HPEx()
|
| | | curNPC.Notify_MaxHPEx()
|
| | | #GameWorld.DebugLog(" aftHP=%s,aftMaxHP=%s" % (aftHP, aftMaxHP))
|
| | | |
| | | # 机器人复活初始化给技能
|
| | | if isReborn and curNPC.GetType() == ChConfig.ntRobot:
|
| | | __OnFBRobotReborn(curNPC, strengthenLV)
|
| | | |
| | | return
|
| | |
|
| | | def __OnFBRobotReborn(curNPC, npcLV):
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | objID = curNPC.GetID()
|
| | | jobSkillDict = IpyGameDataPY.GetFuncEvalCfg("FBRobotCfg", 1)
|
| | | robotJob = random.choice(jobSkillDict.keys())
|
| | | lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {})
|
| | | lineRobotJobDict[objID] = robotJob
|
| | | PyGameData.g_fbRobotJobDict[lineID] = lineRobotJobDict
|
| | | skillInfoDict = jobSkillDict[robotJob]
|
| | | 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技能: objID=%s,robotJob=%s,npcLV=%s, %s" % (objID, robotJob, npcLV, skillIDList))
|
| | | skillManager = curNPC.GetSkillManager()
|
| | | for skillID in skillIDList:
|
| | | skillManager.LearnSkillByID(skillID)
|
| | | playerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if not curPlayer:
|
| | | continue
|
| | | FBLogic.DoFBHelp(curPlayer, tick)
|
| | | 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):
|
| | |
| | | paramDict = attrStrengthenInfo[NPCAttr_ParamDict] # 过程参数公式字典
|
| | | attrStrengthenList = attrStrengthenInfo[NPCAttr_AttrStrengthenList] # 属性成长公式字典
|
| | | playerCntCoefficient = attrStrengthenInfo[NPCAttr_PlayerCntCoefficient] # 人数系数
|
| | | npcIDPlayerCntCoefficient = attrStrengthenInfo[NPCAttr_NPCPlayerCntCoefficient] # 特殊NPC人数系数
|
| | | baseMaxHP = npcData.GetHPEx() * ShareDefine.Def_PerPointValue + npcData.GetHP()
|
| | |
|
| | | if strengthenLV:
|
| | |
| | | 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]
|
| | |
| | | if not hasattr(npcData, attrFuncName):
|
| | | continue
|
| | | attrValue = getattr(npcData, attrFuncName)()
|
| | | coefficient = GameWorld.GetDictValueByRangeKey(coefficientDict, strengthenPlayerCnt, 1)
|
| | | # 按字典配置
|
| | | 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"
|
| | |
| | | return attrDict
|
| | |
|
| | | def GiveKillNPCDropPrize(curPlayer, mapID, npcCountDict, exp_rate=None, mailTypeKey=None, isMail=False,
|
| | | extraItemList=[], prizeMultiple=1, dropItemMapInfo=[]):
|
| | | extraItemList=[], prizeMultiple=1, dropItemMapInfo=[], curGrade=0):
|
| | | '''给玩家击杀NPC掉落奖励
|
| | | @param mapID: 击杀的NPC所在地图ID,注意次地图并不一定是玩家当前地图
|
| | | @param npcCountDict: 执行单次时所击杀的npc数量字典 {npcID:count, ...}
|
| | |
| | | # 掉落有概率因素,需多次执行
|
| | | for dCount in xrange(1, totalCount + 1):
|
| | | isKillCountDropEquipEx = dCount == 1 # 同一只NPC一次处理中多次击杀的情况,只算一次附加装备处理
|
| | | dropInfo = GetNPCDropInfo(curPlayer, mapID, npcID, isKillCountDropEquipEx=isKillCountDropEquipEx)
|
| | | dropInfo = GetNPCDropInfo(curPlayer, mapID, npcID, isKillCountDropEquipEx=isKillCountDropEquipEx, curGrade=curGrade)
|
| | | if not dropInfo:
|
| | | continue
|
| | | dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue = dropInfo
|
| | |
| | | % (npcID, killCount, dropIDCountDict, dropIDBindDict, dropMoney), playerID)
|
| | | return dropIDCountDict, dropIDBindDict, dropMoney
|
| | |
|
| | | def GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList=[], ipyDrop=None, isSingle=True, isKillCountDropEquipEx=True):
|
| | | def GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList=[], ipyDrop=None, isSingle=True, isKillCountDropEquipEx=True, curGrade=0):
|
| | | '''获取NPC掉落信息, 击杀及扫荡通用,调用该函数获得掉落信息,然后再看掉落地板上还是直接放入背包
|
| | | @param dropPlayer: 用于判断调用相关用的玩家示例,该玩家并不一定是击杀者,只是按一定规则设定的掉落判断依据的玩家
|
| | | 如队伍,取等级最大的玩家,该玩家并不一定是击杀者
|
| | |
| | | indepRateDoCnt = ipyDrop.GetIndepRateDoCnt()
|
| | | if indepRateDoCnt:
|
| | | indepRateDoCnt = __GetNPCDropDoCountChange(indepRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd)
|
| | | dropEquipInfoList += __GetNPCIndepRateEquipDrop(ipyDrop, indepRateDoCnt, equipDropRatePlus)
|
| | | dropEquipInfoList += __GetNPCIndepRateEquipDrop(ipyDrop, indepRateDoCnt, equipDropRatePlus, curGrade)
|
| | |
|
| | | #GameWorld.DebugLog("阶,颜色,部位集合key,dropEquipInfoList=%s" % (dropEquipInfoList))
|
| | | placeDict = IpyGameDataPY.GetFuncCfg("EquipDropPartSets", 1)
|
| | |
| | | tagPlaceSortList.sort() # 升序排序
|
| | | tagPlaceSortList2.sort() # 升序排序
|
| | | if isKillCountDropEquipEx:
|
| | | GameWorld.DebugLog("都不满足目标装备的优先级信息: npcID=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, tagPlaceSortList), playerID)
|
| | | GameWorld.DebugLog("部分满足目标装备的优先级信息: npcID=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, tagPlaceSortList2), playerID)
|
| | | tagPlaceSortList += tagPlaceSortList2
|
| | | if tagPlaceSortList:
|
| | | tagPlace = tagPlaceSortList[0][-2]
|
| | | tagJob = tagPlaceSortList[0][-1]
|
| | | |
| | | GameWorld.DebugLog("都不满足目标装备的优先级信息: npcID=%s, 数量=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, len(tagPlaceSortList), tagPlaceSortList), playerID)
|
| | | GameWorld.DebugLog("部分满足目标装备的优先级信息: npcID=%s, 数量=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, len(tagPlaceSortList2), tagPlaceSortList2), playerID)
|
| | | if tagPlaceSortList or tagPlaceSortList2:
|
| | | isOptimalPlace = IpyGameDataPY.GetFuncCfg("DropEquipPlaceMode", 1) # 是否取最优解部位
|
| | | if isOptimalPlace:
|
| | | tagPlaceSortList += tagPlaceSortList2
|
| | | if tagPlaceSortList:
|
| | | tagPlace = tagPlaceSortList[0][-2]
|
| | | tagJob = tagPlaceSortList[0][-1]
|
| | | GameWorld.DebugLog("掉落目标部位取最优解: tagPlace=%s,tagJob=%s" % (tagPlace, tagJob), playerID)
|
| | | else:
|
| | | randPlaceCountLimit = IpyGameDataPY.GetFuncCfg("DropEquipPlaceMode", 2) # 全不满足目标条件部位有几个时才优先随机
|
| | | if len(tagPlaceSortList) < randPlaceCountLimit:
|
| | | tagPlaceSortList += tagPlaceSortList2
|
| | | else:
|
| | | GameWorld.DebugLog("优先随机都不满足目标装备的,randPlaceCountLimit=%s" % randPlaceCountLimit, playerID)
|
| | | randPlaceIndex = random.randint(0, len(tagPlaceSortList) - 1)
|
| | | GameWorld.DebugLog("掉落目标部位随机, randPlaceIndex=%s, 颜色,阶,星,评分,部位,职业=%s" % (randPlaceIndex, tagPlaceSortList), playerID)
|
| | | tagPlace = tagPlaceSortList[randPlaceIndex][-2]
|
| | | tagJob = tagPlaceSortList[randPlaceIndex][-1]
|
| | | GameWorld.DebugLog("掉落目标部位随机不满足条件的: tagPlace=%s,tagJob=%s" % (tagPlace, tagJob), playerID)
|
| | | |
| | | if isKillCountDropEquipEx:
|
| | | GameWorld.DebugLog("附加掉落指定目标装备信息: npcID=%s,玩家最少的击杀次数=%s,目标击杀数=%s,tagClassLV=%s,tagColor=%s,tagStar=%s,tagStarMin=%s,tagPlace=%s,tagJob=%s"
|
| | | % (npcID, dropEquipExKillCount, tagKillCount, tagClassLV, tagColor, tagStar, tagStarMin, tagPlace, tagJob), playerID)
|
| | |
| | | fbGradeColorStarRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 2) # 评级影响品质星级概率 {npcID:{(颜色,星级):[D级影响概率, ..., S级影响概率], ...}, ...}
|
| | | if npcID in fbGradeColorStarRateDict:
|
| | | gradeColorStarRateDict = fbGradeColorStarRateDict[npcID]
|
| | | curGrade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
|
| | | curGrade = curGrade if curGrade else GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
|
| | |
|
| | | colorDropCntDict = {} # 装备颜色已经掉落数 {颜色:数量, ...}
|
| | | colorMaxDropCntDict = ipyDrop.GetIndepRateMaxDropCount() # {颜色:上限数量,...}
|
| | |
| | | fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3)
|
| | | if npcID in fbGradePriItemIDDropDict:
|
| | | gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID]
|
| | | curGrade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
|
| | | curGrade = curGrade if curGrade else GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
|
| | | priDropInfoList = gradePriItemIDDropDict.get(curGrade, [])
|
| | | priDropIDList = []
|
| | | for priItemID, priItemCount in priDropInfoList:
|
| | |
| | | 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
|
| | | jobItemID = jobItemList[job - 1]
|
| | | canDropCount += 1
|
| | | |
| | | jobItemID = jobItemList[job - 1]
|
| | | for _ in xrange(canDropCount):
|
| | | dropItemIDList.append(jobItemID)
|
| | | #GameWorld.DebugLog("掉落自身职业指定物品ID: jobItemKey=%s,jobItemID=%s" % (jobItemKey, jobItemID))
|
| | |
|
| | |
| | | # 在只掉本职业里的不处理
|
| | | if jobItemKey in ItemKeyDropRateJobDict:
|
| | | 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
|
| | | |
| | | for _ in xrange(canDropCount):
|
| | | randJobItemID = random.choice(jobItemList)
|
| | | dropItemIDList.append(randJobItemID)
|
| | | #GameWorld.DebugLog("掉落随机职业指定物品ID: jobItemKey=%s,randJobItemID=%s" % (jobItemKey, randJobItemID))
|
| | |
| | | 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() / 100
|
| | | 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() / 100
|
| | | 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 __GetEquipIDList(npcID, classLV, color, placeList, star, itemJobList, tagPlace=None):
|
| | |
| | | #GameWorld.DebugLog("饼图装备掉落结果: doCnt=%s, %s" % (doCnt, dropEquipInfoList))
|
| | | return dropEquipInfoList
|
| | |
|
| | | def __GetNPCIndepRateEquipDrop(ipyDrop, doCnt, equipDropPlus):
|
| | | def __GetNPCIndepRateEquipDrop(ipyDrop, doCnt, equipDropPlus, curGrade=0):
|
| | | ## 获取NPC独立掉率装备掉落信息
|
| | | npcID = ipyDrop.GetNPCID()
|
| | | indepRateDict = ipyDrop.GetIndepRateDrop() # {(阶,颜色,部位集合key):概率,...}
|
| | |
| | | fbGradeColorRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 1) #{npcID:{颜色:[D级影响概率, ..., S级影响概率], ...}, ...}
|
| | | if npcID in fbGradeColorRateDict:
|
| | | gradeColorRateDict = fbGradeColorRateDict[npcID]
|
| | | curGrade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
|
| | | curGrade = curGrade if curGrade else GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
|
| | |
|
| | | #colorDropCntDict = {} # 装备颜色已经掉落数 {颜色:数量, ...}
|
| | | dropEquipInfoList = []
|
| | |
| | | # 设置npc死亡及自身处理
|
| | | SetDeadEx(summonNPC)
|
| | |
|
| | | if curNPC.GetGameObjType() == IPY_GameWorld.gotNPC and \
|
| | | curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:
|
| | | FBLogic.DoFB_SummonNPCDead(curNPC)
|
| | | if curNPC.GetGameObjType() == IPY_GameWorld.gotNPC:
|
| | | FBLogic.DoFB_NPCDead(curNPC)
|
| | |
|
| | | summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID)
|
| | | if summonPlayerID > 0:
|
| | |
| | | #因为存在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)
|
| | | |
| | |
|
| | | # 清除队伍成员伤血列表
|
| | | AttackCommon.ClearTeamPlayerHurtValue(curNPC)
|
| | | # 清除自定义伤血列表
|
| | | BossHurtMng.ClearHurtValueList(curNPC)
|
| | |
|
| | | #BossHurtMng.ClearHurtValueList(curNPC)
|
| | | if curNPC.GetType() == ChConfig.ntRobot:
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {})
|
| | | lineRobotJobDict.pop(curNPC.GetID(), 0)
|
| | | PyGameData.g_fbRobotJobDict[lineID] = lineRobotJobDict
|
| | | |
| | | # C++设置npc死亡
|
| | | curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason),
|
| | | curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerType),
|
| | |
| | | self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致
|
| | | self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者
|
| | | self.__FeelPlayerList = [] # 所有摸怪玩家列表,处理任务及某些逻辑用
|
| | | |
| | | self.__OwnerHurtType = 0
|
| | | self.__OwnerHurtID = 0
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | ## 移动到某一个点的附近点
|
| | |
| | | def GetIsBossView(self):
|
| | | # 主动视野情况,GetIsBoss 0 1 4 为普通NPC视野(有视野范围配置,但去除视野刷新),其他为BOSS类视野有刷新
|
| | | curNPC = self.__Instance
|
| | | if not ChConfig.IsGameBoss(curNPC) and not GetFaction(curNPC):
|
| | | if not ChConfig.IsGameBoss(curNPC) and not GetFaction(curNPC) and curNPC.GetType() != ChConfig.ntRobot:
|
| | | return False
|
| | |
|
| | | return True
|
| | |
| | | self.__AddAngryValue(npcAngry, curObjID, curObjType, plusAngryValue, canPile)
|
| | |
|
| | | #激活呆滞的NPC
|
| | | if curNPC.GetHP() > 0 and not curNPC.GetIsNeedProcess() :
|
| | | if GameObj.GetHP(curNPC) > 0 and not curNPC.GetIsNeedProcess() :
|
| | | curNPC.SetIsNeedProcess(True)
|
| | |
|
| | |
|
| | |
| | | # 这种情况一般是玩家未加入队伍前对该NPC有伤血,加入到某个队伍后,将该伤害转移到队伍中
|
| | | return True
|
| | |
|
| | | if hurtPlayer.GetHP() <= 0 or hurtPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | deadTime = hurtPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
|
| | | if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
|
| | | #GameWorld.DebugLog("伤血玩家死亡超过伤血保护时长,清除该伤血!playerID=%s" % hurtID)
|
| | | return True
|
| | | |
| | | #GameWorld.DebugLog("正常玩家伤血保护中!playerID=%s" % hurtID)
|
| | | return False
|
| | |
|
| | | def __GetTeamHurtNPCPlayerIDList(self, refreshPoint, teamID, tick):
|
| | |
|
| | | curNPC = self.__Instance
|
| | | teamHurtPlayerIDList = []
|
| | | # 如果没有在线队员在有效范围内,则进一步判断离线队员是否有伤血保护中的
|
| | | playerMgr = GameWorld.GetPlayerManager()
|
| | |
| | | if curTeamPlayer.GetCopyMapID() != copyMapID:
|
| | | #GameWorld.DebugLog("队员不在本线路,不计!playerID=%s" % playerID)
|
| | | continue
|
| | | |
| | | if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | deadTime = curTeamPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
|
| | | if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
|
| | | #GameWorld.DebugLog("伤血队员死亡超过伤血保护时长,不计!playerID=%s" % playerID)
|
| | | continue
|
| | | |
| | | #if curTeamPlayer.GetHP() > 0 and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
|
| | | if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
|
| | | if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
|
| | | and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False):
|
| | | #GameWorld.DebugLog("有队员在boss范围内,保留队伍伤血!teamID=%s,playerID=%s" % (teamID, curTeamPlayer.GetPlayerID()))
|
| | | teamHurtPlayerIDList.append(playerID)
|
| | | else:
|
| | |
| | | #获得伤血对象
|
| | | hurtObj = npcHurtList.GetHurtAt(index)
|
| | |
|
| | | curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, False)
|
| | | curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, True)
|
| | |
|
| | | if curPlayer or curTeam:
|
| | | return hurtObj
|
| | |
| | | curNPC = self.__Instance
|
| | | #清除状态
|
| | | self.__ClearNPCAllState(False)
|
| | | #初始化召唤兽
|
| | | self.__InitNPCSummon()
|
| | | #重置技能CD
|
| | | self.__NormalNPCInItCD()
|
| | | #只在重生或者满血的状态下才重置以下内容
|
| | | if isReborn or GameObj.GetHP(curNPC) >= GameObj.GetMaxHP(curNPC):
|
| | | #初始化召唤兽
|
| | | self.__InitNPCSummon()
|
| | | #重置技能CD
|
| | | self.__NormalNPCInItCD()
|
| | | |
| | | #重刷属性
|
| | | self.RefreshNPCState(isReborn=isReborn)
|
| | | #通知血量, 复活的情况不通知血量,由NPC出现包通知
|
| | |
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState',
|
| | | '%s' % (msgList), len(str(msgList)))
|
| | |
|
| | | if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
|
| | | FamilyRobBoss.FamilyOwnerBossOnReborn(curNPC)
|
| | | |
| | | # 检查是否有光环, 在重生时处理,不然可能导致有些无战斗逻辑的怪物无法套上光环buff
|
| | | skillManager = curNPC.GetSkillManager()
|
| | | for index in xrange(skillManager.GetSkillCount()):
|
| | |
| | | # @remarks 刷新NPC属性
|
| | | def RefreshNPCAttrState(self, canSyncClient=True, isReborn=False):
|
| | | curNPC = self.__Instance
|
| | | curNPCMaxHP_Before = GameObj.GetMaxHP(curNPC)
|
| | | #curNPCMaxHP_Before = GameObj.GetMaxHP(curNPC)
|
| | | #清空NPC战斗属性
|
| | | curNPC.ClearBattleEffect()
|
| | | #--------------------------------------------
|
| | |
| | |
|
| | | 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_HPEx()
|
| | | curNPC.Notify_MaxHPEx()
|
| | | return
|
| | |
|
| | | # NPC移动速度特殊处理,只处理百分比不能处理固定值
|
| | | # 因为 ChConfig.TYPE_Calc_AttrSpeed 非服务端移动速度,偷懒处理法
|
| | |
| | | # @remarks 刷新NPC行为属性
|
| | | def RefreshNPCActionState(self):
|
| | | curNPC = self.__Instance
|
| | | |
| | | OperControlManager.ClearObjActionState(curNPC)
|
| | |
|
| | | #根据BUFF 加上状态
|
| | |
| | | #=====================================================================================================
|
| | |
|
| | | #boss伤血排行榜击杀逻辑
|
| | | BossHurtMng.BossOnKilled(curNPC)
|
| | | #BossHurtMng.BossOnKilled(curNPC)
|
| | |
|
| | | #掉落需要用到摸怪,所以在处理掉落奖励之前设置
|
| | | self.__SetFeelNPCPlayerList()
|
| | |
| | | # 记录boss击杀信息的NPC
|
| | | bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID)
|
| | | if bossIpyData:
|
| | | if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
|
| | | killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID)
|
| | | #KillerJob = 0 if not self.__Killer else self.__Killer.GetJob()
|
| | | GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0)
|
| | | #===========================================================================================
|
| | |
| | | return moneyID
|
| | | return moneyItemList[-1][1]
|
| | |
|
| | | def __NPCSpecialDropItem(self, ownerPlayerList, ipyDrop):
|
| | | def __NPCSpecialDropItem(self, dropPlayer, ownerPlayerList, ipyDrop):
|
| | | '''特殊掉落 (私有特殊掉落 + 击杀次数特殊掉落), 支持摸怪
|
| | | @return: None
|
| | | @return: [[ownerPlayer, itemID, isBind, 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
|
| | |
|
| | | # 私有掉落
|
| | | fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3)
|
| | |
| | | npcID = curNPC.GetNPCID()
|
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | mapID = FBCommon.GetRecordMapID(mapID)
|
| | | isGameBoss = ChConfig.IsGameBoss(curNPC)
|
| | | if isGameBoss:
|
| | | GameWorld.Log("NPC开始掉落: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID())
|
| | | if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
|
| | | return
|
| | | ipyDrop = GetNPCDropIpyData(npcID)
|
| | | if not ipyDrop:
|
| | | if isGameBoss:
|
| | | curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
|
| | | GameWorld.ErrLog("取不到NPC掉落信息!npcID=%s,curWorldLV=%s" % (npcID, curWorldLV))
|
| | | return
|
| | |
|
| | | #if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
|
| | |
| | | dropIDList += [moneyID] * dropMoneyCnt
|
| | |
|
| | | specItemSign = "SpecItem"
|
| | | playerSpecDropList = self.__NPCSpecialDropItem(ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isBind, isDropInItemPack], ...] 私有特殊掉落 + 击杀次数特殊掉落
|
| | | playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isBind, 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())
|
| | |
|
| | | gameMap = GameWorld.GetMap()
|
| | | dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # 以NPC为中心点开始掉落
|
| | |
| | | ownerType, ownerID = hurtType, hurtID
|
| | | itemCnt = moneyValue if itemID == moneyID else 1
|
| | | isBind = dropIDBindDict.get(itemID, 1)
|
| | | |
| | | |
| | | curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, isBind)
|
| | | if not curItem:
|
| | | continue
|
| | | |
| | | if mapID == ChConfig.Def_FBMapID_GatherSoul:#聚魂副本特殊处理
|
| | | GameLogic_GatherSoul.KillGatherSoulNPCDropAward(itemID, itemCnt, isBind)
|
| | | dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem)
|
| | | self.SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
|
| | | curItem.Clear()
|
| | | continue
|
| | |
|
| | | if isDropInItemPack:
|
| | |
| | | if ItemControler.DoLogic_PutItemInPack(ownerPlayer, curItem, True, True,
|
| | | event=["NPCDrop", False, {"npcID":npcID}]):
|
| | | #通知客户端
|
| | | vItemDrop = ChPyNetSendPack.tagMCVirtualItemDrop()
|
| | | vItemDrop.ItemTypeID = itemID
|
| | | vItemDrop.PosX = resultX
|
| | | vItemDrop.PosY = resultY
|
| | | vItemDrop.UserData = dropItemDataStr
|
| | | vItemDrop.UserDataLen = len(vItemDrop.UserData)
|
| | | NetPackCommon.SendFakePack(ownerPlayer, vItemDrop)
|
| | | self.SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
|
| | | |
| | | else:
|
| | | self.__MapCreateItem(curItem, resultX, resultY, ownerType, ownerID)
|
| | | return
|
| | |
|
| | | def SendVirtualItemDrop(self, player, itemID, posX, posY, userDataStr):
|
| | | #通知客户端
|
| | | vItemDrop = ChPyNetSendPack.tagMCVirtualItemDrop()
|
| | | vItemDrop.ItemTypeID = itemID
|
| | | vItemDrop.PosX = posX
|
| | | vItemDrop.PosY = posY
|
| | | vItemDrop.UserData = userDataStr
|
| | | vItemDrop.UserDataLen = len(vItemDrop.UserData)
|
| | | NetPackCommon.SendFakePack(player, vItemDrop)
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | | ## NPC被杀死逻辑处理
|
| | | # @param self 类实例
|
| | |
| | | # @remarks 设置对象奖励
|
| | | def __GiveObjPrize(self):
|
| | | curNPC = self.__Instance
|
| | | objID = curNPC.GetID()
|
| | | #objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx()
|
| | | self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家
|
| | |
|
| | | self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo()
|
| | | #isLog = self.__GetIsLog()
|
| | | #if isLog:
|
| | | # GameWorld.Log("__GiveObjPrize npcID=%s,hurtType=%s,hurtID=%s,allKillPlayer=%s,curTeam=%s" |
| | | # % (npcID, hurtType, hurtID, self.__AllKillerDict.keys(), curTeam.GetTeamID() if curTeam else None))
|
| | | |
| | | # 归属队伍时,有击杀次数限制的NPC特殊处理
|
| | | if hurtType == ChConfig.Def_NPCHurtTypeTeam and curTeam:
|
| | | if ChConfig.IsGameBoss(curNPC) and GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_MaxHurt:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog("击杀boss有次数限制的NPC,队伍人数=%s" % (curTeam.GetMemberCount()))
|
| | | memInfoList = []
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" i=%s,队员不存在!" % i)
|
| | | memInfoList.append(None)
|
| | | continue
|
| | | findBuff = SkillCommon.FindBuffByID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]
|
| | | if not findBuff:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" i=%s,找不到归属buff!" % i, curTeamPlayer.GetPlayerID())
|
| | | memInfoList.append([curTeamPlayer.GetPlayerID(), "Not DropOwnerBuff"])
|
| | | continue
|
| | | #同一张地图可能有多个boss,该队伍可能同时在打多个boss,且都获得归属,所以需判断归属的buff所对应的NPC实例ID
|
| | | if findBuff.GetOwnerType() != IPY_GameWorld.gotNPC or findBuff.GetOwnerID() != objID:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" i=%s,不同归属bossBuff,不能设置归属!objID=%s,curBuffOwnerID=%s" |
| | | # % (i, objID, findBuff.GetOwnerID()), curTeamPlayer.GetPlayerID())
|
| | | #GameWorld.DebugLog("不同归属bossbuff,不能设置归属!objID=%s,curBuffOwnerID=%s" |
| | | # % (objID, findBuff.GetOwnerID()), curTeamPlayer.GetPlayerID())
|
| | | memInfoList.append([curTeamPlayer.GetPlayerID(), {"OwnerType":findBuff.GetOwnerType(), "OwnerID":findBuff.GetOwnerID()}])
|
| | | continue
|
| | | playerID = curTeamPlayer.GetPlayerID()
|
| | | if playerID not in self.__AllKillerDict:
|
| | | self.__AllKillerDict[playerID] = curTeamPlayer
|
| | | memInfoList.append([playerID, 1])
|
| | | |
| | | curTeam = None
|
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0
|
| | | |
| | | if not self.__AllKillerDict:
|
| | | GameWorld.ErrLog("归属异常队伍信息: objID=%s,npcID=%s, %s" % (objID, npcID, memInfoList))
|
| | | |
| | | isGameBoss = ChConfig.IsGameBoss(curNPC)
|
| | | self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo(isGameBoss)
|
| | | self.__OwnerHurtType, self.__OwnerHurtID = hurtType, hurtID
|
| | | if isGameBoss:
|
| | | GameWorld.Log("__GiveObjPrize npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
|
| | | |
| | | #最后一击处理
|
| | | self.__DoLastTimeHurtLogic()
|
| | |
|
| | |
| | | elif curTeam != None:
|
| | | self.__KilledByTeamSetPrize(curTeam, hurtType, hurtID)
|
| | |
|
| | | else:
|
| | | GameWorld.ErrLog("NPC归属异常:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
|
| | | #被仙盟杀死
|
| | | elif hurtType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | self.__KilledByFamilySetPrize(hurtType, hurtID)
|
| | |
|
| | | elif isGameBoss:
|
| | | GameWorld.ErrLog("NPC归属异常:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
|
| | | |
| | | if isGameBoss:
|
| | | dataDict = {"objID":curNPC.GetID(), "bossID":npcID, "mapID":GameWorld.GetMap().GetMapID(),
|
| | | "lineID":GameWorld.GetGameWorld().GetLineID(), "teamID":curTeam.GetTeamID() if curTeam else 0,
|
| | | "killerID":self.__AllKillerDict.keys(), "hurtType":hurtType,"hurtID":hurtID}
|
| | | DataRecordPack.SendEventPack("KillBossRecord", dataDict)
|
| | | |
| | | if OnNPCDie:
|
| | | OnNPCDie(curNPC, hurtType, hurtID)
|
| | |
|
| | |
| | | ## NPC死亡, 分享经验逻辑
|
| | | # @param self 类实例
|
| | | # @return 返回击杀玩家信息元组, (玩家列表实例,队伍实例,归属类型,归属ID)
|
| | | def __FindNPCKillerInfo(self):
|
| | | def __FindNPCKillerInfo(self, isGameBoss):
|
| | | curNPC = self.__Instance
|
| | | npcID = curNPC.GetNPCID()
|
| | | objID = curNPC.GetID()
|
| | | key = (GameWorld.GetGameWorld().GetLineID(), objID, npcID)
|
| | | if key in PyGameData.g_npcKillerInfo:
|
| | | killerDict, killTeam, hurtType, hurtID = PyGameData.g_npcKillerInfo.pop(key)
|
| | | teamID = killTeam.GetTeamID() if killTeam else 0
|
| | | GameWorld.Log("NPC被击杀,归属信息: key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s" |
| | | % (key, killerDict.keys(), teamID, hurtType, hurtID))
|
| | | return killerDict, killTeam, hurtType, hurtID
|
| | |
|
| | | hurtType = 0
|
| | | hurtID = 0
|
| | |
| | |
|
| | | #isLog = self.__GetIsLog()
|
| | | dropOwnerType = GetDropOwnerType(curNPC)
|
| | | #GameWorld.DebugLog("NPC击杀者信息...npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))
|
| | | |
| | | if isGameBoss:
|
| | | GameWorld.Log("NPC被击杀, key=%s,dropOwnerType=%s" % (key, dropOwnerType))
|
| | | |
| | | # 最大伤血 - 伤血可能被重置
|
| | | if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
|
| | | npcHurtList = curNPC.GetPlayerHurtList()
|
| | | npcHurtList.Sort()
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog("NPC被击杀,npcID=%s,dropOwnerType=%s,hurtCount=%s" % (npcID, dropOwnerType, npcHurtList.GetHurtCount()))
|
| | | if isGameBoss:
|
| | | GameWorld.Log("hurtCount=%s" % (npcHurtList.GetHurtCount()))
|
| | | for i in xrange(npcHurtList.GetHurtCount()):
|
| | | #获得最大伤血对象
|
| | | maxHurtObj = npcHurtList.GetHurtAt(i)
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" i=%s,hurtValueType=%s,valueID=%s" % (i, maxHurtObj.GetValueType(), maxHurtObj.GetValueID()))
|
| | | curPlayer, curTeam = self.__GetTagByHurtObj(maxHurtObj)
|
| | | if isGameBoss:
|
| | | GameWorld.Log("hurtIndex=%s,hurtValueType=%s,valueID=%s" % (i, maxHurtObj.GetValueType(), maxHurtObj.GetValueID()))
|
| | | curPlayer, curTeam = self.__GetTagByHurtObj(maxHurtObj, isLog=isGameBoss)
|
| | | #当前伤血对象超出指定范围或已经死亡
|
| | | if curPlayer == None and curTeam == None:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" 当前伤血对象超出指定范围或已经死亡")
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 当前伤血对象超出指定范围或已经死亡")
|
| | | continue
|
| | |
|
| | | if curPlayer:
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID not in killerDict:
|
| | | killerDict[playerID] = curPlayer
|
| | | GameWorld.Log(" 归属最大伤血玩家: npcID=%s,dropOwnerType=%s,playerID=%s" % (npcID, dropOwnerType, playerID))
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 归属最大伤血玩家: npcID=%s,dropOwnerType=%s,playerID=%s" % (npcID, dropOwnerType, playerID))
|
| | | return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, playerID
|
| | |
|
| | | if curTeam:
|
| | | killTeam = curTeam
|
| | | GameWorld.Log(" 归属最大伤血队伍: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID()))
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 归属最大伤血队伍: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID()))
|
| | | return killerDict, curTeam, ChConfig.Def_NPCHurtTypeTeam, curTeam.GetTeamID()
|
| | | # 最大伤血玩家 - 伤血不会被重置
|
| | | elif dropOwnerType == ChConfig.DropOwnerType_MaxHurtPlayer:
|
| | |
| | | if self.__LastHurtPlayer:
|
| | | lastHurtPlayerID = self.__LastHurtPlayer.GetPlayerID()
|
| | | teamID = self.__LastHurtPlayer.GetTeamID()
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" 归属最后一击,npcID=%s,lastHurtPlayerID=%s,teamID=%s" % (npcID, lastHurtPlayerID, teamID))
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 归属最后一击,npcID=%s,lastHurtPlayerID=%s,teamID=%s" % (npcID, lastHurtPlayerID, teamID))
|
| | | if teamID:
|
| | | killTeam = GameWorld.GetTeamManager().FindTeam(teamID)
|
| | | if not killTeam and lastHurtPlayerID not in killerDict:
|
| | |
| | |
|
| | | if dropOwnerType == ChConfig.DropOwnerType_All:
|
| | | hurtType = ChConfig.Def_NPCHurtTypeAll
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" 无归属...npcID=%s" % npcID)
|
| | | #GameWorld.DebugLog(" 无归属...")
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 无归属...npcID=%s" % npcID)
|
| | |
|
| | | elif dropOwnerType == ChConfig.DropOwnerType_Faction:
|
| | | #阵营归属
|
| | |
| | | if protectFaction > 0:
|
| | | hurtType = ChConfig.Def_NPCHurtTypeFaction
|
| | | hurtID = protectFaction
|
| | | #GameWorld.DebugLog(" 阵营归属...factionID=%s" % protectFaction)
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 阵营归属...factionID=%s" % protectFaction)
|
| | |
|
| | | if hurtType == 0:
|
| | | #归属队伍
|
| | | if killTeam:
|
| | | hurtType = ChConfig.Def_NPCHurtTypeTeam
|
| | | hurtID = killTeam.GetTeamID()
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" 归属默认队伍, npcID=%s,teamID=%s" % (npcID, hurtID))
|
| | | #GameWorld.DebugLog(" 归属默认队伍, teamID=%s" % hurtID)
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 归属默认队伍, npcID=%s,teamID=%s" % (npcID, hurtID))
|
| | | #伤血归属玩家
|
| | | elif killerDict:
|
| | | hurtType = ChConfig.Def_NPCHurtTypePlayer
|
| | | hurtID = killerDict.keys()[0]
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog(" 归属默认玩家, npcID=%s,playerID=%s" % (npcID, hurtID))
|
| | | #GameWorld.DebugLog(" 归属默认玩家, playerID=%s" % hurtID)
|
| | | if isGameBoss:
|
| | | GameWorld.Log(" 归属默认玩家, npcID=%s,playerID=%s" % (npcID, hurtID))
|
| | |
|
| | | return killerDict, killTeam, hurtType, hurtID
|
| | |
|
| | |
| | | # @param maxHurtObj 最大伤血对象
|
| | | # @return 返回值, 伤血对象
|
| | | # @remarks 获得伤血对象,支持抢怪
|
| | | def __GetTagByHurtObj(self, maxHurtObj, isLog=True):
|
| | | def __GetTagByHurtObj(self, maxHurtObj, isCheckRefreshArea=False, isLog=False):
|
| | | #获得死亡的NPC
|
| | | curNPC = self.__Instance
|
| | | npcID = curNPC.GetNPCID()
|
| | | # 伤害的obj类型元组(玩家, 队伍)
|
| | | hurtObjTuple = (None, None)
|
| | | #isLog = self.__GetIsLog() and isLog
|
| | | if maxHurtObj == None:
|
| | | GameWorld.DebugLog("伤血对象错误,npcID=%s" % (curNPC.GetNPCID()))
|
| | | return hurtObjTuple
|
| | |
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | #最大伤血类型
|
| | | maxHurtValueType = maxHurtObj.GetValueType()
|
| | |
|
| | |
| | | curPlayer = GameWorld.GetObj(maxHurtObj.GetValueID(), IPY_GameWorld.gotPlayer)
|
| | |
|
| | | if curPlayer == None:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog("无法找到玩家,npcID=%s" % (curNPC.GetNPCID()))
|
| | | if isLog:
|
| | | GameWorld.Log("找不到该目标伤血玩家: npcID=%s,playerID=%s" % (npcID, maxHurtObj.GetValueID()))
|
| | | return hurtObjTuple
|
| | |
|
| | | #支持抢怪,个人杀死,但自己死亡,不算
|
| | | if curPlayer.GetHP() <= 0 :
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog("玩家已死亡!playerID=%s" % curPlayer.GetPlayerID())
|
| | | if curPlayer.GetHP() <= 0 or curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | if isLog:
|
| | | GameWorld.Log("该目标伤血玩家已死亡: npcID=%s,playerID=%s" % (npcID, maxHurtObj.GetValueID()))
|
| | | return hurtObjTuple
|
| | |
|
| | | if isCheckRefreshArea:
|
| | | if not self.GetIsInRefreshPoint(curPlayer.GetPosX(), curPlayer.GetPosY(), refreshPoint):
|
| | | if isLog:
|
| | | GameWorld.Log("该目标伤血玩家不在NPC区域内: npcID=%s,playerID=%s,pos(%s,%s)" |
| | | % (npcID, maxHurtObj.GetValueID(), curPlayer.GetPosX(), curPlayer.GetPosY()))
|
| | | return hurtObjTuple
|
| | | #如果玩家已经超出指定距离,不加经验
|
| | | if GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),
|
| | | elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),
|
| | | curPlayer.GetPosX(), curPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog("玩家已经超出指定距离,npcPos(%s,%s),playerPos(%s,%s)" % (curNPC.GetPosX(), curNPC.GetPosY(), curPlayer.GetPosX(), curPlayer.GetPosY()))
|
| | | if isLog:
|
| | | GameWorld.Log("该目标伤血玩家超出指定距离: npcID=%s,playerID=%s,npcPos(%s,%s),playerPos(%s,%s)" |
| | | % (npcID, maxHurtObj.GetValueID(), curNPC.GetPosX(), curNPC.GetPosY(), curPlayer.GetPosX(), curPlayer.GetPosY()))
|
| | | return hurtObjTuple
|
| | |
|
| | | #正常返回
|
| | |
| | | #获得当前队伍
|
| | | teamID = maxHurtObj.GetValueID()
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(teamID)
|
| | | if isLog:
|
| | | GameWorld.Log("目标伤血队伍: npcID=%s,teamID=%s" % (npcID, teamID))
|
| | | if curTeam == None:
|
| | | #if isLog:
|
| | | # GameWorld.Log("该队伍异常不存在!npcID=%s,teamID=%s" % (curNPC.GetNPCID(), teamID))
|
| | | if isLog:
|
| | | GameWorld.Log("找不到目标队伍, teamID=%s" % (teamID))
|
| | | return hurtObjTuple
|
| | |
|
| | | #组队成员检查
|
| | | playerlist = PlayerControl.GetAreaTeamMember(curTeam, curNPC.GetPosX(), curNPC.GetPosY())
|
| | | if len(playerlist) == 0 :
|
| | | #所有队伍成员,均超过获得奖励距离,或者全部死亡
|
| | | if isLog:
|
| | | GameWorld.Log("队伍成员数: GetMemberCount=%s" % (curTeam.GetMemberCount())) |
| | | #遍历队伍,半径为一屏半的距离内的所有队伍/团队成员,可以获得经验
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | if isLog:
|
| | | GameWorld.Log(" i=%s, 无该队员!" % (i))
|
| | | continue
|
| | | |
| | | if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | if isLog:
|
| | | GameWorld.Log(" i=%s, 队员已死亡!memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
|
| | | continue
|
| | | |
| | | if isCheckRefreshArea:
|
| | | if not self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
|
| | | if isLog:
|
| | | GameWorld.Log(" i=%s, 队员不在NPC区域内!memPlayerID=%s,pos(%s,%s)" |
| | | % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY()))
|
| | | continue
|
| | | elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(),
|
| | | curTeamPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:
|
| | | if isLog:
|
| | | GameWorld.Log(" i=%s, 队员超出指定距离!memPlayerID=%s,npcPos(%s,%s),playerPos(%s,%s)" |
| | | % (i, curTeamPlayer.GetPlayerID(), curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY()))
|
| | | continue
|
| | | |
| | | hurtObjTuple = (None, curTeam)
|
| | | return hurtObjTuple
|
| | |
|
| | | #正常返回
|
| | | hurtObjTuple = (None, curTeam)
|
| | | return hurtObjTuple
|
| | |
|
| | | #最大伤血对象是NPC,那么一定不给经验(玩家的召唤兽伤血算玩家)
|
| | | elif maxHurtValueType == ChConfig.Def_NPCHurtTypeNPC:
|
| | | #if isLog:
|
| | | # GameWorld.DebugLog("最大伤血对象是NPC...valueID=%s" % maxHurtObj.GetValueID())
|
| | | return hurtObjTuple
|
| | |
|
| | | #异常信息,添加伤血类型错误
|
| | | else:
|
| | | pass
|
| | | #if isLog:
|
| | | # GameWorld.Log("异常信息,伤血类型错误 maxHurtValueType = %s" % (maxHurtValueType))
|
| | |
|
| | | return hurtObjTuple
|
| | |
|
| | |
| | | self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)
|
| | | #GameWorld.Log("队伍杀死怪物奖励,逻辑成功结束")
|
| | | return
|
| | |
|
| | | |
| | | def __KilledByFamilySetPrize(self, hurtType, hurtID):
|
| | | ## 仙盟杀死NPC奖励逻辑
|
| | | curNPC = self.__Instance
|
| | | |
| | | maxLV = 0
|
| | | dropPlayer = None
|
| | | ownerPlayerList = []
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(copyPlayerMgr.GetPlayerCount()):
|
| | | player = copyPlayerMgr.GetPlayerByIndex(index)
|
| | | if not player:
|
| | | continue
|
| | | |
| | | if player.GetFamilyID() != hurtID or not self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):
|
| | | continue
|
| | | |
| | | curPlayerLV = player.GetLV()
|
| | | if maxLV < curPlayerLV:
|
| | | maxLV = curPlayerLV
|
| | | dropPlayer = player
|
| | | ownerPlayerList.append(player)
|
| | | |
| | | if not ownerPlayerList:
|
| | | GameWorld.Log("奖励归属仙盟,但是不存在可获得该奖励的成员!npcID=%s,hurtType=%s,hurtID=%s" |
| | | % (curNPC.GetNPCID(), hurtType, hurtID))
|
| | | |
| | | # 因为仙盟归属boss归属伤血第一的仙盟,仙盟伤血有保护,可能存在伤血第一仙盟在boss死亡的时候都不在
|
| | | # 此时掉落计算玩家算最后一击玩家,归属还是算伤血第一仙盟的
|
| | | if not dropPlayer:
|
| | | dropPlayer = self.__LastHurtPlayer
|
| | | |
| | | if not dropPlayer:
|
| | | GameWorld.ErrLog("奖励归属仙盟,找不到掉落玩家!npcID=%s,hurtType=%s,hurtID=%s" |
| | | % (curNPC.GetNPCID(), hurtType, hurtID))
|
| | | return
|
| | | |
| | | # 赶时间,先简单处理直接取最大等级的,之后可按实际情况来
|
| | | if not self.__LastHurtPlayer:
|
| | | self.__LastHurtPlayer = dropPlayer
|
| | | if not self.__MaxHurtPlayer:
|
| | | self.__MaxHurtPlayer = dropPlayer
|
| | | if not self.__Killer:
|
| | | self.__Killer = dropPlayer
|
| | | maxHurtID = dropPlayer.GetPlayerID()
|
| | | |
| | | for curPlayer in ownerPlayerList:
|
| | | self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, False)
|
| | | |
| | | #调用物品掉落
|
| | | self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)
|
| | | return
|
| | | |
| | | ## 队伍或自己击杀NPC扩展功能
|
| | | # @param curPlayer
|
| | | # @return None
|
| | |
| | | npcID = curNPC.GetNPCID()
|
| | | defObjType = curNPC.GetGameObjType()
|
| | | mapFBType = GameWorld.GetMap().GetMapFBType()
|
| | | mapID = GameWorld.GetMap().GetMapID()
|
| | | mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
|
| | | playerID = curPlayer.GetPlayerID()
|
| | |
|
| | | # 如果是NPC
|
| | |
| | | #掉落归属
|
| | | if mapFBType != IPY_GameWorld.fbtNull:
|
| | | FBLogic.DoFB_DropOwner(curPlayer , curNPC)
|
| | | |
| | | else:
|
| | | if curNPC.GetLV()>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):
|
| | | PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC)
|
| | | |
| | | killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
|
| | | limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
|
| | | if limitIndex != None:
|
| | |
| | | dataDict = {"objID":curNPC.GetID(), "bossID":npcID, "touchCnt":newCnt,
|
| | | "AccID":curPlayer.GetAccID(), "PlayerID":curPlayer.GetPlayerID()}
|
| | | DataRecordPack.SendEventPack("AddKillBossCnt", dataDict, curPlayer)
|
| | | |
| | | if limitIndex == 0:
|
| | | # 世界BOSS击杀成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillWorldBoss, 1)
|
| | | # 每日活动
|
| | | PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS)
|
| | | PlayerMagicWeapon.SetMWPrivilegeData(curPlayer, ChConfig.MWPrivilege_KillBossAddAttr, 1, True)
|
| | | PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_WorldBOSS, 1)
|
| | | PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1)
|
| | | elif limitIndex == 1: #BOSS之家
|
| | | # BOSS之家BOSS击杀成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
|
| | | # 每日活动
|
| | | PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
|
| | | PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)
|
| | | PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)
|
| | | #击杀特定NPC成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID])
|
| | | if ChConfig.IsGameBoss(curNPC) and mapID == ChConfig.Def_FBMapID_BossHome:
|
| | | #BOSS之家
|
| | | # BOSS之家BOSS击杀成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
|
| | | # 每日活动
|
| | | PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
|
| | | PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)
|
| | | PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)
|
| | | |
| | | |
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | #不是普通NPC
|
| | | elif npcObjType != IPY_GameWorld.gnotNormal:
|
| | | return
|
| | | |
| | | npcID = curNPC.GetNPCID()
|
| | | #GameWorld.DebugLog("__MissionOnKillNPC isFeel=%s" % (isFeel), curPlayer.GetPlayerID())
|
| | | killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
|
| | | limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, curNPC.GetNPCID())
|
| | | limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
|
| | | isWorldBoos = limitIndex == 0
|
| | | if isFeel:
|
| | | #击杀NPC触发摸怪任务事件
|
| | |
| | | EventShell.EventRespons_OnKillById(curPlayer, curNPC)
|
| | | if isWorldBoos:
|
| | | EventShell.EventRespons_KillWorldBoss(curPlayer)
|
| | | |
| | | #击杀特定NPC成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID])
|
| | | return
|
| | |
|
| | | def __GetIsLog(self):
|
| | | ## 测试查错日志,临时用
|
| | | ## 相关bug: 仙界秘境无经验、boss无掉落
|
| | | return False
|
| | | return ChConfig.IsGameBoss(self.__Instance)
|
| | | #return GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_BZZD or ChConfig.IsGameBoss(self.__Instance)
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | return max(value / pow(10, nlen), 1)
|
| | |
|
| | |
|
| | | Def_CollNPCCfg_Len = 9
|
| | | Def_CollNPCCfg_Len = 10
|
| | | (
|
| | | Def_CollNPCCfg_CanTogether, # 是否允许同时采集
|
| | | Def_CollNPCCfg_SysMsgMark, # 不可同时采集提示
|
| | |
| | | Def_CollNPCCfg_ZhenQi, # 获得的真气/魔魂
|
| | | Def_CollNPCCfg_GiveItemModeID, # 获得的物品信息模板编号
|
| | | Def_CollNPCCfg_NotCostItemNotify, # 消耗品不足提示
|
| | | Def_CollNPCCfg_LimitSysMsgMark, #采集上限提示
|
| | | ) = range(Def_CollNPCCfg_Len)
|
| | |
|
| | |
|
| | |
| | | GameWorld.DebugLog(" maxTime=%s,todayTime=%s" % (limitMaxTime, todayCollTime))
|
| | |
|
| | | if limitMaxTime > 0 and todayCollTime >= limitMaxTime:
|
| | | PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_807125")
|
| | | |
| | | PlayerControl.NotifyCode(curPlayer, collectNPCInfo[Def_CollNPCCfg_LimitSysMsgMark], [limitMaxTime])
|
| | | return True
|
| | |
|
| | | # 采集消耗
|
| | |
| | |
|
| | | PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, IPY_GameWorld.pstMissionCollecting, \
|
| | | prepareID=curNPC.GetID())
|
| | | |
| | | FBLogic.OnBeginCollect(curPlayer, curNPC)
|
| | | ##添加这个NPC的伤血列表,用于判断可否同时采集,改为字典判断
|
| | | AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1)
|
| | | return
|
| | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
|
| | | SyncCollNPCTime(curPlayer, npcIDList=[npcID])
|
| | | GameWorld.DebugLog(" 增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime))
|
| | | |
| | | #采集成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, successCnt, [npcID])
|
| | | SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
|
| | | #DataRecordPack.DR_CollectNPCOK(curPlayer, npcID, addMoney, addExp, addZhenQi, giveItemInfoList)
|
| | | return True
|
| | |
| | | GameWorld.DebugLog(" 最终可得到物品giveItemInfoList=%s" % giveItemInfoList)
|
| | |
|
| | | syncItemInfoList = [] # 同步的采集到的物品信息列表
|
| | | for itemType, itemID, itemCnt, isBind in giveItemInfoList:
|
| | | for itemID, itemCnt, isBind in giveItemInfoList:
|
| | | if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
|
| | | break
|
| | |
|
| | | isBind = setBind or isBind
|
| | | if itemType == 0:
|
| | | getItemObj = ItemControler.GetOutPutItemObj(itemID)
|
| | | elif itemType == 1:
|
| | | itemDictData = ItemControler.GetAppointItemDictData(itemID, isBind)
|
| | | getItemObj = ItemControler.GetItemByData(itemDictData)
|
| | | elif itemType == 2:
|
| | | quality = ItemCommon.GetRandEquipQualityByTable(itemID, "CollectEquipRandQuality")
|
| | | if quality == 0:
|
| | | isBroadcast = False
|
| | | getItemObj = ItemCommon.RandNormalEquip(curPlayer, itemID, isBind, "CollectNormalEquip")
|
| | | else:
|
| | | getItemObj, isBroadcast = ItemCommon.RandGreateEquip(curPlayer, itemID, isBind, "CollectGreateEquip", quality)
|
| | | if getItemObj == None:
|
| | | continue
|
| | | |
| | | itemID = getItemObj.GetItemTypeID()
|
| | | |
| | | getItemObj = ItemControler.GetOutPutItemObj(itemID)
|
| | | # elif itemType == 1:
|
| | | # itemDictData = ItemControler.GetAppointItemDictData(itemID, isBind)
|
| | | # getItemObj = ItemControler.GetItemByData(itemDictData)
|
| | | # elif itemType == 2:
|
| | | # quality = ItemCommon.GetRandEquipQualityByTable(itemID, "CollectEquipRandQuality")
|
| | | # if quality == 0:
|
| | | # isBroadcast = False
|
| | | # getItemObj = ItemCommon.RandNormalEquip(curPlayer, itemID, isBind, "CollectNormalEquip")
|
| | | # else:
|
| | | # getItemObj, isBroadcast = ItemCommon.RandGreateEquip(curPlayer, itemID, isBind, "CollectGreateEquip", quality)
|
| | | # if getItemObj == None:
|
| | | # continue
|
| | | # |
| | | # itemID = getItemObj.GetItemTypeID()
|
| | | userData = getItemObj.GetUserData()
|
| | | getItemObj.SetCount(itemCnt)
|
| | | getItemObj.SetIsBind(isBind)
|
| | | ItemCommon.NotifyItemDropByKill(curPlayer, getItemObj, npcID)
|
| | |
|
| | | SendGameServerGoodItemRecord(mapID, npcID, curPlayer.GetPlayerName(), curPlayer.GetPlayerID(), itemID)
|
| | | #SendGameServerGoodItemRecord(mapID, npcID, curPlayer.GetPlayerName(), curPlayer.GetPlayerID(), itemID)
|
| | | #可以放入背包
|
| | | if not ItemControler.DoLogic_PutItemInPack(curPlayer, getItemObj, True, True,
|
| | | event=["CollectNPC", False, {"npcID":npcID}]):
|
| | | break
|
| | | syncItemInfoList.append([itemType, itemID, itemCnt, isBind, userData])
|
| | | syncItemInfoList.append([itemID, itemCnt, isBind, userData])
|
| | | return syncItemInfoList
|
| | |
|
| | | ## 采集结果同步
|
| | | # @param None
|
| | | # @param None
|
| | | def SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, syncItemInfoList, collectNPCID=0):
|
| | | return #暂不同步
|
| | | if addExp <= 0 and addMoney <= 0 and addZhenQi <= 0 and not syncItemInfoList:
|
| | | return
|
| | |
|
| | |
| | | collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
|
| | | npcIDList = collectNPCIDTimeLimit.keys()
|
| | |
|
| | | if funcTypeList:
|
| | | collection = ChPyNetSendPack.tagMCFuncNPCCollectionCnt()
|
| | | for fType in funcTypeList:
|
| | | todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % fType)
|
| | | collection.Clear()
|
| | | collection.FuncType = fType
|
| | | collection.CollectionCnt = todayCollTime
|
| | | collection.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % fType)
|
| | | NetPackCommon.SendFakePack(curPlayer, collection)
|
| | | # if funcTypeList:
|
| | | # collection = ChPyNetSendPack.tagMCFuncNPCCollectionCnt()
|
| | | # for fType in funcTypeList:
|
| | | # todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % fType)
|
| | | # collection.Clear()
|
| | | # collection.FuncType = fType
|
| | | # collection.CollectionCnt = todayCollTime
|
| | | # collection.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % fType)
|
| | | # NetPackCommon.SendFakePack(curPlayer, collection)
|
| | |
|
| | | if npcIDList:
|
| | | npcIDCollInfo = ChPyNetSendPack.tagMCNPCIDCollectionCntInfo()
|
| | |
| | | NetPackCommon.SendFakePack(curPlayer, npcInfoPack)
|
| | | return
|
| | |
|
| | |
|
| | | ## 获取本地图NPC数量
|
| | | # @param queryNPCIDList:查询的NPCID列表
|
| | | # @param tick
|
| | | # @return {NPCID:cnt}
|
| | | def GetNPCCntInfo(queryNPCIDList, tick):
|
| | | npcCntDict = {}
|
| | |
|
| | | if not queryNPCIDList:
|
| | | return npcCntDict
|
| | | |
| | | gameNPCManager = GameWorld.GetNPCManager()
|
| | | GameWorld.DebugLog("GetNPCCntInfo...queryNPCIDList=%s" % (str(queryNPCIDList)))
|
| | |
|
| | | for index in xrange(gameNPCManager.GetNPCCount()):
|
| | | curNPC = gameNPCManager.GetNPCByIndex(index)
|
| | | curID = curNPC.GetID()
|
| | | if curID == 0:
|
| | | continue
|
| | | |
| | | curNPCID = curNPC.GetNPCID()
|
| | | |
| | | if curNPCID not in queryNPCIDList:
|
| | | continue
|
| | | if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
|
| | | continue
|
| | | npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
|
| | | |
| | | GameWorld.DebugLog(" npcCntDict=%s" % (str(npcCntDict)))
|
| | | return npcCntDict
|
| | |
|
| | | ## 同步地图NPC数量信息
|
| | | # @param curPlayer:采集玩家实例
|
| | | # @param mapID:
|
| | | # @param npcInfoDict:
|
| | | # @return None
|
| | | def SyncNPCCntInfo(curPlayer, mapID, npcCntDict):
|
| | | npcInfoPack = ChPyNetSendPack.tagMCNPCCntList()
|
| | | npcInfoPack.Clear()
|
| | | npcInfoPack.MapID = mapID
|
| | | npcInfoPack.NPCInfoList = []
|
| | |
|
| | | for npcid, npcCnt in npcCntDict.items():
|
| | | npcInfo = ChPyNetSendPack.tagMCNPCCntInfo()
|
| | | npcInfo.Clear()
|
| | | npcInfo.NPCID = npcid
|
| | | npcInfo.Cnt = npcCnt
|
| | | npcInfoPack.NPCInfoList.append(npcInfo)
|
| | | |
| | | npcInfoPack.NPCInfoCnt = len(npcInfoPack.NPCInfoList)
|
| | | NetPackCommon.SendFakePack(curPlayer, npcInfoPack)
|
| | | return
|
| | |
|
| | | def SendGameServerGoodItemRecord(mapID, npcID, playerName, playerID, itemID, equipInfo=[]):
|
| | | # @param equipInfo: [equipPlace, itemClassLV, itemColor, itemQuality, itemUserData]
|
| | | # GameWorld.DebugLog("检查物品是否发送GameServer: mapID=%s, npcID=%s, playerName=%s, itemID=%s"
|