ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -40,28 +40,22 @@
import DataRecordPack
import NetPackCommon
import FBCommon
import PlayerActivity
import PlayerSuccess
import PlayerPrestigeSys
import GY_Query_BossFirstKill
import FormulaControl
import PlayerBossReborn
import PlayerCrossYaomoBoss
import PlayerActCollectWords
import PlayerActGarbageSorting
import PlayerActBossTrial
import PlayerTongTianLing
import CrossPlayerData
import PlayerFeastWish
import PlayerFeastTravel
import PlayerGoldInvest
import PlayerWeekParty
import NPCRealmRefresh
import PlayerActLogin
import PlayerActTask
import PlayerZhanling
#import PlayerZhanling
import IpyGameDataPY
import PlayerGubao
import PlayerState
import TurnAttack
import PyGameData
@@ -110,12 +104,6 @@
    # NPC等级
    if hasattr(curNPC, "GetCurLV"):
        return max(curNPC.GetCurLV(), curNPC.GetLV())
    if curPlayer and PlayerControl.GetRealmDifficulty(curPlayer):
        npcID = curNPC.GetNPCID()
        needRealmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer))
        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, needRealmLV)
        if realmNPCIpyData:
            return realmNPCIpyData.GetLV()
    return curNPC.GetLV()
def GetNPCDataPy(npcID):
@@ -796,115 +784,6 @@
        
    return
#// B4 0F 回收私有专属木桩怪 #tagCMRecyclePriWoodPile
#
#struct    tagCMRecyclePriWoodPile
#{
#    tagHead        Head;
#    DWORD        ObjID;
#};
def OnRecyclePriWoodPile(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    objID = clientData.ObjID
    curNPC = GameWorld.FindNPCByID(objID)
    if not curNPC:
        return
    if curNPC.GetType() not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
        return
    summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
    if curPlayer.GetPlayerID() != summonPlayerID:
        #GameWorld.DebugLog("非玩家私有木桩...")
        return
    SetDeadEx(curNPC)
    return
#// B4 0C 召唤私有专属木桩怪 #tagCMSummonPriWoodPile
#
#struct    tagCMSummonPriWoodPile
#{
#    tagHead        Head;
#    DWORD        NPCID;
#    BYTE        Count;    //默认1个,最多5个
#    DWORD        HP;    //默认0取最大值,其中一个血量数值大于0则用指定血量
#    DWORD        HPEx;    //默认0取最大值,其中一个血量数值大于0则用指定血量
#};
def OnSummonPriWoodPile(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    npcID = clientData.NPCID
    count = clientData.Count
    hp = clientData.HP
    hpEx = clientData.HPEx
    SummonPriWoodPile(curPlayer, npcID, count, hp, hpEx)
    return
def SummonPriWoodPile(curPlayer, npcID, count, hp=0, hpEx=0):
    ''' 召唤私有专属木桩怪
    '''
    mapID = PlayerControl.GetCustomMapID(curPlayer)
    lineID = PlayerControl.GetCustomLineID(curPlayer)
    if mapID:
        if not FBLogic.OnCanSummonPriWoodPile(curPlayer, mapID, lineID, npcID, count):
            GameWorld.ErrLog("无法召唤木桩怪!mapID=%s,lineID=%s,npcID=%s,count=%s" % (mapID, lineID, npcID, count))
            return
    if count != 1:
        hp, hpEx = 0, 0 # 指定血量的暂仅适用于单只的
    playerID = curPlayer.GetPlayerID()
    if playerID not in PyGameData.g_playerPriWoodPileNPCDict:
        PyGameData.g_playerPriWoodPileNPCDict[playerID] = []
    playerPriWoodNPCList = PyGameData.g_playerPriWoodPileNPCDict[playerID]
    maxCount = 3
    nowCount = len(playerPriWoodNPCList)
    summonCount = min(count, maxCount - nowCount)
    GameWorld.DebugLog("召唤木桩: npcID=%s,count=%s,maxCount=%s,nowCount=%s,summonCount=%s,hp=%s,hpEx=%s"
                       % (npcID, count, maxCount, nowCount, summonCount, hp, hpEx))
    if summonCount <= 0:
        return
    npcManager = GameWorld.GetNPCManager()
    for _ in xrange(summonCount):
        #summonNPC = curPlayer.SummonNewNPC()
        summonNPC = npcManager.AddPlayerSummonNPC()
        #设置召唤兽基础信息
        summonNPC.SetNPCTypeID(npcID)
        summonNPC.SetSightLevel(curPlayer.GetSightLevel())
        #初始化
        InitNPC(summonNPC)
        #玩家召唤兽列表添加召唤兽,召唤兽添加主人
        #summonNPC.SetOwner(curPlayer)
        summonNPC.SetDict(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID, playerID)
        #将召唤兽召唤出来
        #玩家周围随机出生点
        #技能召唤坐标 ChConfig.Def_SummonAppearDist
        summonPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), 3)
        summonNPC.Reborn(summonPos.GetPosX(), summonPos.GetPosY(), False)
        NPCControl(summonNPC).ResetNPC_Init(isReborn=True)
        if hp or hpEx:
            hpTotal = hpEx * ShareDefine.Def_PerPointValue + hp
            GameObj.SetHP(summonNPC, hpTotal)
            GameObj.SetMaxHP(summonNPC, hpTotal)
        summonNPC.NotifyAppear() # 最终统一通知NPC出现
        playerPriWoodNPCList.append(summonNPC)
    return
