From b82e6dbda1129a3f55d0177964a35d77feff7c77 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 20 十二月 2019 16:40:51 +0800
Subject: [PATCH] 8360 【主干】仙界秘境修改(改为击杀固定怪物数模式)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_BZZD.py |  445 ++++++++++++-------------------------------------------
 1 files changed, 98 insertions(+), 347 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_BZZD.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_BZZD.py
index cc92f20..ddb564f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_BZZD.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_BZZD.py
@@ -25,10 +25,6 @@
 import EventReport
 import ChConfig
 import IpyGameDataPY
-import AttackCommon
-import PyGameData
-import NPCCommon
-import GameObj
 import PlayerSuccess
 import PlayerBossReborn
 import PlayerFairyCeremony
@@ -40,9 +36,8 @@
 import SkillShell
 import BuffSkill
 import EventShell
+import PyGameData
 
-import random
-import math
 
 #---副本配置对应key值---
 (
@@ -60,125 +55,38 @@
 FB_Step_Close, # 副本关闭
 ) = range(5)
 
-BZZD_LastCheckExpTick = 'BZZD_LastCheckExpTick'   # 上次检查保底奖励tick
-BZZD_LastCheckTick = 'BZZD_LastCheckTick'   # 上次检查npc刷新时间
-#BZZD_KillCnt = 'BZZD_KillCnt'   # 击杀数
-BZZD_WaveIndex = 'BZZD_WaveIndex'   # 波数
+BZZD_TotalNPCCount = 'BZZD_TotalNPCCount'   # 总需击杀NPC数量
 
-BZZD_ReExp = 'BZZD_ReExp_%s' # 参考经验, 参数 (npcLV)
-BZZD_NPCMaxHP = 'BZZD_NPCMaxHP_%s_%s' # NPC最大生命值, 参数(npcID, enterLV)
-
+FBPlayerDict_KillCnt = 'FBPlayerDict_KillCnt'   # 击杀数
 FBPlayerDict_EnterLV = 'FBPlayerDict_EnterLV'   # 进入副本时的等级
 FBPlayerDict_TotalExp = 'FBPlayerDict_TotalExp'   # 获得的总经验
 FBPlayerDict_TotalExpPoint = 'FBPlayerDict_TotalExpPoint'   # 获得的总经验点
 FBPlayerDict_EncourageLV = 'FBPlayerDict_EncourageLV'   # 鼓舞等级
 
-FirstEnterExpTimeMax = 99999 # 当单次补时满时记录的一个特殊数值,防止策划调整单次战斗时长时,老号可能会多余补经验
-
-def GetBZZDNPCID(passSecond):
-    ##当前应该刷新的NPCID
-    curNpcid = 0
-    curIndex = 0
-    fairylandNPCList = IpyGameDataPY.GetFuncEvalCfg('FairylandNPC', 1)
-    for i, info in enumerate(fairylandNPCList, 1):
-        timeRange, npcid = info
-        if timeRange[0] <= passSecond <= timeRange[1]:
-            curNpcid = npcid
-            curIndex = i
-            break
-    return curNpcid, curIndex
-
-
-## OnDay处理
-#  @param curPlayer
-#  @return None
-def BZZDOnDay(curPlayer):
-#    joinLineID = __GetPlayerFBLineID(curPlayer)
-#    if joinLineID == None:
-#        GameWorld.DebugLog("BZZDOnDay() level(%s) no enough" % curPlayer.GetLV())
-#        return
-#    
-#    hadEnterCnt = FBCommon.GetEnterFBCount(curPlayer, ChConfig.Def_FBMapID_BZZD)
-#    maxEnterCnt = GetMaxEnterCnt(curPlayer)
-    return
-
-def OnFBPlayerOnLogin(curPlayer):
-    playerID = curPlayer.GetPlayerID()
-    historyEnterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_HistoryEnterCnt)
-    expPerSecondDict = IpyGameDataPY.GetFuncEvalCfg("XjmjFirstEnter", 2, {})
-    if historyEnterCnt not in expPerSecondDict:
-        return
-    playerExpTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_FirstEnterExpTime)
-    if not playerExpTime:
-        #GameWorld.DebugLog("还没进入过仙界秘境,不处理经验补时!", playerID)
-        return
-    
-    mapID = GameWorld.GetMap().GetMapID()
-    mapID = FBCommon.GetRecordMapID(mapID)
-    if mapID == ChConfig.Def_FBMapID_BZZD:
-        GameWorld.DebugLog("仙界秘境副本中,不处理经验补时!", playerID)
-        return
-    fbCfg = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_BZZD)
-    fightTime = fbCfg[Def_FightTime]
-    giveTime = max(0, fightTime - playerExpTime)
-    if not giveTime:
-        #GameWorld.DebugLog("经验补时时间已超过单次挑战时长,不处理经验补时!playerExpTime=%s" % playerExpTime, playerID)
-        return
-    expPerSecond = expPerSecondDict[historyEnterCnt]
-    giveExp = expPerSecond * giveTime
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_FirstEnterExpTime, FirstEnterExpTimeMax)
-    if giveExp:
-        giveExp = PlayerControl.PlayerControl(curPlayer).AddExp(giveExp, ShareDefine.Def_ViewExpType_Sys)
-        GameWorld.DebugLog("玩家首次仙界秘境经验补时:%s秒,giveExp=%s" % (giveTime, giveExp), playerID)
-        
-    return
-
 ## 是否能够通过活动查询进入
