ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -48,8 +48,6 @@
import PlayerBossReborn
import PlayerCrossYaomoBoss
import PlayerActCollectWords
import PlayerActGarbageSorting
import PlayerActBossTrial
import PlayerTongTianLing
import CrossPlayerData
import PlayerFeastWish
@@ -145,119 +143,6 @@
def GetNPCSeries(curNPC): return curNPC.GetPoisionDef() # 毒防字段代表NPC系,按二进制位区分
def DoNPCAttrStrengthen(curNPC, isReborn, isDyn=False):
    '''NPC属性增强, NPC属性成长由两个因素决定
    1.NPC成长等级,成长等级决定成长属性,与成长表结合使用
            可设置地图NPC等级动态成长,但是已经刷新出来的NPC等级不变,动态等级变更后刷新的NPC等级才会使用最新等级
    2.玩家人数因素,决定NPC属性的额外成长系数,可单独使用,或者和1一起使用
            可设置马上刷新NPC属性
            除血量外,其他属性会根据动态因素直接变更
            血量会根据血量百分比动态变更至相应的百分比
    '''
    npcID = curNPC.GetNPCID()
    strengthenIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCStrengthen", npcID)
    if not strengthenIpyData:
        #GameWorld.DebugLog("该NPC属性不成长!npcID=%s" % npcID)
        return
    strengthenLV = 0
    strengthenPlayerCnt = 0
    gameFB = GameWorld.GetGameFB()
    if strengthenIpyData.GetIsStrengthenByPlayerCount():
        strengthenPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt)
        if not strengthenPlayerCnt:
            GameWorld.ErrLog("NPC配置了按玩家人数成长类型,但是无法获取到对应的玩家人数!npcID=%s" % (npcID))
            return
    lvStrengthenType = strengthenIpyData.GetLVStrengthenType()
    # 根据世界等级
    if lvStrengthenType == 3:
        strengthenLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
    # 根据最大等级
    elif lvStrengthenType == 2:
        strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV)
    # 根据平均等级
    elif lvStrengthenType == 1:
        strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenAverageLV)
    # 根据按成长等级的上下限随机
    elif lvStrengthenType == 4:
        randMinLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMinLV)
        randMaxLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV)
        strengthenLV = random.randint(randMinLV, randMaxLV)
    # 根据境界难度
    elif lvStrengthenType == 5:
        realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel())
        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
        if realmNPCIpyData:
            strengthenLV = realmNPCIpyData.GetLV()
        else:
            lvStrengthenType = 0
    # 木桩怪最大、平均成长等级处理,直接取归属玩家等级
    if lvStrengthenType in [1, 2] and curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
        owner = None
        summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
        if summonPlayerID:
            owner = GameWorld.GetObj(summonPlayerID, IPY_GameWorld.gotPlayer)
        if owner:
            strengthenLV = owner.GetLV()
    if strengthenIpyData.GetCmpNPCBaseLV():
        strengthenLV = max(strengthenLV, curNPC.GetLV())
    if lvStrengthenType in [1, 2] and not strengthenLV:
        GameWorld.ErrLog("NPC配置了成长等级类型,但是无法获取到对应的成长等级值!npcID=%s,lvStrengthenType=%s" % (npcID, lvStrengthenType))
        return
    # 副本特殊指定
    npcFBAttrDict = FBLogic.GetFBNPCStrengthenAttr(curNPC, isReborn)
    if "LV" in npcFBAttrDict:
        strengthenLV = npcFBAttrDict["LV"]
    attrDict = {} #GetNPCStrengthenAttrDict(npcID, strengthenLV, strengthenPlayerCnt, strengthenIpyData)
    attrDict.update(npcFBAttrDict) # 如果副本有指定属性,则以副本为主
    if not attrDict:
        return
    # 成长等级只在重生的时候设置一次
    if isReborn and curNPC.GetCurLV() != strengthenLV:
        curNPC.SetCurLV(strengthenLV, False) # 重生的不通知等级变更,属性成长刷新后由NPC出现包通知
    befMaxHP = GameObj.GetMaxHP(curNPC)
    befHP = GameObj.GetHP(curNPC)
    #GameWorld.DebugLog("NPC属性成长刷新,isReborn=%s,npcID=%s,LV=%s,curLV=%s,befMaxHP=%s,befHP=%s,attrDict=%s"
    #                   % (isReborn, npcID, curNPC.GetLV(), curNPC.GetCurLV(), befMaxHP, befHP, attrDict))
    for attrKey, strengthenValue in attrDict.items():
        if not hasattr(curNPC, "Set%s" % attrKey):
            if attrKey == "FightPower":
                SetSuppressFightPower(curNPC, strengthenValue)
            continue
        if attrKey == "MaxHP":
            GameObj.SetMaxHP(curNPC, strengthenValue)
        else:
            strengthenValue = min(strengthenValue, ChConfig.Def_UpperLimit_DWord)
            getattr(curNPC, "Set%s" % attrKey)(strengthenValue)
        #GameWorld.DebugLog("    %s=%s" % (attrKey, strengthenValue))
    aftMaxHP = GameObj.GetMaxHP(curNPC)
    if befMaxHP != aftMaxHP:
        if isReborn:
            GameObj.SetHP(curNPC, aftMaxHP)
        elif isDyn:
            # 动态刷新属性的,血量按百分比继承
            aftHP = int(aftMaxHP * befHP / befMaxHP)
            GameObj.SetHP(curNPC, aftHP)
            curNPC.Notify_HP()
            curNPC.Notify_MaxHP()
            #GameWorld.DebugLog("    aftHP=%s,aftMaxHP=%s" % (aftHP, aftMaxHP))
    # 机器人复活初始化给技能
    if isReborn and curNPC.GetType() == ChConfig.ntRobot:
        __OnFBRobotReborn(curNPC, strengthenLV)
    return
def __OnFBRobotReborn(curNPC, npcLV):
@@ -909,115 +794,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 
@@ -1193,11 +969,7 @@
        PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_KillCrossDemonLandBoss, 1)
        PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_CrossDemonLandBoss, 1)
    if mapID in [ChConfig.Def_FBMapID_CrossPenglai, ChConfig.Def_FBMapID_CrossDemonLand]:
        PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_CrossBoss)
        PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_CrossBoss, 1)
    if npcData.GetIsBoss() == ChConfig.Def_NPCType_Boss_Dark:
        PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_KillBoss)
        
    # 个人首杀记录
    ipyData = IpyGameDataPY.GetIpyGameDataNotLog("BOSSFirstKill", npcID)
@@ -3434,7 +3206,6 @@
        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)
@@ -4169,44 +3940,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功能号采集次数