| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| ##@package PlayerReincarnation  | 
| # Íæ¼ÒתÉúÂß¼  | 
| #  | 
| # @author hch  | 
| # @date 2010-4-28  | 
| # @version 2.9  | 
| #  | 
| # @change: "2010-10-08 15:00" panwei °Î³ý·þÎñÆ÷°æ±¾¿ØÖÆ´úÂë  | 
| # @change: "2013-04-11 18:00" wdb ³á°òʹÓõȼ¶ÓëÇ¿»¯µÈ¼¶Ïà¹Ø  | 
| # @change: "2013-04-15 11:00" wdb ½«ComparePlayerLV_UseItem¸üÃûΪCheckItemUseLV£¬·ÅÈëItemControler  | 
| # @change: "2015-01-28 19:30" hxp ×ªÉúÐÞ¸Ä  | 
| # @change: "2015-01-29 01:00" hxp ×ªÉúͬ²½ËùÓÐÅÅÐаñ(¸üÐÂÖ°ÒµÐÅÏ¢)  | 
| # @change: "2015-01-29 11:00" hxp Ôö¼Óתְ¹ã²¥£»¶Ò»»ÁéÁ¦ÌáÐÑ  | 
| # @change: "2015-01-30 03:30" hxp ÀϺÅÂú¼¶ÉèÖõ±Ç°¾ÑéΪ0; Âú¼¶µô¼¶Ö÷¶¯´¥·¢Ò»´ÎÉý½×¼ì²â  | 
| # @change: "2015-02-04 18:00" hxp ½µ¼¶Ë¢ÐÂÊÀ½çµÈ¼¶¼Ó³É  | 
| # @change: "2015-02-26 12:00" hxp Èýת¿ªÆô´óʦ  | 
| # @change: "2015-04-15 21:00" hxp Ò»×ª¿ªÆô×Ë̬  | 
| # @change: "2015-05-11 14:00" hxp ¶Ò»»ÁéÁ¦Ê§°ÜÔö¼ÓÁ÷Ïò  | 
| # @change: "2015-07-29 15:20" xdh ´óʦ¸Ä³ÉµÈ¼¶¿ªÆô  | 
| # @change: "2015-08-04 15:00" ljd ¶þת½û¿ªÃ·À¼  | 
| # @change: "2015-08-24 14:40" zqx Ôö¼ÓתÉú³É¾Í  | 
| # @change: "2015-12-10 12:00" hxp ×ªÉúÂß¼ÐÞ¸Ä(ÓÀºãÁìÖ÷)  | 
| # @change: "2016-05-26 16:20" xdh Ôö¼ÓתÉú×î´ó¿ª·ÅµÈ¼¶ÅäÖà  | 
| # @change: "2017-01-13 14:00" xdh Ôö¼ÓתÉú½±ÀøÁìÈ¡  | 
| # @change: "2017-03-26 17:30" hxp ×ªÉúÔùË͵ȼ¶¿ª³öÅäÖà  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2017-03-26 17:30"""  | 
| #---------------------------------------------------------------------  | 
| import ReadChConfig  | 
| import ChConfig  | 
| import PlayerControl  | 
| import GameWorld  | 
| import IPY_GameWorld  | 
| import PlayerBillboard  | 
| import DataRecordPack  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import ShareDefine  | 
| import ItemCommon  | 
| import PlayerWorldAverageLv  | 
| import PlayerSuccess  | 
| import ItemControler  | 
| import ChPlayer  | 
| #---------------------------------------------------------------------  | 
|   | 
| (  | 
| Def_ExReiki_DayFreeCnt, # Ã¿ÈÕÃâ·Ñ´ÎÊý  | 
| Def_ExReiki_CostMoney, # ÏûºÄ½ð±ÒÊý  | 
| Def_ExReiki_SuccRate, # ¶Ò»»³É¹¦ÂÊ  | 
| Def_ExReiki_Format, # »ñµÃÁéÁ¦¹«Ê½  | 
| ) = range(4)  | 
|   | 
|   | 
| ## ×ªÉúOnDay  | 
| #  @param curPlayer:  | 
| #  @return: None   | 
| def ReincarOnDay(curPlayer):  | 
|     return  | 
|   | 
| ## ×ªÉúOnLogin  | 
| #  @param curPlayer:  | 
| #  @return: None   | 
| def ReincarOnLogin(curPlayer):  | 
|     SyncReincarnationAwardRecord(curPlayer)  | 
|     return  | 
|   | 
| ## »ñÈ¡Íæ¼ÒתÉúÏà¹Ø×ÖµäÖµ  | 
| #  @param curPlayer:  | 
| #  @return: None   | 
| def __GetPlayerReincDictValue(curPlayer, key, defaultValue=0):  | 
|     return curPlayer.NomalDictGetProperty(key, defaultValue, ChConfig.Def_PDictType_Reincarnation)  | 
|   | 
|   | 
| ## ÉèÖÃÍæ¼ÒתÉúÏà¹Ø×ÖµäÖµ  | 
| #  @param curPlayer:  | 
| #  @return: None   | 
| def __SetPlayerReincDictValue(curPlayer, key, value):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, key, value, ChConfig.Def_PDictType_Reincarnation)  | 
|     return  | 
|   | 
| ## ¼ÆËãתְ¸½¼ÓÊôÐÔ  | 
| #  @param curPlayer Íæ¼Ò  | 
| #  @param allAttrList ÊôÐÔÁÐ±í  | 
| #  @return None  | 
| def CalcReincarnationAttr(curPlayer, allAttrList):  | 
|     curReinCnt = curPlayer.GetReincarnationLv() # µ±Ç°×ªÉú´ÎÊý  | 
|   | 
|     if curReinCnt <= 0:  | 
|         return  | 
|       | 
|     Reincarnation_AttrDict = ReadChConfig.GetEvalChConfig("Reincarnation_Attr")  | 
|       | 
|     attrNameList = [ChConfig.AttrName_BothAtk, # Ë«¹¥  | 
|                     ChConfig.AttrName_Def, # ·ÀÓù  | 
|                     ChConfig.AttrName_Hit, # ÃüÖÐ  | 
|                     ChConfig.AttrName_DefRate, # ÉÁ±Ü  | 
|                     ChConfig.AttrName_MaxHP, # ×î´óѪÁ¿  | 
|                     ]  | 
|   | 
|     for reinCnt, attrList in Reincarnation_AttrDict.items():  | 
|           | 
|         if reinCnt > curReinCnt:  | 
|             continue  | 
|           | 
|         # ¼ÆËã×ÔÉíÊôÐÔ  | 
|         for index, value in enumerate(attrList):  | 
|             attrName = attrNameList[index]  | 
|             PlayerControl.CalcAttrDict_Type(attrName, value, allAttrList)  | 
|               | 
|     return  | 
|   | 
|   | 
| ## ×ªÉúÂß¼Èë¿Ú  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def DoPlayerReincarnation(curPlayer):  | 
|     curReinCnt = curPlayer.GetReincarnationLv() # µ±Ç°×ªÉú´ÎÊý  | 
|     Reincarnation_Condition = ReadChConfig.GetEvalChConfig("Reincarnation_Condition")  | 
|     nextReinCnt = curReinCnt + 1  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     GameWorld.Log("Íæ¼ÒתÉú£ºÒÑת´ÎÊý(%s)" % (curReinCnt), playerID)  | 
|     ReincarnationMaxLV = ReadChConfig.GetEvalChConfig("ReincarnationMaxLV")  | 
|     if nextReinCnt > ReincarnationMaxLV: #´óÓÚ¿ª·ÅתÉúµÈ¼¶  | 
|         PlayerControl.NotifyCode(curPlayer, 'GeRen_liubo_32161')  | 
|         return  | 
|       | 
|     if nextReinCnt not in Reincarnation_Condition:  | 
|         GameWorld.ErrLog("²»´æÔÚ¸ÃתÉú´ÎÊý¶ÔÓ¦Ìõ¼þÐÅÏ¢£¡´ÎÊý=%s" % (nextReinCnt), playerID)  | 
|         return  | 
|       | 
|     needLV, nMoney, nZhenQi, nDHPassCnt, nChasmPassCnt, nItemList, prizeLVCnt = Reincarnation_Condition[nextReinCnt]  | 
|     curLV = curPlayer.GetLV()  | 
|     if not __DoProcessReinCondition(curPlayer, needLV, nMoney, nZhenQi, nDHPassCnt, nChasmPassCnt, nItemList, nextReinCnt):  | 
|         return  | 
|       | 
|     # Èç¹ûתÉúµÄʱºò¸ÕºÃÊÇתÉúËùÐèµÈ¼¶£¬ÔòĬÈÏËÍÒ»¼¶¾Ñé  | 
|     giveExp = 0  | 
|     if curLV == needLV:  | 
|         for i in range(prizeLVCnt):  | 
|             prizeLV = curLV + i  | 
|             prizeLVUPExp = PlayerControl.GetTotalExpByPlayerLv(prizeLV)  | 
|             giveExp += prizeLVUPExp  | 
|             GameWorld.Log("    ×ªÉúÔùË͵ȼ¶, prizeLV=%s,prizeLVUPExp=%s,giveExp=%s" % (prizeLV, prizeLVUPExp, giveExp), playerID)  | 
|     GameWorld.Log("    ×ªÉúÀÛ¼ÆÔùËÍ×ܾÑé, prizeLVCnt=%s,giveExp=%s" % (prizeLVCnt, giveExp), playerID)  | 
|           | 
|     curPlayer.SetReincarnationLv(nextReinCnt)  | 
|     #Éý¼¶Ç°¼Ç¼תÉúʱ¼ä  | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_LastReinTick, tick)  | 
|       | 
|     playerControl = PlayerControl.PlayerControl(curPlayer)  | 
|     playerControl.PlayerLvUp()  | 
|     playerControl.AddExp(giveExp)  | 
|       | 
|     DataRecordPack.DR_PlayerLVExChange(curPlayer, curReinCnt, curLV, "Reincarnation")  | 
|       | 
|     #תְ³É¹¦µÄ»°¸üÐÂËùÓÐÅÅÐаñ£¬Ö°ÒµÏÔʾÐÅÏ¢ÐèÒª±ä¸ü  | 
|     PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer)  | 
|       | 
|     #תְ³É¹¦¹ã²¥  | 
|     PlayerControl.WorldNotify(0, "GeRen_hgg_543685", [curPlayer.GetPlayerName(), nextReinCnt])  | 
|       | 
|       | 
|     return  | 
|   | 
| def __DoProcessReinCondition(curPlayer, needLV, nMoney, nZhenQi, nDHPassCnt, nChasmPassCnt, nItemList, nextReinCnt):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     curLV = curPlayer.GetLV()  | 
|     GameWorld.Log("´¦ÀíתÉúÌõ¼þ curLV=%s,needLV=%s,nMoney=%s,nZhenQi=%s,nDHPassCnt=%s,nItemList=%s"   | 
|                   % (curLV, needLV, nMoney, nZhenQi, nDHPassCnt, str(nItemList)), playerID)  | 
|       | 
|     if curLV < needLV:  | 
|         PlayerControl.NotifyCode(curPlayer, 'GeRen_mx_327925')  | 
|         GameWorld.Log("    µÈ¼¶²»×㣬ÎÞ·¨×ªÉú£¡needLV=%s,curLV=%s" % (needLV, curLV), playerID)  | 
|         return False  | 
|       | 
|     if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, nMoney):  | 
|         GameWorld.Log("    ½ð±Ò²»×㣬ÎÞ·¨×ªÉú£¡nMoney=%s" % (nMoney), playerID)  | 
|         return False  | 
|       | 
|     if PlayerControl.GetZhenQi(curPlayer) < nZhenQi:  | 
|         PlayerControl.NotifyCode(curPlayer, 'GeRen_pan_367906')  | 
|         GameWorld.Log("    ÕæÆø²»×㣬ÎÞ·¨×ªÉú£¡nZhenQi=%s" % (nZhenQi), playerID)  | 
|         return False  | 
|       | 
|     itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  | 
|     allIndexList = []  | 
|     for itemID, needCnt in nItemList:  | 
|         enough, indexList, hasBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(itemID, itemPack, needCnt)  | 
|         if not enough:  | 
|             PlayerControl.NotifyCode(curPlayer, 'Horse_lhs_31379', [itemID])  | 
|             GameWorld.Log("    ËùÐèתÉúÎïÆ·²»×㣬ÎÞ·¨×ªÉú£¡itemID=%s,needCnt=%s" % (itemID, needCnt), playerID)  | 
|             return False  | 
|         allIndexList.append([indexList, needCnt])  | 
|       | 
|     ## Ìõ¼þÅжÏͨ¹ý£¬¿ªÊ¼¿Û³ý  | 
|     # ¿Û½ð±Ò  | 
|     infoDict = {ChConfig.Def_Cost_Reason_SonKey:nextReinCnt}  | 
|     if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, nMoney, ChConfig.Def_Cost_Reincarnation, infoDict):  | 
|         GameWorld.ErrLog("Reincarnation pay Err: silver-Money:%s)" % nMoney, playerID)  | 
|         return False  | 
|       | 
|     # ¿ÛÕæÆø  | 
|     PlayerControl.PlayerLostZhenQi(curPlayer, nZhenQi, "Reincarnation", {"ReinCount":nextReinCnt})  | 
|       | 
|     # ¿ÛÎïÆ·  | 
|     for indexList, delCnt in allIndexList:  | 
|         ItemCommon.ReduceItem(curPlayer, itemPack, indexList, delCnt, False, "Reincarnation")  | 
|           | 
|     return True  | 
|   | 
|   | 
| ## ÁìȡתÉú½±Àø  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @param awardType: Áì½±ÀàÐÍ  | 
| #  @param tick: Ê±¼ä´Á  | 
| #  @return  | 
| def GetReincarnationAward(curPlayer, dataEx):  | 
|     curReinCnt = curPlayer.GetReincarnationLv() # µ±Ç°×ªÉú´ÎÊý  | 
|     if dataEx > curReinCnt:  | 
|         GameWorld.DebugLog('GetReincarnationAward Íæ¼ÒתÉúµÈ¼¶%s, ²»¿ÉÁìÈ¡%sתµÄ½±Àø' % (curReinCnt, dataEx))  | 
|         return  | 
|       | 
|     reincarnationAwardDict = ReadChConfig.GetEvalChConfig("Reincarnation_Award")  | 
|     if dataEx not in reincarnationAwardDict:  | 
|         GameWorld.DebugLog('Reincarnation_Award.txt ²»´æÔÚ¸ÃתÉúµÈ¼¶½±Àø dataEx=%s' % dataEx)  | 
|         return  | 
|     reinLVList = reincarnationAwardDict.keys()  | 
|     reinLVList.sort()  | 
|     awardIndex = reinLVList.index(dataEx)  | 
|       | 
|     awardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Reinc_AwardRecord, 0)  | 
|     if awardRecord & pow(2, awardIndex):  | 
|         GameWorld.DebugLog("תÉú½±ÀøÒѾÁìÈ¡¹ý! ²»ÄÜÖØ¸´ÁìÈ¡£¡", curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     prizeItemInfo = reincarnationAwardDict[dataEx]  | 
|     # ¼ì²é±³°ü  | 
|     packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem)  | 
|     if len(prizeItemInfo) > packSpace:  | 
|         PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_998371")  | 
|         return  | 
|       | 
|     updRecord = awardRecord | pow(2, awardIndex)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Reinc_AwardRecord, updRecord)  | 
|       | 
|     SyncReincarnationAwardRecord(curPlayer)  | 
|       | 
|     # ¸ø½±Àø  | 
|     for awardItem in prizeItemInfo:  | 
|         # ×Öµä½á¹¹Ðè񻂿·ÖÖ°Òµ  | 
|         if isinstance(awardItem, dict):  | 
|             if curPlayer.GetJob() not in awardItem:  | 
|                 GameWorld.ErrLog("    Reincarnation_Award.txt Ö°Òµ(%s)δÅäÖý±Àø!dataEx=%s" % (curPlayer.GetJob(), dataEx))  | 
|                 continue  | 
|             awardItem = awardItem[curPlayer.GetJob()]  | 
|               | 
|         if len(awardItem) != 4:  | 
|             GameWorld.ErrLog("    Reincarnation_Award.txt ½±ÀøÅäÖøñʽ´íÎó!len(%s) != 4, dataEx=%s" % (awardItem, dataEx))  | 
|             continue  | 
|         itemID, itemCount, isBind, isAppoint = awardItem  | 
|         if isAppoint:  | 
|             ItemControler.GivePlayerAppointItem(curPlayer, itemID, isBind, True, True)  | 
|         else:  | 
|             ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isBind, [IPY_GameWorld.rptItem], True, showSysInfo=True)  | 
|       | 
|       | 
|     GameWorld.Log('ÁìȡתÉú½±Àø³É¹¦£¬dataEx=%s' % dataEx)  | 
|     return  | 
|   | 
| ## Í¬²½×ªÉú½±ÀøÁì½±¼Ç¼  | 
| #  @param curPlayer: Íæ¼ÒʵÀý  | 
| #  @return  | 
| def SyncReincarnationAwardRecord(curPlayer):  | 
|     record = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Reinc_AwardRecord, 0)  | 
|     #ChPlayer.Sync_RewardGetRecordInfo(curPlayer, ShareDefine.Def_RewardType_Reincarnation, record)  | 
|     return  | 
|   | 
|   | 
| #// A5 46 ¶Ò»»ÁéÁ¦ #tagCMExchangeReiki  | 
| #  | 
| #struct    tagCMExchangeReiki  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        ExType;    //¶Ò»»ÀàÐÍ0-½µ¼¶¶Ò»»; 1-×êʯ¹ºÂò  | 
| #    BYTE        ExData;    //¶Ò»»À©Õ¹Êý¾Ý(×êʯ¹ºÂò¿É·¢Ë͹ºÂòµÄÏûºÄË÷Òý)  | 
| #};  | 
| ## ¶Ò»»ÁéÁ¦  | 
| #  @param index: Íæ¼ÒË÷Òý  | 
| #  @param clientData: ·â°ü½á¹¹Ìå  | 
| #  @param tick: Ê±¼ä´Á  | 
| #  @return: None  | 
| def OnExchangeReiki(index, clientData, tick):  | 
|     return  | 
| #    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
| #      | 
| #    ExType = clientData.ExType  | 
| #    ExData = clientData.ExData  | 
| #      | 
| #    # ½µ¼¶¶Ò»»  | 
| #    if ExType == 0:  | 
| #        __DoExchangeReikiByDownLVEx(curPlayer)  | 
| #    # ×êʯ¹ºÂò  | 
| #    elif ExType == 1:  | 
| #        __DoExchangeReikiByGold(curPlayer, ExData)  | 
| #    return  | 
|   | 
| ### ×êʯ¶Ò»»ÁéÁ¦  | 
| ##  @param curPlayer: Íæ¼ÒË÷Òý  | 
| ##  @param index: ¶Ò»»Ë÷Òý  | 
| ##  @return: None  | 
| #def __DoExchangeReikiByGold(curPlayer, index):  | 
| #    playerID = curPlayer.GetPlayerID()  | 
| #    ExchangeReikiByGoldList = ReadChConfig.GetEvalChConfig("ExchangeReikiByGold")  | 
| #      | 
| #    if index < 0 or index >= len(ExchangeReikiByGoldList):  | 
| #        GameWorld.ErrLog("×êʯ¶Ò»»×ªÉúÁéÁ¦ÅäÖôíÎó: Ã»ÓиÃË÷ÒýÐÅÏ¢£¡ index=%s" % (index), playerID)  | 
| #        return  | 
| #      | 
| #    needGold, addReiki = ExchangeReikiByGoldList[index]  | 
| #    if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, needGold):  | 
| #        # Ôª±¦²»×ãʱ·µ»Ø  | 
| #        GameWorld.DebugLog("×êʯ¶Ò»»ÁéÁ¦£¬×êʯ²»×ã needGold=%s" % needGold, playerID)  | 
| #        return  | 
| #      | 
| #    # Ö§¸¶Ôª±¦  | 
| #    if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, needGold,  | 
| #                                  costType = ShareDefine.Def_GoldCostType_ExchangeReiki):  | 
| #        return  | 
| #      | 
| #    curReiki = __GetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_Reiki)  | 
| #    updReiki = curReiki + addReiki  | 
| #    __SetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_Reiki, updReiki)  | 
| #    PlayerControl.NotifyCode(curPlayer, "GeRen_hgg_960792", [addReiki])  | 
| #    GameWorld.Log("×êʯ¶Ò»»×ªÉúÁéÁ¦: index=%s,curReiki=%s,addReiki=%s,updReiki=%s"   | 
| #                  % (index, curReiki, addReiki, updReiki), playerID)  | 
| #    Sync_PlayerReikiInfo(curPlayer)  | 
| #    return  | 
|   | 
|   | 
| ### ½µ¼¶¶Ò»»ÁéÁ¦  | 
| ##  @param curPlayer: Íæ¼ÒË÷Òý  | 
| ##  @return: None  | 
| #def __DoExchangeReikiByDownLVEx(curPlayer):  | 
| #    curLVEx = curPlayer.GetLVEx()  | 
| #    curReincarLV = curPlayer.GetReincarnationLv()  | 
| #  | 
| #    Reincarnation_Condition = ReadChConfig.GetEvalChConfig("Reincarnation_Condition")  | 
| #    nextReincarLV = curReincarLV + 1  | 
| #    playerID = curPlayer.GetPlayerID()  | 
| #      | 
| #    # Èç¹ûÓÐÏÂһת£¬Ôò×îµÍ²»Äܽµµ½×ªÉúËùÐèµÈ¼¶  | 
| #    if nextReincarLV in Reincarnation_Condition:  | 
| #        needLV = Reincarnation_Condition[nextReincarLV][0]  | 
| #        if curLVEx <= needLV:  | 
| #            GameWorld.ErrLog("×îµÍ²»Äܽµµ½Ï´ÎתÉúËùÐèµÈ¼¶: curReincarLV=%s,curLVEx=%s,nextReincarLV=%s,needLV=%s"   | 
| #                             % (curReincarLV, curLVEx, nextReincarLV, needLV), playerID)  | 
| #            return  | 
| #      | 
| #    ExchangeReikiByLVExDict = ReadChConfig.GetEvalChConfig("ExchangeReikiByLVEx")  | 
| #      | 
| #    if curReincarLV not in ExchangeReikiByLVExDict:  | 
| #        return  | 
| #      | 
| #    ExchangeReikiByLVEx = ExchangeReikiByLVExDict[curReincarLV]  | 
| #      | 
| #    dayFreeCnt = ExchangeReikiByLVEx[Def_ExReiki_DayFreeCnt]  | 
| #    costMoney = ExchangeReikiByLVEx[Def_ExReiki_CostMoney]  | 
| #    succRate = ExchangeReikiByLVEx[Def_ExReiki_SuccRate]  | 
| #    getReikiFormat = ExchangeReikiByLVEx[Def_ExReiki_Format]  | 
| #      | 
| #    # ÅжϴÎÊý  | 
| #    exCnt = __GetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_ChangeReikiCnt)  | 
| #    addCnt = __GetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_ChangeReikiAddCnt)  | 
| #    maxCnt = dayFreeCnt + addCnt  | 
| #    if exCnt >= maxCnt:  | 
| #        GameWorld.Log("½µ¼¶¶Ò»»ÁéÁ¦£º¶Ò»»´ÎÊýÒÑÂú£¡exCnt=%s,dayFreeCnt=%s,addCnt=%s,maxCnt=%s"   | 
| #                      % (exCnt, dayFreeCnt, addCnt, maxCnt), playerID)  | 
| #        return  | 
| #      | 
| #    # ÅжϽð±Ò  | 
| #    if costMoney > 0 and not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, costMoney):  | 
| #        return  | 
| #          | 
| #    maxExp = PlayerControl.GetTotalExpByPlayerLv(curLVEx)  | 
| #    isFull = False  | 
| #    # Âú¼¶µÄ  | 
| #    if maxExp <= 0:  | 
| #        # ¾ÑéÉÏÏÞ¸ÄΪ¿É³¬¹ý20Òں󣬸ò¿·ÖÂß¼ÔÝʱ²»´¦Àí£¬Ö»×öreturn£¬ Ö®ºóÓõ½¸Ã¹¦ÄÜÔÙÓÅ»¯  | 
| #        return  | 
| #        curExp = curPlayer.GetTotalExp()  | 
| #        curExp = min(curExp, ChConfig.Def_UpperLimit_DWord)  | 
| #        maxExp = ChConfig.Def_UpperLimit_DWord  | 
| #        isFull = True  | 
| #    else:  | 
| #        curExp = PlayerControl.GetPlayerTotalExp(curPlayer)  | 
| #          | 
| #    curExpPer = curExp * 1.0 / maxExp  | 
| #          | 
| #    updLVEx = curLVEx - 1  | 
| #    if updLVEx <= 0:  | 
| #        return  | 
| #      | 
| #    updMaxExp = PlayerControl.GetTotalExpByPlayerLv(updLVEx)  | 
| #    if not updMaxExp:  | 
| #        return  | 
| #      | 
| #    # ¿ÛÇ®£¬Ôö¼Ó¶Ò»»´ÎÊý  | 
| #    if costMoney > 0:  | 
| #        PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Silver_Money, costMoney)  | 
| #          | 
| #    __SetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_ChangeReikiCnt, exCnt + 1)  | 
| #      | 
| #    addDataDict = {"succRate":succRate}  | 
| #    # ¸ÅÂʶһ»  | 
| #    if GameWorld.CanHappen(succRate):  | 
| #        addReiki = eval(getReikiFormat)  | 
| #        curReiki = __GetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_Reiki)  | 
| #        updReiki = curReiki + addReiki  | 
| #        addDataDict["isSuccess"] = 1  | 
| #        addDataDict.update({"curReiki":curReiki, "addReiki":addReiki, "updReiki":updReiki})  | 
| #        __SetPlayerReincDictValue(curPlayer, ChConfig.Def_PDict_Reinc_Reiki, updReiki)  | 
| #  | 
| #        PlayerControl.NotifyCode(curPlayer, "GeRen_hgg_960792", [addReiki])  | 
| #        updExp = int(updMaxExp * curExpPer) # ½µ¼¶ºóµÄ¾Ñé  | 
| #        curPlayer.SetLVEx(updLVEx)  | 
| #        PlayerControl.SetPlayerTotalExp(curPlayer, updExp)  | 
| #          | 
| #        addDataDict.update({"curExp":curExp, "maxExp":maxExp, "updExp":updExp, "updMaxExp":updMaxExp})  | 
| #        GameWorld.DebugLog("½µ¼¶¶Ò»»ÁéÁ¦£ºaddDataDict=%s" % str(addDataDict), playerID)  | 
| #          | 
| #        if isFull:  | 
| #            PlayerControl.PlayerControl(curPlayer).PlayerLvUp()  | 
| #              | 
| #        #¸üÐÂÊÀ½çµÈ¼¶  | 
| #        PlayerWorldAverageLv.UpdatePlayerWorldAverageLv(curPlayer)  | 
| #    else:  | 
| #        addDataDict["isSuccess"] = 0  | 
| #        PlayerControl.NotifyCode(curPlayer, "GeRen_hgg_161234")  | 
| #  | 
| #    # ×ªÉúµÈ¼¶±ä¸üÁ÷Ïò  | 
| #    DataRecordPack.DR_PlayerLVExChange(curPlayer, curReincarLV, curLVEx, "ExchangeReiki", addDataDict)  | 
| #    Sync_PlayerReikiInfo(curPlayer)  | 
| #    return  | 
|   | 
|   | 
| #// A5 47 Íæ¼ÒתÉú #tagCMReincarnation  | 
| #  | 
| #struct    tagCMReincarnation  | 
| #{  | 
| #    tagHead        Head;  | 
| #};  | 
| ## ¶Ò»»ÁéÁ¦  | 
| #  @param index: Íæ¼ÒË÷Òý  | 
| #  @param clientData: ·â°ü½á¹¹Ìå  | 
| #  @param tick: Ê±¼ä´Á  | 
| #  @return: None  | 
| def OnReincarnation(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     DoPlayerReincarnation(curPlayer)  | 
|     return  | 
|   | 
| ##------------------------------------------------------------------------------  |