def ClearPriWoodPile(curPlayer):
    ## 清除私有木桩
    playerID = curPlayer.GetPlayerID()
    if playerID not in PyGameData.g_playerPriWoodPileNPCDict:
        return
    playerPriWoodNPCList = PyGameData.g_playerPriWoodPileNPCDict.pop(playerID)
    for summonNPC in playerPriWoodNPCList:
        if not summonNPC:
            continue
        SetDeadEx(summonNPC)
    return
## 设置npc死亡及自身处理(请不要将游戏逻辑加在此函数中)
#  @param curNPC:npc实例
#  @return 
@@ -936,12 +815,12 @@
    # 暗金boss
    if ChConfig.IsGameBoss(curNPC): 
        # 通知GameServer boss状态 封魔坛在副本里单独处理
        ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcid)
        if ipyData and ipyData.GetMapID() not in [ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss]:
            GameServe_GameWorldBossState(npcid, 0)
            #GameWorld.GetGameWorld().SetGameWorldDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
            #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典
            GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
        #ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcid)
        #if ipyData and ipyData.GetMapID() not in [ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss]:
        #    GameServe_GameWorldBossState(npcid, 0)
        #    #GameWorld.GetGameWorld().SetGameWorldDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
        #    #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典
        #    GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
            
        ChNPC.OnNPCSetDead(curNPC)
        
@@ -1017,81 +896,6 @@
    return
def OnPlayerKillBoss(curPlayer, npcID, mapID, isCrossServer):
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
    if not npcData:
        return
    killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
    limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
    if limitIndex != None:
        totalKey = ChConfig.Def_PDict_Boss_KillCntTotal % limitIndex
        totalCnt = min(curPlayer.NomalDictGetProperty(totalKey, 0) + 1, ChConfig.Def_UpperLimit_DWord)
        PlayerControl.NomalDictSetProperty(curPlayer, totalKey, totalCnt)
        #今日杀怪次数+1
        key = ChConfig.Def_PDict_Boss_KillCnt % limitIndex
        newCnt = curPlayer.NomalDictGetProperty(key, 0) + 1
        PlayerControl.NomalDictSetProperty(curPlayer, key, newCnt)
        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])
        PlayerState.SetBossStateExit(curPlayer)
    if isCrossServer:
        return
    if limitIndex == ShareDefine.Def_Boss_Func_World:
        # 世界BOSS击杀成就
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillWorldBoss, 1)
        PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillWorldBoss, 1)
        # 每日活动
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_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)
        PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_WorldBoss, 1)
        PlayerZhanling.AddZhanlingValue(curPlayer, PlayerZhanling.ZhanlingType_Huanjingge, 1)
        PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_WorldBoss, 1)
    elif limitIndex == ShareDefine.Def_Boss_Func_Home:
        #BOSS之家
        # BOSS之家BOSS击杀成就
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
        PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillBossHome, 1)
        # 每日活动
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_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)
    if mapID == ChConfig.Def_FBMapID_CrossPenglai:
        #跨服蓬莱仙境
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossPenglai)
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillCrossPenglaiBoss, 1)
        PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillCrossPenglaiBoss, 1)
        PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_CrossPenglaiBoss, 1)
    elif mapID == ChConfig.Def_FBMapID_CrossDemonLand:
        #跨服魔化之地
        PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossDemonLand)
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillCrossDemonLandBoss, 1)
        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)
    if ipyData:
        GY_Query_BossFirstKill.SetPlayerFirstKillBoss(curPlayer, npcID)
    #Boss投资
    PlayerGoldInvest.OnKillBoss(curPlayer, npcID)
    return
    
#################################################
@@ -2605,13 +2409,13 @@
        #杀死NPC, 触发任务
        self.__EventKillNpc()
            
        mapID = GameWorld.GetMap().GetMapID()
        killerName = "" if not self.__Killer else self.__Killer.GetPlayerName()
        # 记录boss击杀信息的NPC
        bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID)
        if bossIpyData and mapID not in [ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_SealDemon]:
            killerIDList = [player.GetPlayerID() for player in self.__ownerPlayerList]
            GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0, True, killerIDList)
        #mapID = GameWorld.GetMap().GetMapID()
        #killerName = "" if not self.__Killer else self.__Killer.GetPlayerName()
        ## 记录boss击杀信息的NPC
        #bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID)
        #if bossIpyData and mapID not in [ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_SealDemon]:
        #    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()])
@@ -3320,10 +3124,7 @@
            FBLogic.DoFB_DropOwner(curPlayer , curNPC)
        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)
        
        if ChConfig.IsGameBoss(curNPC):