-#  @param curPlayer 玩家实例
-#  @param mapID 地图ID
-#  @param lineID 线路id
-#  @param tick 时间戳
-#  @return 布尔值
 def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
-    return __CheckCanEnterBZZD(curPlayer, mapID, lineID)
-
-
-## 检查可否进入百战之地
-def __CheckCanEnterBZZD(curPlayer, mapID, lineID, enterCnt=1):
     return True
 
-
 ## 进入传送点
-#  @param curPlayer
-#  @param mapID 地图ID
-#  @param lineId 分线ID
-#  @param tick
-#  @return 坐标列表(X,Y)
 def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
     if len(ipyEnterPosInfo) == 3:
         return ipyEnterPosInfo
     return ipyEnterPosInfo + [3]
 
-
-##查询是否可以进入地图
-# @param ask:请求结构体(IPY_BMChangeMapAsk)
-# @param tick:时间戳
-# @return IPY_GameWorld.cme 枚举
+## 查询是否可以进入地图
 def OnChangeMapAsk(ask, tick):
     return IPY_GameWorld.cmeAccept
 
+## 开启副本
+def OnOpenFB(tick):
+    return
 
 ## 进副本
-#  @param curPlayer
-#  @param tick
-#  @return None
 def DoEnterFB(curPlayer, tick):
     playerID = curPlayer.GetPlayerID()
     playerLV = curPlayer.GetLV()
-    curCopyMapID = GameWorld.GetGameWorld().GetCopyMapID()
-    teamID = curPlayer.GetTeamID()
-    GameWorld.Log("DoEnterFB...playerCopyMapID=%s,curCopyMapID=%s,playerLV=%s,teamID=%s" 
-                  % (curPlayer.GetCopyMapID(), curCopyMapID, playerLV, teamID), playerID)
+    lineID = GameWorld.GetGameWorld().GetLineID()
+    GameWorld.Log("DoEnterFB..lineID=%s,playerLV=%s" % (lineID, playerLV), playerID)
     gameFB = GameWorld.GetGameFB()
     hadDelTicket = FBCommon.GetHadDelTicket(curPlayer)
     if not hadDelTicket:
@@ -199,29 +107,28 @@
         EventShell.EventRespons_FBEvent(curPlayer, 'passxjmj')
         FBCommon.UpdateFBEnterTick(curPlayer)
         gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_EnterLV, playerLV)
-        PyGameData.g_bzzdPlayerKillNPCCntDict.pop(playerID, 0)
         
         logType = FBCommon.GetFBJoinType(curPlayer, False)
         EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_BZZD, 0, ChConfig.CME_Log_Start, logType)
         historyEnterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_HistoryEnterCnt)
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_HistoryEnterCnt, min(historyEnterCnt+1, 999))
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_FirstEnterExpTime, 1)
-        __GiveFirstEnterPrize(curPlayer, historyEnterCnt+1)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_HistoryEnterCnt, min(historyEnterCnt + 1, 999))
+        __GiveFirstEnterPrize(curPlayer, historyEnterCnt + 1)
         
+        # 初始化所需击杀NPC
+        fairylandNPCList = IpyGameDataPY.GetFuncEvalCfg('FairylandNPC', 1)
+        refreshNPCList = []
+        for npcID, npcCount in fairylandNPCList:
+            refreshNPCList += [npcID] * npcCount
+        PyGameData.g_bzzdRefreshNPCListDict[lineID] = refreshNPCList
+        gameFB.SetGameFBDict(BZZD_TotalNPCCount, len(refreshNPCList))
         
-    fbPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt)
-    isTeamEnter = (teamID and fbPlayerCnt > 1)
-    if not isTeamEnter:
-        CheckHurtBuff(curPlayer, tick)
+    CheckHurtBuff(curPlayer, tick)
     showState = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_GuideState, ChConfig.GuideState_BZZDShow)
     if not showState:
-        if not isTeamEnter:
-            FBCommon.SendFBEncourageInfo(curPlayer, 0)
-            GameWorld.Log("首次单人进入该副本,需要等前端播完副本场景引导秀才正常进入准备阶段!", playerID)
-            return
-        else:
-            GameWorld.Log("队伍方式进入该副本,不播放副本场景引导秀!", playerID)
-            
+        FBCommon.SendFBEncourageInfo(curPlayer, 0)
+        GameWorld.Log("前端场景秀还没播完,需要等前端播完副本场景引导秀才正常进入准备阶段!", playerID)
+        return
+    
     fbStep = gameFB.GetFBStep()
     if fbStep < FB_Step_Prepare:
         FBCommon.SetFBStep(FB_Step_Prepare, tick)
@@ -236,15 +143,16 @@
         mapID = GameWorld.GetMap().GetMapID()
         notify_tick = FBCommon.GetFBLineStepTime(mapID)[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
         curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
-    
+        FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(mapID), curPlayer)
+        
     # 上鼓舞buff
     encourageLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EncourageLV)
     if encourageLV > 0:
         FBCommon.AddFbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, tick)
     else:
         FBCommon.SendFBEncourageInfo(curPlayer, encourageLV)
+        
     DoFBHelp(curPlayer, tick)
-    
     return
 
 def __GiveFirstEnterPrize(curPlayer, historyEnterCnt):
@@ -263,7 +171,7 @@
     return
 
 def CheckHurtBuff(curPlayer, tick, isAdd=True):
-    #人物等级低于世界等级X级,单人挑战仙界密境获得伤害BUFF加成
+    ## 人物等级低于世界等级X级,单人挑战仙界密境获得伤害BUFF加成
     if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_WorldLV):
         return
     playerID = curPlayer.GetID()
@@ -273,8 +181,8 @@
     curLV = curPlayer.GetLV()
     worldlv = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
     buffID = IpyGameDataPY.GetFuncCfg('XjmjAddHarm', 2)
-    lvRange = IpyGameDataPY.GetFuncCfg('XjmjAddHarm')
-    if isAdd and worldlv - curLV >=lvRange:
+    lvRange = IpyGameDataPY.GetFuncCfg('XjmjAddHarm', 1)
+    if isAdd and worldlv - curLV >= lvRange:
         curSkill = GameWorld.GetGameData().GetSkillBySkillID(buffID)
         SkillShell.__DoLogic_AddBuff(curPlayer, curPlayer, curSkill, False, tick, 0, 0)
     if not isAdd and worldlv - curLV < lvRange:
@@ -296,18 +204,16 @@
     curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, max(notify_tick, 0), True)
     curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)
     DoFBHelp(curPlayer, tick)
-#    
-#    isFirstEnter = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_FirstEnterExpTime)
-#    # 没有首次进入经验时间记录,可视为首次进入
-#    if not isFirstEnter:
-#        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_FirstEnterExpTime, 1)
-#        __GiveFirstEnterPrize(curPlayer)
     return
 
-##玩家退出副本
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 无意义
+## 关闭副本
+def OnCloseFB(tick):
+    #GameWorld.GetGameWorld().SetPropertyID(0)
+    lineID = GameWorld.GetGameWorld().GetLineID()
+    PyGameData.g_bzzdRefreshNPCListDict.pop(lineID, None)
+    return
+
+## 玩家退出副本
 def DoExitFB(curPlayer, tick):
     # 清除鼓舞buff
     FBCommon.ClearEncourageBuff(curPlayer, tick)
@@ -316,47 +222,35 @@
     FBCommon.UpdFBLineNPCStrengthenLV(curPlayer.GetPlayerID(), True)
     return
 
-##玩家主动离开副本.
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值无意义
+## 玩家主动离开副本
 def DoPlayerLeaveFB(curPlayer, tick):
     return
 
+## 玩家升级
 def OnPlayerLVUp(curPlayer):
     CheckHurtBuff(curPlayer, GameWorld.GetGameWorld().GetTick(), False)
     FBCommon.UpdFBLineNPCStrengthenLV(curPlayer.GetPlayerID(), False)
     return
 
 ## 获得副本帮助信息
-#  @param curPlayer 当前玩家(被通知对象)
-#  @param tick 当前时间
-#  @return None
 def DoFBHelp(curPlayer, tick):
     gameFB = GameWorld.GetGameFB()
     playerID = curPlayer.GetID()
     
     # 获得副本信息
-
-   
-    #killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, BZZD_KillCnt)
-    killNPCCnt = int(PyGameData.g_bzzdPlayerKillNPCCntDict.get(playerID, 0))
-    passCnt = gameFB.GetGameFBDictByKey(BZZD_WaveIndex)
-    passAllCnt = len(IpyGameDataPY.GetFuncEvalCfg('FairylandNPC'))
+    killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_KillCnt)
+    totalNPCCount = gameFB.GetGameFBDictByKey(BZZD_TotalNPCCount)
     exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)
     expPoint = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExpPoint)
-     
+    
     #副本帮助
-    helpDict = {FBCommon.Help_npcTotal:killNPCCnt, FBCommon.Help_exp:exp, FBCommon.Help_expPoint:expPoint, FBCommon.Help_wheel:passCnt, 'passAllCnt':passAllCnt}
+    helpDict = {FBCommon.Help_npcTotal:killNPCCnt, FBCommon.Help_npcTotalNeed:totalNPCCount,
+                FBCommon.Help_exp:exp, FBCommon.Help_expPoint:expPoint}
     GameWorld.DebugLog("DoFBHelp %s" % str(helpDict))
     FBCommon.Notify_FBHelp(curPlayer, helpDict)
     return
 
-
 ##---副本总逻辑计时器---
-# @param tick:时间戳
-# @return 无意义
-# @remarks 副本总逻辑计时器
 def OnProcess(tick):
     fbStep = GameWorld.GetGameFB().GetFBStep()
     
@@ -373,8 +267,6 @@
     return
 
 ## 副本准备逻辑
-#  @param tick:时间戳
-#  @return 无意义
 def __DoLogic_FB_Prepare(tick):
     #gameFB = GameWorld.GetGameFB()
     mapID = GameWorld.GetMap().GetMapID()
@@ -385,138 +277,54 @@
     
     # 设置开始刷怪
     CheckNPCRefresh(tick)
-
     
     # 副本开始
-
     FBCommon.SetFBStep(FB_Step_Fighting, tick)
     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, fbCfg[Def_FightTime] * 1000)
-    
     return
 
 def CheckNPCRefresh(tick):
     #npc刷新检查
-    gameFB = GameWorld.GetGameFB()
-    lastCheckTick = gameFB.GetGameFBDictByKey(BZZD_LastCheckTick)
-    playerManager = GameWorld.GetMapCopyPlayerManager()
-    heroCnt = playerManager.GetPlayerCount()
-    checkCD = eval(IpyGameDataPY.GetFuncCompileCfg('FairylandNPC', 2))
     
-    if lastCheckTick and tick - lastCheckTick < checkCD:
+    lineID = GameWorld.GetGameWorld().GetLineID()
+    if lineID not in PyGameData.g_bzzdRefreshNPCListDict:
         return
-    gameFB.SetGameFBDict(BZZD_LastCheckTick, tick)
-    passSecond = (tick - GameWorld.GetGameFB().GetFBStepTick())/1000
-    npcID, waveIndex = GetBZZDNPCID(passSecond)
-    if not npcID:
+    refreshNPCList = PyGameData.g_bzzdRefreshNPCListDict[lineID]
+    if not refreshNPCList:
         return
-    if gameFB.GetGameFBDictByKey(BZZD_WaveIndex) != waveIndex:
-        gameFB.SetGameFBDict(BZZD_WaveIndex, waveIndex)
-        for i in range(playerManager.GetPlayerCount()):
-            curPlayer = playerManager.GetPlayerByIndex(i)
-            DoFBHelp(curPlayer, tick)
-            
-    rMarkList = IpyGameDataPY.GetFuncEvalCfg('FairylandPoint')
-    maxCnt = IpyGameDataPY.GetFuncCfg('FairylandPoint',2)
-    firstRMarkList = IpyGameDataPY.GetFuncEvalCfg('FairylandPoint',3)
-    allRmark = rMarkList+firstRMarkList
-    npcCntDict = {mark:0 for mark in allRmark} #标识点对应数量
-    npcCnt = 0
+    
     gameNPC = GameWorld.GetNPCManager()
-    for i in range(0, gameNPC.GetCustomNPCRefreshCount()):
+    customNPCRefreshCount = gameNPC.GetCustomNPCRefreshCount()
+    for i in xrange(customNPCRefreshCount):
         npcRefresh = gameNPC.GetCustomNPCRefreshAt(i)
-        npcCnt += npcRefresh.GetCount()
-        rmark = npcRefresh.GetRefreshMark()
-        npcCntDict[rmark] = npcCntDict.get(rmark, 0)+npcRefresh.GetCount()
-    
-    if not lastCheckTick:
-        needAddCnt = IpyGameDataPY.GetFuncCfg('FairylandNPC', 3)
-    else:
-        needAddCnt = eval(IpyGameDataPY.GetFuncCompileCfg('FairylandNPCCnt'))
-
-    if not needAddCnt:
-        return
-    
-    markCntList = sorted(npcCntDict.iteritems(), key=lambda asd:asd[1])
-    #GameWorld.Log('11111111111111111markCntList=%s'%markCntList)
-    hasRefreshCnt = 0
-    for rMark, curCnt in markCntList:
-        if hasRefreshCnt >=needAddCnt:
+        if npcRefresh.GetCount():
+            continue
+        rMark = npcRefresh.GetRefreshMark()
+        npcID = refreshNPCList.pop(0) # 直接按顺序取NPCID
+        NPCCustomRefresh.SetNPCRefresh(rMark, [npcID])
+        
+        if not refreshNPCList:
+            GameWorld.DebugLog("怪全部刷完了,没怪了!")
             break
-        cnt = min(maxCnt, needAddCnt-hasRefreshCnt)
-        hasRefreshCnt +=cnt
-        curMaxCnt = curCnt+cnt
-        NPCCustomRefresh.SetNPCRefresh(rMark, [(npcID, cnt)], curMaxCnt, cnt)
-    NPCCustomRefresh.ProcessAllNPCRefresh(tick) # 立即出发一次标识点刷新
-    return
-
-def CheckFirstEnterExp(tick, isOver=False):
-    gameFB = GameWorld.GetGameFB()
-    if not isOver:
-        lastCheckExpTick = gameFB.GetGameFBDictByKey(BZZD_LastCheckExpTick)
-        if not lastCheckExpTick:
-            gameFB.SetGameFBDict(BZZD_LastCheckExpTick, tick)
-            return
-        if tick - lastCheckExpTick < 5000:
-            return
-    gameFB.SetGameFBDict(BZZD_LastCheckExpTick, tick) # 这个全局tick只是处理多久执行一次而已,不参与其他逻辑
-    
-    fightTime = int(math.ceil((tick - GameWorld.GetGameFB().GetFBStepTick()) / 1000.0)) # 已经战斗时长,秒
-    expPerSecondDict = IpyGameDataPY.GetFuncEvalCfg("XjmjFirstEnter", 2, {})
-    
-    
-    playerManager = GameWorld.GetMapCopyPlayerManager()
-    playerCount = playerManager.GetPlayerCount()
-    for i in xrange(playerCount):
-        curPlayer = playerManager.GetPlayerByIndex(i)
-        if not curPlayer:
-            continue
-        playerID = curPlayer.GetPlayerID()
-        historyEnterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_HistoryEnterCnt)
-        if historyEnterCnt not in expPerSecondDict:
-            continue
-        playerExpTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_FirstEnterExpTime)
-        if playerExpTime >= fightTime:
-            #GameWorld.DebugLog("已经处理完保底经验时间,不再处理!", playerID)
-            continue
         
-        updExpTime = FirstEnterExpTimeMax if isOver else fightTime
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_FirstEnterExpTime, updExpTime)
-        
-        exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)
-        expPoint = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExpPoint)
-        playerTotalExp = expPoint * ChConfig.Def_PerPointValue + exp
-        expPerSecond = expPerSecondDict[historyEnterCnt]
-        minTotalExp = expPerSecond * fightTime # 理论保底最少经验
-        giveExp = max(0, minTotalExp - playerTotalExp)
-        if giveExp > 0:
-            giveExp = PlayerControl.PlayerControl(curPlayer).AddExp(giveExp, ShareDefine.Def_ViewExpType_Sys)
-            __RecordAddExp(curPlayer, giveExp, True)
-            
-        GameWorld.DebugLog("保底经验: updExpTime=%s,minTotalExp=%s,playerTotalExp=%s,giveExp=%s" 
-                           % (updExpTime, minTotalExp, playerTotalExp, giveExp), playerID)
+    NPCCustomRefresh.ProcessAllNPCRefresh(tick) # 立即出发一次标识点刷新            
     return
 
 ## 副本进行中
