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
@@ -72,6 +71,7 @@
import IpyGameDataPY
import PlayerGubao
import PlayerState
import TurnAttack
import PyGameData
import PlayerTeam
import NPCHurtMgr
@@ -150,7 +150,7 @@
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最终固定伤害加成, 普攻也有效果
@@ -2262,7 +2262,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)
@@ -2323,9 +2325,20 @@
                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)
    tfMgr.delNPCGUID(objID)
    return
def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):
@@ -2383,7 +2396,6 @@
                    "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:
@@ -2741,10 +2753,6 @@
            GameWorld.Log("curNPC = %s 查找对象, 获得对象实例失败" % (curNPC.GetNPCID()))
            return False
        
        #守卫攻击镖车,仇恨特殊处理
        if self.__GuaedAttackTruck(seeObjDetail , tick):
            return True
        #小怪不可行进通道就当作看不见
        if not AttackCommon.CanAttackByPath(curNPC, seeObjDetail):
            #GameWorld.DebugLog("有障碍  看见也不加仇恨")
@@ -2764,37 +2772,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
@@ -3664,41 +3641,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)
    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.GetBindMissionID():
        #    #GameWorld.DebugLog("有绑定任务ID的,前端自己展示NPC秀!mapID=%s,npcID=%s" % (mapID, npcID))
        #    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
    
    #---------------------------------------------------------------------
@@ -3755,48 +3711,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 类实例
@@ -3850,12 +3764,61 @@
    #  @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({
                                 ShareDefine.Def_Effect_Atk:500000000,
                                 ShareDefine.Def_Effect_Def:50000000,
                                 ShareDefine.Def_Effect_MaxHP:3000000000,
                                 })
        else:
            npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
            if not npcDataEx:
                return
            heroAttrDict.update({
                                 ShareDefine.Def_Effect_Atk:npcDataEx.GetAtk(),
                                 ShareDefine.Def_Effect_Def:npcDataEx.GetDef(),
                                 ShareDefine.Def_Effect_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(ShareDefine.Def_Effect_Atk, 1))
        curNPC.SetMaxAtk(heroAttrDict.get(ShareDefine.Def_Effect_Atk, 1))
        curNPC.SetDef(heroAttrDict.get(ShareDefine.Def_Effect_Def, 1))
        GameObj.SetMaxHP(curNPC, heroAttrDict.get(ShareDefine.Def_Effect_MaxHP, 1))
        #GameObj.SetMissRate(curNPC, npcDataEx.GetMissRate())
        #GameObj.SetMissDefRate(curNPC, npcDataEx.GetMissDefRate())
        #GameObj.SetSuperHitRate(curNPC, npcDataEx.GetSuperHitRate())
        #GameObj.SetSuperHitRateReduce(curNPC, npcDataEx.GetSuperHitRateReduce())
        #GameObj.SetFaintRate(curNPC, npcDataEx.GetFaintRate())
        #GameObj.SetFaintDefRate(curNPC, npcDataEx.GetFaintDefRate())
        #GameObj.SetComboRate(curNPC, npcDataEx.GetComboRate())
        #GameObj.SetComboDefRate(curNPC, npcDataEx.GetComboDefRate())
        #GameObj.SetAtkBackRate(curNPC, npcDataEx.GetAtkBackRate())
        #GameObj.SetAtkBackDefRate(curNPC, npcDataEx.GetAtkBackDefRate())
        #GameObj.SetSuckHPPer(curNPC, npcDataEx.GetSuckHPPer())
        #GameObj.SetSuckHPDefPer(curNPC, npcDataEx.GetSuckHPDefPer())
        return
    ## 刷新NPC属性
    #  @param self 类实例
    #  @param canSyncClient 是否通知客户端刷新信息(宠物)
@@ -4039,11 +4002,6 @@
        curNPC = self.__Instance
        npcID = curNPC.GetNPCID()
        #######################特殊NPC的处理
        #=====================================================================================================
        # if curNPC.GetGameNPCObjType() == IPY_GameWorld.gnotTruck:
        #    #如果是骠车死亡, 调用骠车死亡逻辑
        #    PlayerTruck.DoTruckDestroy(curNPC)
        #=====================================================================================================
        
        #boss伤血排行榜击杀逻辑
        #BossHurtMng.BossOnKilled(curNPC)
@@ -4077,14 +4035,7 @@
        #    #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
@@ -4332,10 +4283,6 @@
        curNPC_GameNPCObjType = curNPC.GetGameNPCObjType()
        #---特殊死亡逻辑---
        
        #镖车不能通知死亡
        if curNPC_GameNPCObjType == IPY_GameWorld.gnotTruck:
            return
        #宠物死亡调用独立接口
        if curNPC_GameNPCObjType == IPY_GameWorld.gnotPet:
            PetControl.SetPetDead(curNPC)
@@ -4350,52 +4297,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 类实例
@@ -5017,7 +4919,7 @@
                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)
@@ -5044,19 +4946,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
@@ -6272,13 +6161,7 @@
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())
    GameObj.NotifyObjInfoRefresh(curNPC, IPY_GameWorld.CDBPlayerRefresh_Speed, speed)
    return
def UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount=0):