| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldLogic.FBProcess.GameLogic_TrialTower  | 
| #  | 
| # @todo:·ûÓ¡Ëþ  | 
| # @author xdh  | 
| # @date 2017-05-05  | 
| # @version 1.0  | 
| # ÏêϸÃèÊö: ·ûÓ¡Ëþ  | 
| #  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2017-05-05 11:00"""  | 
| #---------------------------------------------------------------------  | 
|   | 
| import FBCommon  | 
| import GameWorld  | 
| import IPY_GameWorld  | 
| import PlayerControl  | 
| import NPCCustomRefresh  | 
| import ChPyNetSendPack  | 
| import ItemControler  | 
| import EventShell  | 
| import NetPackCommon  | 
| import ShareDefine  | 
| import IpyGameDataPY  | 
| import PlayerRune  | 
| import ItemCommon  | 
| import ChConfig  | 
| import ChPlayer  | 
| import PlayerSuccess  | 
| import PlayerActivity  | 
| import PlayerBillboard  | 
| import EventReport  | 
|   | 
| import random  | 
| import math  | 
| import PlayerBossReborn  | 
|   | 
| g_runeTypeDict = {}  | 
| FBDict_Level = 'FBDict_Level'   # ¸±±¾¹Ø¿¨  | 
|   | 
|   | 
| # ¸±±¾Í¨ÓÃÅäÖà  | 
| (  | 
| Def_PrepareTime, # Ã¿¹Ø×¼±¸Ê±¼ä£¬Ãë  | 
| Def_FightTime, # Ã¿¹ØÕ½¶·Ê±¼ä£¬Ãë  | 
| Def_ExitTime, # Í˳öʱ¼ä, Ãë  | 
| Def_DayPrizeMaxCnt, #ÿÈÕ½±Àø×î¶àÀÛ»ý¼¸Ì죨Åä0ÔòÎÞÏÞ£©  | 
| ) = range(4)  | 
|   | 
|   | 
|   | 
|   | 
| # ¸±±¾×´Ì¬  | 
| (  | 
| FB_State_Open, # ¸±±¾¿ªÆô  | 
| FB_State_FightPrepare, # Õ½¶·×¼±¸Ê±¼ä  | 
| FB_State_Fighting, # Õ½¶·  | 
| FB_State_FreeTime, # »î¶¯½áÊø×¼±¸£¨Ê¤Àû/ʧ°Ü£©  | 
| FB_State_Close, # ¹Ø±Õ¸±±¾  | 
| ) = range(5)  | 
|   | 
|   | 
| ## ·ûÓ¡ËþÅäÖÃ  | 
| def __GetTrialCfg(): return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_TrialTower)  | 
|   | 
| def GetTowerIpyData(level):  | 
|     return IpyGameDataPY.GetIpyGameData('RuneTower', level)  | 
|   | 
| def OnFBPlayerLogin(curPlayer):  | 
|     SyncTrialLevelInfo(curPlayer)  | 
|     return  | 
|   | 
| def OnFBPlayerOnDay(curPlayer):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_TrialTower_LastDayPassLV, __GetTrialLevelCurPassLV(curPlayer))  | 
|     #֪ͨ  | 
|     SyncTrialLevelInfo(curPlayer)  | 
|     return  | 
|   | 
|   | 
| ## Í¬²½·ûÓ¡Ëþ¹Ø¿¨ÐÅÏ¢  | 
| #  @fbLevel Îª0ʱĬÈÏÈ«²¿Í¬²½£¬> 0ʱ½öͬ²½¸Ã¹Ø¿¨  | 
| def SyncTrialLevelInfo(curPlayer):  | 
|     ttInfo = ChPyNetSendPack.tagMCTrialTowerInfo()  | 
|     ttInfo.Clear()  | 
|     ttInfo.PassLV = __GetTrialLevelCurPassLV(curPlayer)  | 
|     ttInfo.YesterDayPassLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_TrialTower_LastDayPassLV)  | 
|     NetPackCommon.SendFakePack(curPlayer, ttInfo)  | 
|     return  | 
|   | 
| ## »ñÈ¡µ±Ç°ÒÑͨ¹Ø¹Ø¿¨  | 
| def __GetTrialLevelCurPassLV(curPlayer):  | 
|     return curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_TrialTower_PassLV)  | 
|   | 
| ## ¸üе±Ç°ÒÑͨ¹Ø¹Ø¿¨  | 
| def SetTrialLevelCurPassLV(curPlayer, passlv):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_TrialTower_PassLV, passlv)  | 
|     PlayerRune.DoUnlockRuneHole(curPlayer)  | 
|     #ͨ¹Ø·ûÓ¡Ëþ³É¾Í  | 
|     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_PassRuneTower, 1, [passlv])  | 
|     PlayerBillboard.UpdateRuneTowerBillboard(curPlayer)  | 
|     GameWorld.DebugLog(' ¸üзûÓ¡ËþÒÑͨ¹ØÊý %s' % passlv)  | 
|     return  | 
|   | 
| ## ÊÇ·ñ¿É½øÈë  | 
| #  @param curPlayer  | 
| #  @param mapID µØÍ¼ID  | 
| #  @param lineId ·ÖÏßID  | 
| #  @param tick  | 
| #  @return ÊÇ·ñ¿É½øÈë  | 
| def OnEnterFBEvent(curPlayer, mapID, lineId, tick):      | 
|     return True  | 
|   | 
|   | 
| ## ¼ì²é¿É·ñ½øÐÐÌôÕ½  | 
| def __CheckCanChallenge(curPlayer, fbLevel):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     ipyData = GetTowerIpyData(fbLevel)  | 
|       | 
|     if not ipyData:  | 
|         GameWorld.ErrLog("·ûÓ¡Ëþ¹Ø¿¨(%s)²»´æÔÚ" % (fbLevel), playerID)  | 
|         return False  | 
|       | 
|     # ÊÇ·ñÒѹý¹Ø  | 
|     if fbLevel <= __GetTrialLevelCurPassLV(curPlayer):  | 
|         GameWorld.DebugLog("·ûÓ¡Ëþ±¾¹Ø(%s)Òѹý¹Ø, ÎÞ·¨ÌôÕ½!" % fbLevel, playerID)  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
|   | 
| ##¸±±¾Íæ¼Ò½øÈëµã  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param mapID µØÍ¼ID  | 
| # @param lineId ·ÖÏßID  | 
| # @param ipyEnterPosInfo ¹¦ÄÜÏß·IPYÅäÖÃ×ø±êÐÅÏ¢  | 
| # @param tick Ê±¼ä´Á  | 
| # @return posX, posY, Ëæ»ú°ë¾¶(¿ÉÑ¡)  | 
| def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  | 
|     return ipyEnterPosInfo  | 
|   | 
|   | 
| ## ÊÇ·ñ¿ÉÒÔ½øÈë  | 
| #  @param ask ÇëÇóÐÅÏ¢  | 
| #  @param tick  | 
| #  @return »Ø¸´ÊÇ·ñͨ¹ýÇëÇó  | 
| def OnChangeMapAsk(ask, tick):  | 
|     return IPY_GameWorld.cmeAccept  | 
|   | 
| ## ½ø¸±±¾  | 
| #  @param curPlayer  | 
| #  @param tick  | 
| #  @return None  | 
| def DoEnterFB(curPlayer, tick):  | 
|     # ²»×ö´¦Àí£¬Óи±±¾ÐÐΪ¿Í»§¶Ë·¢°üÑ¡ÔñÌôÕ½¹Ø¿¨  | 
|     EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_TrialTower, 0, ChConfig.CME_Log_Start)  | 
|     return  | 
|   | 
|   | 
| ## ¸±±¾Ê±¼äµ½¹Ø±Õ  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def OnCloseFB(tick):  | 
|     return  | 
|   | 
|   | 
| ##Íæ¼ÒÍ˳ö¸±±¾.  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| def DoExitFB(curPlayer, tick):  | 
|     # Íæ¼ÒÍ˳öĬÈϹرո±±¾  | 
|     #GameWorldProcess.CloseFB(tick)  | 
|     return  | 
|   | 
|   | 
| ##¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  | 
| def OnProcess(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = gameFB.GetFBStep()  | 
|       | 
|     if fbStep == FB_State_FightPrepare:  | 
|         __DoLogic_FightPrepare(tick)  | 
|     elif fbStep == FB_State_Fighting:  | 
|         __DoLogic_Fighting(tick)  | 
|     elif fbStep == FB_State_FreeTime:  | 
|         __DoLogic_FreeTime(tick)  | 
|     elif fbStep == FB_State_Close:  | 
|         pass  | 
|       | 
|     return  | 
|   | 
| ## »ñÈ¡BossID  | 
| def __GetTrialBossID(fbLevel= -1):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if fbLevel == -1:  | 
|         fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  | 
|     ipyData = GetTowerIpyData(fbLevel)  | 
|       | 
|     if not ipyData:  | 
|         GameWorld.ErrLog("__GetTrialBossID() can not find %s in TrialTowerNPC.txt" % fbLevel)  | 
|         return 0  | 
|     return ipyData.GetNPCID()  | 
|   | 
| ##Õ½¶·×¼±¸Ê±¼ä  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| def __DoLogic_FightPrepare(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|       | 
|     trialCfg = __GetTrialCfg()  | 
|     if tick - gameFB.GetFBStepTick() < trialCfg[Def_PrepareTime] * 1000:  | 
|         return  | 
|       | 
|     bossID = __GetTrialBossID()  | 
|     if not bossID:  | 
|         FBCommon.DoLogic_FBKickAllPlayer()  | 
|         return  | 
|       | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, trialCfg[Def_FightTime] * 1000)  | 
|       | 
|     NPCCustomRefresh.SetNPCRefresh(FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_TrialTower, 0), [bossID])  | 
|       | 
|     #תÈëÕ½¶·  | 
|     FBCommon.SetFBStep(FB_State_Fighting, tick)  | 
|     return  | 
|   | 
| ## ¿ªÊ¼¸±±¾¹Ø¿¨  | 
| def StartFBLevel(curPlayer, fbLevel, tick):  | 
|       | 
|     if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  | 
|         GameWorld.DebugLog("¸´»îÍæ¼Ò...", curPlayer.GetPlayerID())  | 
|         ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_City, tick)  | 
|     curPlayer.SetHP(curPlayer.GetMaxHP())  | 
|     FBCommon.ClearFBNPC()  | 
|       | 
|     gameFB = GameWorld.GetGameFB()  | 
|     gameFB.SetGameFBDict(FBDict_Level, fbLevel)  | 
|       | 
|     prepareTick = __GetTrialCfg()[Def_PrepareTime] * 1000  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttAddUpTime, prepareTick)  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, prepareTick)  | 
|     FBCommon.SetFBStep(FB_State_FightPrepare, tick)  | 
|     helpDict = {FBCommon.Help_wheel:fbLevel}  | 
|     FBCommon.Notify_FBHelp(curPlayer, helpDict)  | 
|     GameWorld.DebugLog("StartFBLevel, fbLevel=%s, helpDict=%s"   | 
|                        % (fbLevel, str(helpDict)), curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
|   | 
| ##Õ½¶·Ê±¼ä  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| def __DoLogic_Fighting(tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|       | 
|     #ÅжÏʱ¼ä½áÊø  | 
|     if tick - gameFB.GetFBStepTick() < __GetTrialCfg()[Def_FightTime] * 1000:  | 
|         return  | 
|       | 
|     fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  | 
|     playerManager = GameWorld.GetMapCopyPlayerManager()  | 
|     for index in xrange(playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if not curPlayer:  | 
|             continue  | 
|         __SendTrialTowerOverInfo(curPlayer, fbLevel, False)  | 
|       | 
|     #ÓÎÏ·½áÊø  | 
|     __SetFBToFreeTime(tick)  | 
|     return  | 
|   | 
| ##ÉèÖø±±¾½øÈëÀ뿪״̬  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| def __SetFBToFreeTime(tick):  | 
|     FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, __GetTrialCfg()[Def_ExitTime] * 1000)  | 
|     FBCommon.SetFBStep(FB_State_FreeTime, tick)  | 
|     return  | 
|   | 
| ##±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  | 
| # @param tick  Ê±ÖÓ  | 
| # @return ÎÞÒâÒå  | 
| # @remarks ±ÈÈü½áÊøµÄ¿ÕÏÐʱ¼ä  | 
| def __DoLogic_FreeTime(tick):  | 
|     if tick - GameWorld.GetGameFB().GetFBStepTick() < __GetTrialCfg()[Def_ExitTime] * 1000:  | 
|         return  | 
|       | 
|     #FBCommon.DoLogic_FBKickAllPlayer()  | 
|     return  | 
|   | 
| ## É±¹Ö  | 
| #  @param curPlayer  | 
| #  @param curNPC ±»É±µÄ¹Ö  | 
| #  @param tick  | 
| #  @return None  | 
| def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() != FB_State_Fighting:  | 
|         return  | 
|     bossID = __GetTrialBossID()  | 
|     if bossID != curNPC.GetNPCID():  | 
|         return  | 
|       | 
|       | 
|     fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  | 
|               | 
|     # ¹ý¹ØÈ«·þ¹ã²¥  | 
|     ipyData = GetTowerIpyData(fbLevel)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     floorCnt = IpyGameDataPY.GetFuncCfg('TowerRuneType', 2)  | 
|     if fbLevel % 100 == floorCnt:  | 
|         # ¼Ç¼¹ý¹Ø  | 
|         EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_TrialTower, 0, ChConfig.CME_Log_End, 0, 1)  | 
|           | 
|     if ipyData.GetIsNotify():  | 
|         IPY_Data = IpyGameDataPY.IPY_Data()  | 
|         maxLevel = IPY_Data.GetRuneTowerByIndex(IPY_Data.GetRuneTowerCount()-1).GetID()  | 
|         sysMark = 'RuneTowerInfo_1' if fbLevel == maxLevel else 'GeRen_liubo_471172'  | 
|         PlayerControl.WorldNotify(0, sysMark,  | 
|                                   [curPlayer.GetPlayerName(), fbLevel / 100])  | 
|     #¸üйؿ¨  | 
|     SetTrialLevelCurPassLV(curPlayer, fbLevel)  | 
|     # ¸ø¹ý¹Ø½±Àø  | 
|     prizeDict = __GiveFBPassPrize(curPlayer, fbLevel)  | 
|     # ¹ý¹ØÊ±¼ä  | 
|     costTime = tick - GameWorld.GetGameFB().GetFBStepTick()  | 
|     prizeDict[FBCommon.Over_costTime] = costTime  | 
|     __SendTrialTowerOverInfo(curPlayer, fbLevel, True, prizeDict)  | 
|       | 
|     #ÈÎÎñ  | 
|     EventShell.EventRespons_TrialTowerCnt(curPlayer, fbLevel)  | 
|       | 
|     SyncTrialLevelInfo(curPlayer) # Í¬²½×îйؿ¨ÐÅÏ¢  | 
|     __SetFBToFreeTime(tick)  | 
|     #ÿÈÕÈÎÎñ  | 
|     PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_Tower)  | 
|     return  | 
|   | 
|   | 
|   | 
| ## ¸ø¹ý¹Ø½±Àø  | 
| def __GiveFBPassPrize(curPlayer, fbLevel):  | 
|     ipyData = GetTowerIpyData(fbLevel)  | 
|     if not ipyData:  | 
|         return {}  | 
|     #·ûÓ¡¾«»ª  | 
|     addJH = ipyData.GetRunePoint()  | 
|     PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_Rune, addJH)  | 
|     #·ûӡħ¾«  | 
|     RuneMagicEssence = ipyData.GetYsog()  | 
|     PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_Ysog, RuneMagicEssence)  | 
|     specialAwardDict = IpyGameDataPY.GetFuncEvalCfg('PreFourAward')  | 
|     if fbLevel in specialAwardDict:  | 
|         prizeItemList = []  | 
|         for itemID, itemCnt in specialAwardDict[fbLevel]:  | 
|             for _ in xrange(itemCnt):  | 
|                 prizeItemList.append([itemID, 1, 1])  | 
|     else:  | 
|         prizeItemList = __GetEndAward(curPlayer, fbLevel)  | 
|         #¹Ì¶¨½±Àø  | 
|         FixEndAward = ipyData.GetFixEndAward()  | 
|         for itemID, itemCnt in FixEndAward:  | 
|             for _ in xrange(itemCnt):  | 
|                 prizeItemList.append([itemID, 1, 1])  | 
|         #ºÃ¶«Î÷  | 
|         goodDropDict = ipyData.GetGoodDrop()  | 
|         for itemID, rate in goodDropDict.items():  | 
|             if GameWorld.CanHappen(rate):  | 
|                 prizeItemList.append([itemID, 1, 1])  | 
|     #ÌØÊâ·ûÓ¡¹ã²¥  | 
|     for itemID, itemCnt, isBind in prizeItemList:  | 
|         itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  | 
|         if not itemData:  | 
|             continue  | 
|         if itemData.GetItemColor() >= ShareDefine.Def_Item_Color_Orange:  | 
|             PlayerControl.WorldNotify(0, 'RuneTowerInfo_2', [curPlayer.GetName(), fbLevel, itemID])  | 
|           | 
|     # ·¢Óʼþ»ò·ÅÈë·ûÓ¡±³°ü  | 
|     needSpace = len(prizeItemList)  | 
|     emptySpace = ItemCommon.GetItemPackSpace(curPlayer, ShareDefine.rptRune, needSpace)  | 
|     isSendMail = int(needSpace > emptySpace) # ÊÇ·ñ·¢ËÍÓʼþ  | 
|     if isSendMail:  | 
|         PlayerControl.SendMailByKey('TowerPrize', [curPlayer.GetPlayerID()], prizeItemList)  | 
|         GameWorld.DebugLog("±³°ü¿Õ¼ä²»¹»£¬·¢ËÍÓʼþ: mailItemList=%s" % str(prizeItemList), curPlayer.GetPlayerID())  | 
|     else:  | 
|         for itemID, itemCnt, isBind in prizeItemList:  | 
|             ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [ShareDefine.rptRune],  | 
|                                             event=["RuneTower", False, {}])  | 
|                   | 
|     moneyDict = {ShareDefine.TYPE_Price_Rune:addJH, ShareDefine.TYPE_Price_Ysog:RuneMagicEssence}  | 
|     prizeDict = {FBCommon.Over_money:FBCommon.GetJsonMoneyList(moneyDict), FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(prizeItemList)}  | 
|       | 
| #    for _ in xrange(challengeCnt):  | 
| #        EventReport.WriteEvent_custom_mission_log(curPlayer, ChConfig.CME_FB_TrialTower, ChConfig.CME_Log_End, 1, cmeInfoEx=bossName)  | 
|     return prizeDict  | 
|   | 
|   | 
| def __GetEndAward(curPlayer, fbLevel):  | 
|     #½áËã½±Àø  | 
|     giveItemCountRateList = IpyGameDataPY.GetFuncEvalCfg('RuneAwardCntRate')  | 
|     giveItemCount = GameWorld.GetResultByRandomList(giveItemCountRateList)  | 
|     if not giveItemCount:  | 
|         return []  | 
|       | 
|     runeTypeList = GetRuneTypeByTowerLV(fbLevel)  | 
|     if not runeTypeList:  | 
|         return  | 
|     InitRuneTypeColorInfo(curPlayer)  | 
|       | 
|     giveItemList = []  | 
|     runeColorRateDict = IpyGameDataPY.GetFuncEvalCfg('RuneAwardColor')  | 
|     for _ in xrange(giveItemCount):  | 
|         giveRuneType = random.choice(runeTypeList)  | 
|           | 
|         if giveRuneType not in g_runeTypeDict:  | 
|             break  | 
|         runeColorRateList = GameWorld.GetDictValueByKey(runeColorRateDict, giveRuneType)  | 
|         giveColor = GameWorld.GetResultByRandomList(runeColorRateList)  | 
|         if giveColor == None:  | 
|             break  | 
|         giveItemID = g_runeTypeDict[giveRuneType].get(giveColor)  | 
|         if not giveItemID:  | 
|             continue  | 
|         giveItemList.append([giveItemID, 1, 1])  | 
|       | 
|     GameWorld.DebugLog("    Ëæ»ú¸øÎïÆ·Êý: %s, giveItemList=%s,runeTypeList=%s" % (giveItemCount, giveItemList,runeTypeList))  | 
|     return giveItemList  | 
|   | 
| ## ¸ù¾ÝÀàÐÍ»ñÈ¡·ûÓ¡ÊÇ·ñÒѽâËø  | 
| def InitRuneTypeColorInfo(curPlayer):  | 
|     global g_runeTypeDict  | 
|     if not g_runeTypeDict:  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for i in xrange(ipyDataMgr.GetRuneCount()):  | 
|             ipyData = ipyDataMgr.GetRuneByIndex(i)  | 
|             itemID = ipyData.GetID()  | 
|             itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  | 
|             if not itemData:  | 
|                 continue  | 
|             itemColor = itemData.GetItemColor()  | 
|             curEff = itemData.GetEffectByIndex(0)  | 
|             curRuneType = curEff.GetEffectID()  | 
|             if curRuneType in g_runeTypeDict:  | 
|                 g_runeTypeDict[curRuneType][itemColor] = itemID  | 
|             else:  | 
|                 g_runeTypeDict[curRuneType] = {itemColor:itemID}  | 
|     return  | 
|   | 
|   | 
| ## ·¢ËÍÌôÕ½½á¹ûÐÅÏ¢  | 
| def __SendTrialTowerOverInfo(curPlayer, fbLevel, isPass, overDict={}):  | 
|       | 
|     overDict[FBCommon.Over_dataMapID] = ChConfig.Def_FBMapID_TrialTower  | 
|     overDict[FBCommon.Over_wheel] = fbLevel  | 
|     overDict[FBCommon.Over_isPass] = int(isPass)  | 
|     GameWorld.DebugLog("__SendTrialTowerOverInfo overDict=%s" % (str(overDict)), curPlayer.GetPlayerID())  | 
|     FBCommon.Notify_FB_Over(curPlayer, overDict)  | 
|     return  | 
|   | 
|   | 
| ## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  | 
| #  @param attacker ¹¥»÷·½  | 
| #  @param defender ·ÀÊØ·½  | 
| #  @return bool  | 
| def CheckCanAttackTagObjInFB(attacker, defender):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     if gameFB.GetFBStep() != FB_State_Fighting:  | 
|         return False  | 
|     return True  | 
|   | 
| ##Íæ¼ÒËÀÍö.  | 
| # @param curPlayer:ËÀÍöµÄÍæ¼Ò   | 
| # @param tick Ê±¼ä´Á  | 
| # @return ·µ»ØÖµÎÞÒâÒå  | 
| # @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  | 
| def DoPlayerDead(curPlayer):  | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbLevel = gameFB.GetGameFBDictByKey(FBDict_Level)  | 
|     __SendTrialTowerOverInfo(curPlayer, fbLevel, False)  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     #ÓÎÏ·½áÊø  | 
|     __SetFBToFreeTime(tick)  | 
|     return  | 
|   | 
| ## ÊÇ·ñ¸±±¾¸´»î  | 
| #  @param None  | 
| #  @return ÊÇ·ñ¸±±¾¸´»î  | 
| def OnPlayerReborn():  | 
|     return True  | 
|   | 
| ## ¸±±¾ÐÐΪ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param actionType ÐÐΪÀàÐÍ  | 
| #  @param actionInfo ÐÐΪÐÅÏ¢  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| def DoFBAction(curPlayer, actionType, actionInfo, tick):  | 
|     # Ä¬ÈÏΪѡÔñ¹Ø¿¨£¬Óɿͻ§¶Ë¾ö¶¨£¬½ø³¡¼°¸±±¾Ñ¡¹ØÍ¨ÓôËÐÐΪ  | 
|     if actionInfo <= 0:  | 
|         return  | 
|       | 
|     gameFB = GameWorld.GetGameFB()  | 
|     fbStep = gameFB.GetFBStep()  | 
|       | 
|     if fbStep in [FB_State_FightPrepare, FB_State_Fighting]:  | 
|         GameWorld.DebugLog("×¼±¸»òÕ½¶·ÖÐ, ÎÞ·¨±ä¸ü¹Ø¿¨!")  | 
|         return  | 
|       | 
|     fbLevel = actionInfo  | 
|     if not __CheckCanChallenge(curPlayer, fbLevel):  | 
|         FBCommon.DoLogic_FBKickAllPlayer()  | 
|         return  | 
|       | 
|     StartFBLevel(curPlayer, fbLevel, tick)  | 
|     return  | 
|   | 
|   | 
| def GetRuneTypeByTowerLV(towerLV):  | 
|     #»ñÈ¡¹Ø¿¨¿ÉµôÂä·ûÓ¡ÀàÐÍ  | 
|     towerRuneTypeDict = IpyGameDataPY.GetFuncEvalCfg('TowerRuneType')  | 
|     return towerRuneTypeDict.get(str(towerLV/100), [])  | 
|   | 
| ## ¿É·ñɨµ´  | 
| def OnPlayerFBSweepAsk(curPlayer, mapID, lineID, sweepCnt, isFinish, dataEx):  | 
|     yesterDayPassLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_TrialTower_LastDayPassLV)  | 
|     if not yesterDayPassLV:  | 
|         GameWorld.DebugLog('    Î´Í¨¹ØÒ»²ã£¬²»ÄÜɨµ´')  | 
|         return False  | 
|     #ÅжÏɨµ´»¨·Ñ  | 
|     curDayTimes, dayTimesLimit = PlayerActivity.GetDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_TowerSD)  | 
|     if curDayTimes >= dayTimesLimit:  | 
|         GameWorld.DebugLog('    É¨µ´´ÎÊý²»×㣡')  | 
|         return  | 
|     needMoney = IpyGameDataPY.GetFuncCfg('RuneTowerSweepBuy', 2) if curDayTimes else 0  | 
|     if needMoney:  | 
|         costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, needMoney)  | 
|         if not costMoneyList:  | 
|             return  | 
|         for moneyType, moneyNum in costMoneyList:  | 
|             if not PlayerControl.PayMoney(curPlayer, moneyType, moneyNum, ChConfig.Def_Cost_FBSweep):  | 
|                 GameWorld.DebugLog("·ûÓ¡Ëþɨµ´ÏÉÓñ²»×ã!costGold=%s£¬curDayTimes=%s" % (needMoney, curDayTimes))  | 
|                 return  | 
|       | 
|     if not PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_TowerSD):  | 
|         GameWorld.DebugLog('    É¨µ´´ÎÊý²»×㣡')  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| ## É¨µ´½á¹û  | 
| def OnPlayerFBSweepResult(curPlayer, mapID, lineID, sweepCnt, isFinish, dataEx):  | 
|     passLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_TrialTower_LastDayPassLV)  | 
|     InitRuneTypeColorInfo(curPlayer)  | 
|     giveItemList = []  | 
|     floorItemDict = {} #{´ó²ãID:{itemID:itemCnt}}  | 
|     giveRunePointDict = {}  | 
|     giveRuneYsogDict = {}  | 
|     giveRunePoint = 0  | 
|     giveRuneYsog = 0  | 
|     giveItemCountRateList = IpyGameDataPY.GetFuncEvalCfg('RuneAwardCntRate', 2)  | 
|     runeColorRateDict = IpyGameDataPY.GetFuncEvalCfg('RuneAwardColor')  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetRuneTowerCount()):  | 
|         ipyData = ipyDataMgr.GetRuneTowerByIndex(i)  | 
|         towerLV = ipyData.GetID()  | 
|         floor = towerLV / 100  | 
|         if towerLV > passLV:  | 
|             break  | 
|         #·ûÓ¡¾«»ª  | 
|         giveRunePointDict[floor] = giveRunePointDict.get(floor, 0) + ipyData.GetSweepRunePoint()  | 
|         giveRunePoint += ipyData.GetSweepRunePoint()  | 
|         giveRuneYsogDict[floor] = giveRuneYsogDict.get(floor, 0) + ipyData.GetSweepYsog()  | 
|         giveRuneYsog += ipyData.GetSweepYsog()  | 
|           | 
|         giveItemCount = GameWorld.GetResultByRandomList(giveItemCountRateList)  | 
|         if not giveItemCount:  | 
|             continue  | 
|         runeTypeList = GetRuneTypeByTowerLV(towerLV)  | 
|         if not runeTypeList:  | 
|             continue  | 
|           | 
|         for _ in xrange(giveItemCount):  | 
|             giveRuneType = random.choice(runeTypeList)  | 
|               | 
|             if giveRuneType not in g_runeTypeDict:  | 
|                 break  | 
|             runeColorRateList = GameWorld.GetDictValueByKey(runeColorRateDict, giveRuneType)  | 
|             giveColor = GameWorld.GetResultByRandomList(runeColorRateList)  | 
|             if giveColor == None:  | 
|                 break  | 
|             giveItemID = g_runeTypeDict[giveRuneType].get(giveColor)  | 
|             if not giveItemID:  | 
|                 continue  | 
|             if floor in floorItemDict:  | 
|                 floorItemDict[floor][giveItemID] = floorItemDict[floor].get(giveItemID,0) +1  | 
|             else:  | 
|                 floorItemDict[floor] = {giveItemID:1}  | 
|             giveItemList.append([giveItemID, 1, 1])  | 
|         #ºÃ¶«Î÷  | 
|         goodDropDict = ipyData.GetSweepGoodDrop()  | 
|         for itemID, rate in goodDropDict.items():  | 
|             if GameWorld.CanHappen(rate):  | 
|                 giveItemList.append([itemID, 1, 1])  | 
|                 if floor in floorItemDict:  | 
|                     floorItemDict[floor][itemID] = floorItemDict[floor].get(itemID,0) +1  | 
|                 else:  | 
|                     floorItemDict[floor] = {itemID:1}  | 
|           | 
|     jsonItemDict = {}  | 
|     for floor, itemDict in floorItemDict.items():  | 
|         jsonitemList = FBCommon.GetJsonItemList(itemDict.items())  | 
|         jsonItemDict[floor] = jsonitemList  | 
|         for itemID in itemDict.keys():  | 
|             itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)  | 
|             if not itemData:  | 
|                 continue  | 
|             if itemData.GetItemColor() >= ShareDefine.Def_Item_Color_Orange:  | 
|                 PlayerControl.WorldNotify(0, 'RuneTowerInfo_3', [curPlayer.GetName(), floor, itemID])  | 
|       | 
|     if giveRunePoint:  | 
|         PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_Rune, giveRunePoint)  | 
|     if giveRuneYsog:  | 
|         PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_Ysog, giveRuneYsog)  | 
|       | 
|               | 
|     # ·¢Óʼþ»ò·ÅÈë·ûÓ¡±³°ü  | 
|     needSpace = len(giveItemList)  | 
|     emptySpace = ItemCommon.GetItemPackSpace(curPlayer, ShareDefine.rptRune, needSpace)  | 
|     isSendMail = int(needSpace > emptySpace) # ÊÇ·ñ·¢ËÍÓʼþ  | 
|     if isSendMail:  | 
|         PlayerControl.SendMailByKey('RunePackUnEnough', [curPlayer.GetPlayerID()], giveItemList)  | 
|         GameWorld.DebugLog("±³°ü¿Õ¼ä²»¹»£¬·¢ËÍÓʼþ: mailItemList=%s" % str(giveItemList), curPlayer.GetPlayerID())  | 
|     else:  | 
|         for itemID, itemCnt, isBind in giveItemList:  | 
|             ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, isBind, [ShareDefine.rptRune],  | 
|                                             event=["RuneTowerSD", False, {}])  | 
|     overDict = {FBCommon.Over_isSweep:1, FBCommon.Over_dataMapID:ChConfig.Def_FBMapID_TrialTower,  | 
|                 "SDTowerItem":jsonItemDict, "SDTowerPoint":giveRunePointDict, "SDTowerYsog":giveRuneYsogDict}  | 
|     GameWorld.DebugLog('    overDict=%s'%overDict)  | 
|     FBCommon.Notify_FB_Over(curPlayer, overDict)  | 
|     #³É¾Í  | 
|     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_TowerSD, 1)  | 
|     #BOSS¸´»î»î¶¯  | 
|     PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_TowerSweep, 1)  | 
|     return True |