-#  @param tick:时间戳
-#  @return 无意义
 def __DoLogic_FB_Fighting(tick):
     #gameFB = GameWorld.GetGameFB()
     mapID = GameWorld.GetMap().GetMapID()
+    FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(mapID))
     fbCfg = FBCommon.GetFBLineStepTime(mapID)
     # 间隔未到
     if tick - GameWorld.GetGameFB().GetFBStepTick() < fbCfg[Def_FightTime] * 1000:
         CheckNPCRefresh(tick)
-        CheckFirstEnterExp(tick)
         return
-    
     __DoBZZDOver()
     return
 
         
 ##副本关闭中
-# @param tick:时间戳
-# @return 无意义
-# @remarks 副本关闭中
 def __DoLogic_FB_Over(tick):
 
     #gameFB = GameWorld.GetGameFB()
@@ -532,9 +340,6 @@
     return
 
 ## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
-#  @param attacker 攻击方
-#  @param defender 防守方
-#  @return bool
 def CheckCanAttackTagObjInFB(attacker, defender):
     gameFB = GameWorld.GetGameFB()
     if gameFB.GetFBStep() != FB_Step_Fighting:
@@ -546,73 +351,30 @@
 def OnGetNPCExp(curPlayer, curNPC):
     if not curPlayer:
         return 0
-    #参数
-    #baseExp     基础值
-    #expMulti    仙界秘境经验效率
-    #hurtValue   伤害值
-    #npcMaxHP    怪物血量, 玩家进入副本时的等级对应怪物成长血量
-    #reExp       等级经验效率, 取副本NPC等级
-    #playerCnt   队员人数
-    playerID = curPlayer.GetPlayerID()
-    npcLV = max(curNPC.GetCurLV(), curNPC.GetLV())
+    
     npcID = curNPC.GetNPCID()
+    playerID = curPlayer.GetPlayerID()
     gameFB = GameWorld.GetGameFB()
-    reExp = gameFB.GetGameFBDictByKey(BZZD_ReExp % npcLV)
-    if not reExp:
-        lvIpyData = PlayerControl.GetPlayerLVIpyData(npcLV)
-        reExp = 0 if not lvIpyData else lvIpyData.GetReExp()
-        gameFB.SetGameFBDict(BZZD_ReExp % npcLV, reExp)
-        GameWorld.DebugLog("初始化参数: npcID=%s,npcLV=%s,reExp=%s" % (npcID, npcLV, reExp), playerID)
-        
-    playerCnt = max(1, gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt))
-    enterLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EnterLV)
-    npcMaxHP = gameFB.GetGameFBDictByKey(BZZD_NPCMaxHP % (npcID, enterLV))
-    if not npcMaxHP:
-        enterLVAttrDict = NPCCommon.GetNPCStrengthenAttrDict(npcID, enterLV)
-        npcMaxHP = enterLVAttrDict.get("MaxHP", 0)
-        gameFB.SetGameFBDict(BZZD_NPCMaxHP % (npcID, enterLV), npcMaxHP)
-        GameWorld.DebugLog("初始化参数: npcID=%s,enterLV=%s,npcMaxHP=%s" % (npcID, enterLV, npcMaxHP), playerID)
-        if not npcMaxHP:
-            GameWorld.ErrLog("无法获得NPC最大生命值,npcID=%s,enterLV=%s" % (npcID, enterLV), playerID)
-            return 0
-        
+    reExp = PlayerControl.GetPlayerReExp(curPlayer)
     baseExp = curNPC.GetExp()
     expMulti = IpyGameDataPY.GetFuncCfg("XjmjMonsterExp", 2)
-    curNPCMaxHP = GameObj.GetMaxHP(curNPC)
-    teamPlayerHurtValue = AttackCommon.GetTeamPlayerHurtValue(curPlayer, curNPC)
-    hurtValue = npcMaxHP if not curPlayer.GetTeamID() else teamPlayerHurtValue
-    #GameWorld.DebugLog("击杀NPC: npcID=%s,baseExp=%s,expMulti=%s,hurtValue=%s,npcMaxHP=%s,curNPCMaxHP=%s,playerCnt=%s" 
-    #                   % (npcID, baseExp, expMulti, hurtValue, npcMaxHP, curNPCMaxHP, playerCnt), playerID)
+    addExp = eval(IpyGameDataPY.GetFuncCompileCfg("XjmjMonsterExp", 1))
     
-    addExp = eval(IpyGameDataPY.GetFuncCompileCfg("XjmjMonsterExp"))
-    #GameWorld.DebugLog("    addExp=%s" % (addExp), playerID)
-    if addExp <= 0:
-        GameWorld.ErrLog("经验计算异常:  npcID=%s,npcLV=%s,reExp=%s,baseExp=%s,expMulti=%s,hurtValue=%s,npcMaxHP=%s,curNPCMaxHP=%s,playerCnt=%s" 
-                         % (npcID, npcLV, reExp, baseExp, expMulti, hurtValue, npcMaxHP, curNPCMaxHP, playerCnt), playerID)
-        
+    #GameWorld.DebugLog("击杀NPC: npcID=%s,reExp=%s,baseExp=%s,expMulti=%s,addExp=%s" 
+    #                   % (npcID, reExp, baseExp, expMulti, addExp), playerID)
+    
     #累计击杀数
-    curHurtValue = curNPCMaxHP if not curPlayer.GetTeamID() else teamPlayerHurtValue
-    addKillCnt = curHurtValue / float(curNPCMaxHP)
-    PyGameData.g_bzzdPlayerKillNPCCntDict[playerID] = PyGameData.g_bzzdPlayerKillNPCCntDict.get(playerID, 0) + addKillCnt
-    #GameWorld.DebugLog("    增加玩家杀怪数: %s / %s = %s, %s" % (curHurtValue, curNPCMaxHP, addKillCnt, PyGameData.g_bzzdPlayerKillNPCCntDict), playerID)
-    
+    killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_KillCnt) + 1
+    gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_KillCnt, killNPCCnt)
     DoFBHelp(curPlayer, GameWorld.GetGameWorld().GetTick())
     return addExp
 
 ## 获得经验
-#  @param curPlayer 当前玩家
-#  @param addExp 获得的经验
-#  @param expViewType 经验类型
-#  @return True or False
 def OnGetExp(curPlayer, addExp, expViewType):
     
     if expViewType != ShareDefine.Def_ViewExpType_KillNPC:
         return
     
-    __RecordAddExp(curPlayer, addExp)
-    return
-
-def __RecordAddExp(curPlayer, addExp, isSys=False):
     playerID = curPlayer.GetID() 
     gameFB = GameWorld.GetGameFB()
     exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)
@@ -624,37 +386,18 @@
     gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_TotalExp, updExp)
     gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_TotalExpPoint, updExpPoint)
     
-    GameWorld.DebugLog("OnGetExp() totalExp=%s,addExp=%s,updTotalExp=%s,isSys=%s" 
-                       % (totalExp, addExp, updTotalExp, isSys), playerID)
+    #GameWorld.DebugLog("OnGetExp() totalExp=%s,addExp=%s,updTotalExp=%s" % (totalExp, addExp, updTotalExp), playerID)
+    
+    killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_KillCnt)
+    totalNPCCount = gameFB.GetGameFBDictByKey(BZZD_TotalNPCCount)
+    if killNPCCnt >= totalNPCCount:
+        GameWorld.DebugLog("怪物已全部杀完,结算副本!")
+        __DoBZZDOver()
     return
-
-### 执行副本杀怪逻辑
-##  @param curPlayer 杀怪的人
-##  @param curNPC 被杀的怪
-##  @param tick 当前时间
-##  @return None
-#def DoFB_DropOwner(curPlayer, curNPC):
-#    playerID = curPlayer.GetID() 
-#    gameFB = GameWorld.GetGameFB()
-#    killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, BZZD_KillCnt)
-#    gameFB.SetPlayerGameFBDict(playerID, BZZD_KillCnt, killNPCCnt + 1)
-#    
-#    DoFBHelp(curPlayer, GameWorld.GetGameWorld().GetTick())
-#    return
-
-#关系有3层,无-友好-敌人
-##判断是否可释放(增/减)技能或普攻
-# @param curPlayer 玩家实例
-# @param curTagPlayer 目标玩家实例
-# @return 布尔值
-def CheckPlayersRelation_IsNone(curPlayer, curTagPlayer):
-    #PlayerControl.NotifyCode(curPlayer, "PK_lhs_272921")
-    return True
 
 ## 副本结束处理
 def __DoBZZDOver():
     tick = GameWorld.GetGameWorld().GetTick()
-    CheckFirstEnterExp(tick, True) # 结算前强制处理一次
     
     playerManager = GameWorld.GetMapCopyPlayerManager()
     playerCount = playerManager.GetPlayerCount()
@@ -665,6 +408,10 @@
     fbCfg = FBCommon.GetFBLineStepTime(mapID)
     gameFB = GameWorld.GetGameFB()
     costTime = tick - gameFB.GetFBStepTick()
+    FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(mapID)) # 结算前强制刷新一次评级
+    grade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)
+    rewardRateList = FBCommon.GetFBGradeRewardRateList(mapID)
+    maxGrade = len(rewardRateList)
     
     for i in xrange(playerCount):
         curPlayer = playerManager.GetPlayerByIndex(i)
@@ -676,6 +423,12 @@
         exp = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExp)
         expPoint = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_TotalExpPoint)
         totalExp = expPoint * ChConfig.Def_PerPointValue + exp
+        gradeAddExpRate = rewardRateList[maxGrade - grade]
+        gradeExp = int(totalExp * gradeAddExpRate / 100.0)
+        totalExp += gradeExp
+        
+        playerControl = PlayerControl.PlayerControl(curPlayer)
+        playerControl.AddExp(gradeExp)
         
         expRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_TotalFightExp)
         expPointRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BZZD_TotalFightExpPoint)
@@ -684,23 +437,26 @@
         if totalExp > totalExpRecord:#超过旧记录
             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_TotalFightExp, exp)
             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BZZD_TotalFightExpPoint, expPoint)
-            upPer = (totalExp - totalExpRecord)*100/totalExpRecord if totalExpRecord else 0
+            upPer = (totalExp - totalExpRecord) * 100 / totalExpRecord if totalExpRecord else 0
             #单场总经验成就
             PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_XJMJGetExp, 1, [expPoint])
             
-        #killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, BZZD_KillCnt)
-        killNPCCnt = int(PyGameData.g_bzzdPlayerKillNPCCntDict.get(playerID, 0))
+        killNPCCnt = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_KillCnt)
         
         # 通知结果
         enterLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EnterLV)
-        __SendBZZDOverInfo(curPlayer, {FBCommon.Over_enterLV:enterLV,FBCommon.Over_exp:exp, FBCommon.Over_expPoint:expPoint,FBCommon.Over_costTime:costTime, FBCommon.Over_npcTotal:killNPCCnt, 'upPer':upPer})
-    
+        overDict = {FBCommon.Over_enterLV:enterLV, FBCommon.Over_exp:exp, FBCommon.Over_expPoint:expPoint, 'gradeExp':gradeExp,
+                    FBCommon.Over_costTime:costTime, FBCommon.Over_npcTotal:killNPCCnt, 'upPer':upPer, FBCommon.Over_grade:grade}
+        __SendBZZDOverInfo(curPlayer, overDict)
+        
     # 进入离开阶段
     FBCommon.SetFBStep(FB_Step_Over, tick)
     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, fbCfg[Def_LeaveTime] * 1000)
     
-    rMarkList = IpyGameDataPY.GetFuncEvalCfg('FairylandPoint')
-    for rMark in rMarkList:
+    gameNPC = GameWorld.GetNPCManager()
+    for i in xrange(gameNPC.GetCustomNPCRefreshCount()):
+        npcRefresh = gameNPC.GetCustomNPCRefreshAt(i)
+        rMark = npcRefresh.GetRefreshMark()
         NPCCustomRefresh.CloseNPCRefresh(rMark, tick)
     return
 
@@ -714,16 +470,11 @@
 
 
 ## 副本行为
-#  @param curPlayer 玩家
-#  @param actionType 行为类型
-#  @param actionInfo 行为信息
-#  @param tick 当前时间
-#  @return None
 def DoFBAction(curPlayer, actionType, actionInfo, tick):
     if actionType == 0:
         #第一次在百战之地鼓舞一次就满级
         FBCommon.FbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, actionInfo, tick)
-        return 
+        return
     
     return
 

--
Gitblit v1.8.0