@@ -3349,10 +3150,6 @@
        #不是普通NPC    
        elif npcObjType != IPY_GameWorld.gnotNormal:
            return
        npcID = curNPC.GetNPCID()
        #GameWorld.DebugLog("__MissionOnKillNPC isFeel=%s" % (isFeel), curPlayer.GetPlayerID())
        #击杀特定NPC成就
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID])
        return
        
    def __GetIsLog(self):
@@ -3395,47 +3192,7 @@
    #  @return 返回值, 获得经验
    #  @remarks 获得经验, 可能是小数
    def __GetExp(self, playerLV, isTeam=False, player=None):
        curNPC = self.__Instance
        baseExp = 0
        #玩家不在副本中
        if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:
            baseExp = FBLogic.OnGetNPCExp(player, curNPC)
        if baseExp > 0:
            return baseExp
        npcID = curNPC.GetNPCID()
        realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel())
        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
        if realmNPCIpyData:
            baseExp = realmNPCIpyData.GetExp()
            npcLV = realmNPCIpyData.GetLV()
        else:
            baseExp = curNPC.GetExp()
            npcLV = curNPC.GetLV()
        if baseExp == 0:
            #GameWorld.Log("杀怪经验异常,该NPC = %s,无经验"%(curNPC.GetID()))
            return 0
        playerID = 0 if not player else player.GetPlayerID()
        # 如果是队伍,则按伤害贡献度计算所获得经验比例
        if isTeam:
            if not player:
                return 0
            hurtPer = AttackCommon.GetTeamPlayerHurtPer(player, curNPC)
            if not hurtPer:
                return 0
            #GameWorld.DebugLog("队员击杀基础经验: npcID=%s,baseExp=%s,hurtPer=%s" % (curNPC.GetNPCID(), baseExp, hurtPer), playerID)
            baseExp *= hurtPer
        #else:
        #    GameWorld.DebugLog("个人击杀基础经验: npcID=%s,baseExp=%s" % (curNPC.GetNPCID(), baseExp), playerID)
        #经验衰减公式 = max(杀怪经验 * max(1-max(玩家等级-怪物等级-10,0)*0.02),0),1)
        exp = eval(FormulaControl.GetCompileFormula("ExpAttenuation", IpyGameDataPY.GetFuncCfg("ExpAttenuation", 1)))
        #exp = CalcNPCExp(baseExp, playerLV, npcLV)
        #GameWorld.DebugLog("击杀NPC最终基础经验: npcID=%s,npcLV=%s,playerLV=%s,baseExp=%s,exp=%s"
        #                   % (curNPC.GetNPCID(), npcLV, playerLV, baseExp, exp), playerID)
        return exp
        return 0
    
    #---------------------------------------------------------------------
    
@@ -3852,12 +3609,7 @@
    npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
    if not npcData:
        return 0
    needRealmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer))
    realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, needRealmLV)
    if realmNPCIpyData:
        baseExp = realmNPCIpyData.GetExp()
    else:
        baseExp = npcData.GetExp()
    baseExp = npcData.GetExp()
    if not baseExp:
        return 0
    npcLV = npcData.GetLV()
@@ -4056,44 +3808,8 @@
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, crossCollectOK=True)
    return
#// A2 34 自定义场景中获取采集奖励 #tagCMGetCustomSceneCollectAward
#
#struct    tagCMGetCustomSceneCollectAward
#{
#    tagHead        Head;
#    DWORD        NPCID;    //采集的NPCID
#};
def OnGetCustomSceneCollectAward(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    npcID = clientData.NPCID
    if not curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):
        GameWorld.ErrLog("非自定义场景中,无法获取定义采集奖励!", playerID)
        return
    mapID = PlayerControl.GetCustomMapID(curPlayer)
    lineID = PlayerControl.GetCustomLineID(curPlayer)
    GameWorld.Log("前端场景采集: mapID=%s,lineID=%s,npcID=%s" % (mapID, lineID, npcID), playerID)
    if not mapID:
        GameWorld.ErrLog("无自定义场景地图ID,不允许采集!", playerID)
        return
    if not FBLogic.OnCustomSceneCollectOK(curPlayer, mapID, lineID, npcID):
        GameWorld.ErrLog("自定义场景地图不允许采集! mapID=%s,lineID=%s,npcID=%s" % (mapID, lineID, npcID), playerID)
        return
    collectNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CollectNPC", npcID)
    if collectNPCIpyData:
        DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)
    return
def DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, collectCnt=1, crossCollectOK=False, isSweep=False):
    return
## 采集结果同步
#  @param None
#  @param None
def SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, syncItemInfoList, collectNPCID=0):
    return #暂不同步
def SyncCollNPCTime(curPlayer, npcIDList=None):
    ## 同步采集NPC功能号采集次数
@@ -4350,7 +4066,6 @@
    if not buyTimesVIPPriID:
        return
    canBuyCnt = 0
    canBuyCnt += PlayerGoldInvest.GetAddBossBuyCnt(curPlayer, killBossMark)
    hasBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Boss_KillCntBuyCnt%killBossMark, 0)
    playerID = curPlayer.GetPlayerID()
    if hasBuyCnt >= canBuyCnt: