#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package PlayerAction  
 | 
#  
 | 
# @todo:Íæ¼Ò»î¶¯Ä£¿é  
 | 
# @author hxp  
 | 
# @date 2013-12-23 14:00  
 | 
# @version 2.0  
 | 
#  
 | 
# @change: "2014-10-29 15:30" hxp Ôö¼Ó½ÚÈÕ¶Ò»»ÎïÆ·»î¶¯  
 | 
# @change: "2014-12-03 21:30" hxp ¸ù¾Ýʱ¼ä»î¶¯Ìí¼ÓÍæ¼Òbuff  
 | 
# @change: "2014-12-06 22:30" hxp »î¶¯buff״̬±ä¸ü  
 | 
# @change: "2015-01-06 13:30" hxp Ôö¼ÓÕÒ²»µ½buff¼¼ÄÜÊý¾Ý·À´í; Ôö¼Ó¶Ò»»ÎïÆ·¹ã²¥Ö§³Ö  
 | 
# @change: "2015-01-06 21:00" hxp Ôö¼Ó¸ù¾Ý»î¶¯keyÖØÖÃÎïÆ·¶Ò»»¼Ç¼  
 | 
# @change: "2015-03-21 21:30" hxp Ôö¼Ó¸öÈ˵ôÂäÖÜÆÚ¿ØÖÆ  
 | 
# @change: "2015-04-15 19:30" hxp Ôö¼Ó±³°üÖиöÊýÏÞÖÆ  
 | 
# @change: "2015-04-28 16:00" hxp ÎïÆ·¶Ò»»Ö§³Ö¶Ò»»¶à¸öÎïÆ·  
 | 
# @change: "2016-08-30 21:30" hxp È«·þ¹ã²¥ÓÅ»¯  
 | 
# @change: "2016-09-19 10:30" hxp È«·þÍæ¼ÒÈËÊý»ñÈ¡·½Ê½ÐÞ¸Ä  
 | 
#  
 | 
# ÏêϸÃèÊö: Íæ¼Ò»î¶¯Ä£¿é  
 | 
#  
 | 
#---------------------------------------------------------------------  
 | 
#"""Version = 2016-09-19 10:30"""  
 | 
#---------------------------------------------------------------------  
 | 
  
 | 
import ReadChConfig  
 | 
import GameWorld  
 | 
import PlayerControl  
 | 
import ItemCommon  
 | 
import ItemControler  
 | 
import IPY_GameWorld  
 | 
import ChPyNetSendPack  
 | 
import DataRecordPack  
 | 
import NetPackCommon  
 | 
import ShareDefine  
 | 
import SkillCommon  
 | 
import SkillShell  
 | 
import BuffSkill  
 | 
import ChConfig  
 | 
  
 | 
import math  
 | 
import time  
 | 
  
 | 
#----------------------------------------------------------------------  
 | 
  
 | 
# ½±ÀøÐÅÏ¢Ë÷Òý¶¨Òå  
 | 
(  
 | 
Def_AwardInfo_PlayerMinLV, # ²ÎÓë»î¶¯Íæ¼Ò×îµÍµÈ¼¶ÏÞÖÆ  
 | 
Def_AwardInfo_DropRate, # µôÂä»î¶¯ÎïÆ·¸ÅÂÊ  
 | 
Def_AwardInfo_RandomItemList, # Ëæ»úÎïÆ·ÁÐ±í  
 | 
Def_AwardInfo_ItemInfoDict, # ÎïÆ·Ïà¹ØÐÅÏ¢  
 | 
) = range(4)  
 | 
  
 | 
# ÎïÆ·ÐÅÏ¢Ë÷Òý¶¨Òå  
 | 
(  
 | 
Def_ItemInfo_IsBind, # ÊÇ·ñ°ó¶¨  
 | 
Def_ItemInfo_Circle, # µôÂäÖÜÆÚ£¬Ãë  
 | 
Def_ItemInfo_CircleSelf, # ¸öÈ˵ôÂäÖÜÆÚ£¬Ãë  
 | 
Def_ItemInfo_MaxCnt, # ±³°üÖÐ×î´ó¸öÊý  
 | 
) = range(4)  
 | 
  
 | 
##»ñÈ¡»÷ɱNPC»î¶¯ÎïÆ·½±Àø  
 | 
# @param lastTimeHurtObj ²¹µ¶Õß(Íæ¼Ò£¬×é¶Ó)  
 | 
# @param curNPC »÷ɱµÄNPC  
 | 
# @return None  
 | 
def GetAwardOnKillNPC(lastTimeHurtObj, curNPC):   
 | 
    actionAward = ReadChConfig.GetEvalChConfig("PlayerActionAward")  
 | 
    if not actionAward:  
 | 
        GameWorld.ErrLog("Info is null! Please check PlayerActionAward.txt!")  
 | 
        return  
 | 
      
 | 
    gameWorldMgr = GameWorld.GetGameWorld()  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    for keyInfo, awardInfo in actionAward.items():  
 | 
          
 | 
        if len(keyInfo) != 2:  
 | 
            GameWorld.ErrLog("keyInfo=%s len!=2 error! Check PlayerActionAward.txt!" % str(keyInfo))  
 | 
            continue  
 | 
          
 | 
        if gameWorldMgr.GetGameWorldDictByKey(keyInfo[0]) != keyInfo[1]:  
 | 
            #GameWorld.DebugLog("keyInfo[0]=%s,keyInfo[1]=%s" % (keyInfo[0], keyInfo[1]))  
 | 
            continue  
 | 
          
 | 
        if len(awardInfo) != 4:  
 | 
            GameWorld.ErrLog("keyInfo=%s awardInfo len!=4 error! Check PlayerActionAward.txt!" % str(keyInfo))  
 | 
            continue  
 | 
          
 | 
        curPlayer, curTeam = lastTimeHurtObj  
 | 
          
 | 
        #²¹µ¶ÊÇÍæ¼Ò  
 | 
        if curPlayer:  
 | 
            __DoPlayerGetActionAward(keyInfo, curPlayer, curNPC, awardInfo, tick)  
 | 
          
 | 
        #²¹µ¶ÊÇ×é¶Ó  
 | 
        elif curTeam:  
 | 
            #¶ÓÔ±ÁÐ±í  
 | 
            playerlist = PlayerControl.GetAreaTeamMember(curTeam, curNPC.GetPosX(), curNPC.GetPosY())      
 | 
            #±éÀú×é¶Ó¶ÓÔ±½øÐзÖÏíÁ¬Õ¶ÊýºÍ¾Ñé¼Ó³É  
 | 
            for curPlayer in playerlist:  
 | 
                __DoPlayerGetActionAward(keyInfo, curPlayer, curNPC, awardInfo, tick)  
 | 
                  
 | 
    return  
 | 
  
 | 
  
 | 
##¶Ôµ¥¸öÍæ¼Ò½øÐл÷ɱNPC»î¶¯Áì½±´¦Àí  
 | 
# @param keyInfo »î¶¯keyÐÅÏ¢  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param curNPC »÷ɱµÄNPC  
 | 
# @param awardInfo ½±ÀøÐÅÏ¢  
 | 
# @param tick Ê±¼ä  
 | 
# @return None  
 | 
def __DoPlayerGetActionAward(keyInfo, curPlayer, curNPC, awardInfo, tick):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
      
 | 
    if curPlayer.GetLV() < awardInfo[Def_AwardInfo_PlayerMinLV]:  
 | 
        #GameWorld.DebugLog("__DoPlayerGetActionAward playerLV Limit!")  
 | 
        return  
 | 
      
 | 
    npcLV = curNPC.GetLV()  
 | 
    curPlayerLV = curPlayer.GetLV()  
 | 
    #GameWorld.DebugLog("curPlayerLV=%s" % curPlayerLV)  
 | 
    modulus = 1  
 | 
    rate = awardInfo[Def_AwardInfo_DropRate] * modulus  
 | 
    #GameWorld.DebugLog("__DoPlayerGetActionAward modulus=%s,rate=%s" % (modulus, rate))  
 | 
    if not GameWorld.CanHappen(rate):  
 | 
        return  
 | 
      
 | 
    itemID = GameWorld.GetResultByRandomList(awardInfo[Def_AwardInfo_RandomItemList])  
 | 
      
 | 
    itemInfoDict = awardInfo[Def_AwardInfo_ItemInfoDict]  
 | 
    if not itemInfoDict:  
 | 
        return  
 | 
      
 | 
    itemInfo = itemInfoDict.get(itemID, [])  
 | 
    if not itemInfo:  
 | 
        GameWorld.ErrLog("itemInfo Error! Check PlayerActionAward.txt! itemID=%s,awardInfo=%s,"   
 | 
                                                        % (itemID, str(awardInfo)))  
 | 
        return  
 | 
      
 | 
    #GameWorld.DebugLog("__DoPlayerGetActionAward itemID=%s,itemInfo=%s" % (itemID, str(itemInfo)))  
 | 
    # ¼ì²éµôÂäÖÜÆÚ  
 | 
    circleTime = itemInfo[Def_ItemInfo_Circle]  
 | 
    if circleTime > 0:  
 | 
        # keyName_sign_itemID  
 | 
        lastDropTickKey = "%s_%s_%d" % (keyInfo[0], keyInfo[1], itemID)  
 | 
        gameWorldMgr = GameWorld.GetGameWorld()  
 | 
        lastDropTick = gameWorldMgr.GetGameWorldDictByKey(lastDropTickKey)  
 | 
        # µôÂäÖÜÆÚÏÞÖÆ  
 | 
        if tick - lastDropTick < circleTime * 1000:  
 | 
            return  
 | 
        #GameWorld.DebugLog("lastDropTickKey=%s,lastDropTick=%s,tick=%s,circleTime=%s,passTime=%s"   
 | 
        #                % (lastDropTickKey, lastDropTick, tick, circleTime * 1000, tick - lastDropTick))  
 | 
        GameWorld.GetGameWorld().SetGameWorldDict(lastDropTickKey, tick)  
 | 
          
 | 
    # ¸öÈ˵ôÂäÖÜÆÚ  
 | 
    if len(itemInfo) > Def_ItemInfo_CircleSelf:  
 | 
        circleTimeSelf = itemInfo[Def_ItemInfo_CircleSelf]  
 | 
        if circleTimeSelf > 0:  
 | 
            lastDropTimeSelfKey = ChConfig.Def_PDict_ActionItemDropTime % itemID  
 | 
            lastDropTime = curPlayer.NomalDictGetProperty(lastDropTimeSelfKey)  
 | 
            curTime = int(time.time())  
 | 
            if curTime - lastDropTime < circleTimeSelf:  
 | 
                return  
 | 
            PlayerControl.NomalDictSetProperty(curPlayer, lastDropTimeSelfKey, curTime)  
 | 
      
 | 
    # ±³°üÖиöÊýÏÞÖÆ  
 | 
    if len(itemInfo) > Def_ItemInfo_MaxCnt:  
 | 
        packMaxItemCnt = itemInfo[Def_ItemInfo_MaxCnt]  
 | 
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  
 | 
        hasEnough = ItemCommon.GetItem_FromPack_ByID(itemID, itemPack, packMaxItemCnt)[0]  
 | 
        if hasEnough:  
 | 
            #GameWorld.DebugLog("»î¶¯ÎïÆ·ÒÑ´ïµ½±³°ü×î´ó¸öÊý=%s£¬²»ÄÜÔÙµôÁË£¡" % packMaxItemCnt)  
 | 
            return  
 | 
      
 | 
    # ¸øÎïÆ·  
 | 
    giveItem = ItemCommon.CreateSingleItem(itemID)  
 | 
          
 | 
    if not giveItem:  
 | 
        GameWorld.ErrLog('__DoPlayerGetActionAward giveItemErr=%s' % (itemID), playerID)  
 | 
        return  
 | 
  
 | 
    ItemControler.SetItemIsBind(giveItem, itemInfo[Def_ItemInfo_IsBind])  
 | 
    itemControler = ItemControler.PlayerItemControler(curPlayer)  
 | 
    if not itemControler.PutInItem(IPY_GameWorld.rptItem, giveItem):  
 | 
        giveItem.Clear()  
 | 
        return  
 | 
      
 | 
    #PlayerControl.NotifyCode(curPlayer, "ObtainRes01", [itemID, 1])   
 | 
    return  
 | 
  
 | 
  
 | 
##-----------------------------»î¶¯¶Ò»»ÎïÆ·-------------------------------  
 | 
  
 | 
# »î¶¯¶Ò»»ÅäÖÃË÷Òý  
 | 
(  
 | 
Def_ExcCfg_GameWorldActionKey, # ¶ÔÓ¦»î¶¯key  
 | 
Def_ExcCfg_ActionState, # ¿É¶Ò»»ÎïÆ·µÄ»î¶¯×´Ì¬  
 | 
Def_ExcCfg_RecordResetWay, # ¶Ò»»´ÎÊýÖØÖ÷½Ê½ 0-»î¶¯Öв»ÖØÖÃ, 1-»î¶¯ÖйýÌìÖØÖà  
 | 
Def_ExcCfg_ItemDict, # ¶Ò»»ÎïÆ·ÐÅÏ¢  
 | 
) = range(4)  
 | 
  
 | 
  
 | 
# ¶Ò»»ÎïÆ·ÐÅÏ¢ÅäÖÃË÷Òý  
 | 
(  
 | 
Def_ExcItem_RecordMark, # ¶Ò»»¼Ç¼±àºÅ±êʶ, ´Ó0¿ªÊ¼ÒÀ´ÎµÝÔö  
 | 
Def_ExcItem_GetCnt, # µ¥´Î¶Ò»»¿É»ñµÃµÄ¸öÊý  
 | 
Def_ExcItem_MaxCnt, # ×î´ó¿É¶Ò»»´ÎÊý  
 | 
Def_ExcItem_CostItem, # ÏûºÄ²ÄÁÏÁбí[(ÏûºÄÎïÆ·ID,¸öÊý),(ÏûºÄÎïÆ·ID,¸öÊý),...]  
 | 
Def_ExcItem_CostMoney, # [ÏûºÄ»õ±ÒÀàÐÍ, »õ±ÒÊý]  
 | 
Def_ExcItem_NotifyMark, # È«·þ¹ã²¥mark, ²ÎÊý[Íæ¼ÒÃû,itemID,itemID]  
 | 
Def_ExcItem_NeedSpace, # ËùÐè¸ñ×ÓÊý  
 | 
Def_ExcItem_GiveItem, # ¸øÓèµÄÎïÆ·Áбí, Èç¹û¸ÃÅäÖÿÕÔòĬÈÏÈ¡key×÷ΪitemID  
 | 
) = range(8)  
 | 
  
 | 
  
 | 
## ½ÚÈÕ»î¶¯Íæ¼ÒµÇ¼  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def ActionOnLogin(curPlayer):  
 | 
    actionItemExchangeInfo = ReadChConfig.GetEvalChConfig("ActionItemExchange")  
 | 
      
 | 
    for actionKey, excCfg in actionItemExchangeInfo.items():  
 | 
        gwDictKey = excCfg[Def_ExcCfg_GameWorldActionKey]  
 | 
        curState = GameWorld.GetGameWorld().GetGameWorldDictByKey(gwDictKey)  
 | 
          
 | 
        # Èç¹ûÊǶһ»»î¶¯ÖУ¬Í¬²½¶Ò»»´ÎÊý  
 | 
        if curState == excCfg[Def_ExcCfg_ActionState]:  
 | 
            Sync_ExcItemCnt(curPlayer, actionKey)  
 | 
              
 | 
    DoPlayerActionBuffOnLogin(curPlayer)  
 | 
    return  
 | 
  
 | 
## ½ÚÈջ¹ýÌì  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def ActionOnDay(curPlayer):  
 | 
    actionItemExchangeInfo = ReadChConfig.GetEvalChConfig("ActionItemExchange")  
 | 
      
 | 
    for actionKey, excCfg in actionItemExchangeInfo.items():  
 | 
        gwDictKey = excCfg[Def_ExcCfg_GameWorldActionKey]  
 | 
        curState = GameWorld.GetGameWorld().GetGameWorldDictByKey(gwDictKey)  
 | 
          
 | 
        # ²»Êǿɶһ»ÎïÆ·»î¶¯ÆÚ¼ä£¬ÖØÖöһ»¼Ç¼  
 | 
        if curState != excCfg[Def_ExcCfg_ActionState]:  
 | 
            GameWorld.DebugLog("·Ç»î¶¯ÖУ¬ÖØÖûÎïÆ·¶Ò»»Êý¾ÝactionKey=%s" % actionKey)  
 | 
            __ResetExcRecord(curPlayer, actionKey, excCfg, False)  
 | 
        else:  
 | 
            resetWay = excCfg[Def_ExcCfg_RecordResetWay]  
 | 
            # »î¶¯ÖйýÌìÖØÖöһ»´ÎÊýµÄ  
 | 
            if resetWay == 1:  
 | 
                GameWorld.DebugLog("»î¶¯ÖУ¬¹ýÌìÖØÖûÎïÆ·¶Ò»»Êý¾ÝactionKey=%s" % actionKey)  
 | 
                __ResetExcRecord(curPlayer, actionKey, excCfg, True)  
 | 
      
 | 
    return  
 | 
  
 | 
  
 | 
## ÖØÖöһ»´ÎÊý¼Ç¼  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def __ResetExcRecord(curPlayer, actionKey, excCfg, isNotify):  
 | 
    itemDict = excCfg[Def_ExcCfg_ItemDict]  
 | 
    for itemInfo in itemDict.values():  
 | 
        recordMark = itemInfo[Def_ExcItem_RecordMark]  
 | 
        excCntKey = ChConfig.Def_PDict_ExcActionItemCnt % (actionKey, recordMark)  
 | 
        PlayerControl.NomalDictSetProperty(curPlayer, excCntKey, 0)  
 | 
      
 | 
    if isNotify:  
 | 
        Sync_ExcItemCnt(curPlayer, actionKey)  
 | 
    return  
 | 
  
 | 
## ¸ù¾Ý»î¶¯keyÖØÖöһ»´ÎÊý¼Ç¼  
 | 
#  @param curPlayer  
 | 
#  @param keyList [keyÁбí]  
 | 
#  @return None  
 | 
def ResetExcRecordByKey(curPlayer, keyList, isNotify=False):  
 | 
      
 | 
    if not keyList:  
 | 
        return  
 | 
      
 | 
    actionItemExchangeInfo = ReadChConfig.GetEvalChConfig("ActionItemExchange")  
 | 
      
 | 
    for actionKey, excCfg in actionItemExchangeInfo.items():  
 | 
          
 | 
        if actionKey in keyList:  
 | 
            __ResetExcRecord(curPlayer, actionKey, excCfg, isNotify)  
 | 
      
 | 
    return  
 | 
  
 | 
##// AB 06 »î¶¯ÎïÆ·¶Ò»» #tagCMExchangeActionItem  
 | 
#  
 | 
#struct     tagCMExchangeActionItem  
 | 
#  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    BYTE        ActionKeyLen;   
 | 
#    char        ActionKey[ActionKeyLen];  
 | 
#    DWORD        ItemID; // ¶Ò»»µÄÄ¿±êÎïÆ·ID  
 | 
#    WORD        ExcCnt; // ¶Ò»»¸öÊý£¬Ä¬ÈÏ1¸ö  
 | 
#};  
 | 
## »î¶¯ÎïÆ·¶Ò»»  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def OnExchangeActionItem(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    if not curPlayer:  
 | 
        return  
 | 
      
 | 
    actionKey = clientData.ActionKey  
 | 
    itemID = clientData.ItemID  
 | 
    excCnt = clientData.ExcCnt  
 | 
    excCnt = max(1, excCnt)  
 | 
      
 | 
    GameWorld.DebugLog("»î¶¯¶Ò»»ÎïÆ·actionKey=%s,itemID=%s,excCnt=%s" % (actionKey, itemID, excCnt))  
 | 
    actionItemExchangeInfo = ReadChConfig.GetEvalChConfig("ActionItemExchange")  
 | 
      
 | 
    if actionKey not in actionItemExchangeInfo:  
 | 
        GameWorld.ErrLog("    ActionItemExchange.txtÎ޸û£¡actionKey=%s" % (actionKey))  
 | 
        return  
 | 
      
 | 
    excCfg = actionItemExchangeInfo[actionKey]  
 | 
    gwDictKey = excCfg[Def_ExcCfg_GameWorldActionKey]  
 | 
    curState = GameWorld.GetGameWorld().GetGameWorldDictByKey(gwDictKey)  
 | 
    exchangeState = excCfg[Def_ExcCfg_ActionState]  
 | 
    if curState != exchangeState:  
 | 
        GameWorld.DebugLog("    ·Ç¶Ò»»ÎïÆ·ÆÚ¼ä£¬²»¿É¶Ò»»£¡curState=%s,exchangeState=%s"   
 | 
                           % (curState, exchangeState))  
 | 
        return  
 | 
      
 | 
    itemDict = excCfg[Def_ExcCfg_ItemDict]  
 | 
      
 | 
    if itemID not in itemDict:  
 | 
        GameWorld.ErrLog("    ActionItemExchange.txtδÅäÖöһ»¸ÃÎïÆ·¶Ò»»ÐÅÏ¢£¡actionKey=%s,itemID=%s"   
 | 
                         % (actionKey, itemID))  
 | 
        return  
 | 
      
 | 
    itemInfo = itemDict[itemID]  
 | 
          
 | 
    recordMark = itemInfo[Def_ExcItem_RecordMark]  
 | 
    getCnt = itemInfo[Def_ExcItem_GetCnt] # µ¥´Î¶Ò»»¿É»ñµÃ¸öÊý  
 | 
    maxCnt = itemInfo[Def_ExcItem_MaxCnt] # ×î´ó¶Ò»»´ÎÊý£¬0Ϊ²»ÏÞÖÆ  
 | 
    costItemList = itemInfo[Def_ExcItem_CostItem]  
 | 
    costMoneyInfo = itemInfo[Def_ExcItem_CostMoney]  
 | 
    notifyMark = itemInfo[Def_ExcItem_NotifyMark]  
 | 
    needSpace = itemInfo[Def_ExcItem_NeedSpace]  
 | 
    giveItemList = itemInfo[Def_ExcItem_GiveItem]  
 | 
      
 | 
    excCntKey = ChConfig.Def_PDict_ExcActionItemCnt % (actionKey, recordMark)  
 | 
    exchangeCnt = curPlayer.NomalDictGetProperty(excCntKey) # ÒѶһ»´ÎÊý  
 | 
      
 | 
    if maxCnt > 0 and exchangeCnt + excCnt > maxCnt:  
 | 
        GameWorld.DebugLog("    ¶Ò»»´ÎÊý²»×㣬²»¿É¶Ò»»£¡ÒѶһ»=%s,Òª¶Ò»»=%s,×î´ó=%s,"   
 | 
                           % (exchangeCnt, excCnt, maxCnt))  
 | 
        return  
 | 
      
 | 
    packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem)  
 | 
    #ÑéÖ¤±³°ü¿Õ¼ä  
 | 
    if needSpace > packSpace:  
 | 
        PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_998371")  
 | 
        return  
 | 
      
 | 
    needMoney = 0  
 | 
    if costMoneyInfo:  
 | 
        moneyType, needMoney = costMoneyInfo  
 | 
        needMoney = needMoney * excCnt  
 | 
        if not PlayerControl.HaveMoney(curPlayer, moneyType, needMoney):  
 | 
            GameWorld.DebugLog("    »õ±Ò²»×ã moneyType=%s,needMoney=%s" % (moneyType, needMoney))  
 | 
            return  
 | 
          
 | 
    costItemCntDict = {} # ÏûºÄÎïÆ·×ܸöÊý×Öµä  
 | 
    for costItemID, costCnt in costItemList:  
 | 
        costItemCntDict[costItemID] = costCnt * excCnt # µ¥´ÎÏûºÄ¸öÊý*¶Ò»»´ÎÊý  
 | 
      
 | 
    delItemInfoList, findItemIsBind, lackItemCntDict = __GetCostItem(curPlayer, costItemCntDict)  
 | 
      
 | 
    if lackItemCntDict:  
 | 
        GameWorld.DebugLog("    ¶Ò»»²ÄÁϲ»×㣬»¹Ðè %s" % str(lackItemCntDict))  
 | 
        return  
 | 
  
 | 
    # Ö§¸¶ËùÐè»õ±Ò  
 | 
    if needMoney > 0:  
 | 
        infoDict = {ChConfig.Def_Cost_Reason_SonKey:"%s_%s" % (actionKey, itemID)}  
 | 
        PlayerControl.PayMoney(curPlayer, moneyType, needMoney, ChConfig.Def_Cost_ExchangeActionItem, infoDict)  
 | 
          
 | 
    # ¿Û³ý¸½¼ÓÎïÆ·  
 | 
    for item, delCnt in delItemInfoList:  
 | 
        ItemCommon.DelItem(curPlayer, item, delCnt, True, "ExchangeActionItem")     
 | 
      
 | 
    # ¸üжһ»´ÎÊý  
 | 
    PlayerControl.NomalDictSetProperty(curPlayer, excCntKey, exchangeCnt + excCnt)  
 | 
    Sync_ExcItemCnt(curPlayer, actionKey)  
 | 
      
 | 
    notifyItemID = 0  
 | 
    if not giveItemList:  
 | 
        giveItemList = [(itemID, getCnt)]  
 | 
        notifyItemID = itemID  
 | 
          
 | 
    for giveItemID, giveCnt in giveItemList:  
 | 
        if not notifyItemID:  
 | 
            notifyItemID = giveItemID  
 | 
        giveTotalCnt = giveCnt * excCnt  
 | 
        if not ItemControler.GivePlayerItem(curPlayer, giveItemID, giveTotalCnt, findItemIsBind,  
 | 
                                            [IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere]):  
 | 
            GameWorld.ErrLog("OnExchangeActionItem(), give itemID:%s,count:%s fail!"   
 | 
                             % (giveItemID, giveTotalCnt), curPlayer.GetPlayerID())  
 | 
        # Äú»ñµÃÁËÎïÆ·XX XX¸ö  
 | 
        #PlayerControl.NotifyCode(curPlayer, "ObtainRes01", [giveItemID, giveTotalCnt])  
 | 
      
 | 
    # È«·þ¹ã²¥  
 | 
    if notifyMark and notifyItemID:  
 | 
        PlayerControl.WorldNotify(0, notifyMark, [curPlayer.GetPlayerName(), notifyItemID, notifyItemID])  
 | 
          
 | 
    # ¶Ò»»Á÷Ïò  
 | 
    addDataDict = {"ActionKey":actionKey, "ExchangeCnt":excCnt, "ExchangeItemIDKey":itemID}  
 | 
    DataRecordPack.DR_FuncGiveItem(curPlayer, "ExchangeItem", addDataDict)  
 | 
           
 | 
    GameWorld.DebugLog("    OK!»ñµÃgiveItemList=%s * excCnt=%s" % (giveItemList, excCnt))  
 | 
    return  
 | 
  
 | 
## »ñÈ¡¶Ò»»ÎïÆ·Ðè¿Û³ýµÄÎïÆ·ÐÅÏ¢  
 | 
#  @param curPlayer  
 | 
#  @param costItemCntDict: ÏûºÄ²ÄÁϸöÊý×Öµä  
 | 
#  @return ·µ»ØÁбí[Òª¿Û³ýµÄÎïÆ·ÐÅÏ¢, ËùÕҵIJÄÁÏÊÇ·ñÓа󶨵Ä, ²»×ãµÄ¸öÊýÐÅÏ¢×Öµä]  
 | 
def __GetCostItem(curPlayer, costItemCntDict):  
 | 
    findItemIsBind = False  
 | 
    delItemInfoList = []  
 | 
  
 | 
    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)  
 | 
    for i in range(itemPack.GetCount()):  
 | 
        curItem = itemPack.GetAt(i)  
 | 
        #¹ýÂ˲»·ûºÏÆäËûÌõ¼þµÄÎïÆ·  
 | 
        if not ItemCommon.CheckItemCanUse(curItem):  
 | 
            continue  
 | 
          
 | 
        itemID = curItem.GetItemTypeID()  
 | 
        if itemID not in costItemCntDict:  
 | 
            continue  
 | 
                  
 | 
        #²éÕÒµ½µÄÎïÆ·Îª°ó¶¨ÎïÆ·  
 | 
        if not findItemIsBind and curItem.GetIsBind():  
 | 
            findItemIsBind = True  
 | 
          
 | 
        needCnt = costItemCntDict[itemID]  
 | 
        itemCount = curItem.GetCount()  
 | 
          
 | 
        #²»¹»  
 | 
        if needCnt > itemCount:  
 | 
            needCnt -= itemCount  
 | 
            costItemCntDict[itemID] = needCnt # ¸üл¹Ðè¸öÊý  
 | 
            delItemInfoList.append([curItem, itemCount])  
 | 
        else:  
 | 
            costItemCntDict.pop(itemID)  
 | 
            delItemInfoList.append([curItem, needCnt])  
 | 
              
 | 
            # Èç¹û¶¼¹»ÁË£¬Ìø³ö£¬²»ÔÙ²éÕÒ  
 | 
            if not costItemCntDict:  
 | 
                break  
 | 
              
 | 
    #·µ»ØÁбí[Òª¿Û³ýµÄÎïÆ·ÐÅÏ¢, ËùÕҵIJÄÁÏÊÇ·ñÓа󶨵Ä, ²»×ãµÄ¸öÊýÐÅÏ¢×Öµä]  
 | 
    return delItemInfoList, findItemIsBind, costItemCntDict  
 | 
  
 | 
  
 | 
## Í¬²½¶Ò»»´ÎÊý  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def Sync_ExcItemCnt(curPlayer, actionKey):  
 | 
    actionItemExchangeInfo = ReadChConfig.GetEvalChConfig("ActionItemExchange")  
 | 
      
 | 
    if actionKey not in actionItemExchangeInfo:  
 | 
        return  
 | 
      
 | 
    excCfg = actionItemExchangeInfo[actionKey]  
 | 
      
 | 
    exRecordPack = ChPyNetSendPack.tagMCExchangeActionItemCntRecord()  
 | 
    exRecordPack.Clear()  
 | 
    exRecordPack.ActionKey = actionKey  
 | 
    exRecordPack.ActionKeyLen = len(actionKey)  
 | 
    exRecordPack.RecordList = []  
 | 
      
 | 
    itemDict = excCfg[Def_ExcCfg_ItemDict]  
 | 
    for itemID, itemInfo in itemDict.items():  
 | 
        recordMark = itemInfo[Def_ExcItem_RecordMark]  
 | 
        excCntKey = ChConfig.Def_PDict_ExcActionItemCnt % (actionKey, recordMark)  
 | 
        exchangeCnt = curPlayer.NomalDictGetProperty(excCntKey) # ÒѶһ»´ÎÊý  
 | 
        excItem = ChPyNetSendPack.tagMCExchangeActionItemCnt()  
 | 
        excItem.Clear()  
 | 
        excItem.ItemID = itemID  
 | 
        excItem.ExcCnt = exchangeCnt  
 | 
        exRecordPack.RecordList.append(excItem)  
 | 
      
 | 
    exRecordPack.RecordCnt = len(exRecordPack.RecordList)  
 | 
    NetPackCommon.SendFakePack(curPlayer, exRecordPack)  
 | 
    return  
 | 
  
 | 
##------------------------------- °´»î¶¯Ê±¼ä¸øbuff ------------------------------  
 | 
  
 | 
## »î¶¯buff״̬±ä¸ü  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def OnActionBuffStateChange(key, tick):  
 | 
    buffID = key[len(ShareDefine.Def_Notify_WorldKey_ActionBuffState) - 2:]  
 | 
    try:  
 | 
        buffID = int(buffID)              
 | 
    except BaseException:  
 | 
        GameWorld.ErrLog("»î¶¯buffIDÅäÖÃkey´íÎó, key=%s" % key)  
 | 
        return  
 | 
      
 | 
    actionBuffList = ReadChConfig.GetEvalChConfig("PlayerActionBuff")  
 | 
    if buffID not in actionBuffList:  
 | 
        GameWorld.ErrLog("»î¶¯buffID²»ÔÚPlayerActionBuff.txtÀï, buffID=%s" % buffID)  
 | 
        return  
 | 
      
 | 
    buffState = GameWorld.GetGameWorld().GetGameWorldDictByKey(key)  
 | 
    GameWorld.DebugLog("OnActionBuffStateChange buffID=%s,state=%s" % (buffID, buffState))  
 | 
      
 | 
    playerManager = GameWorld.GetPlayerManager()  
 | 
    for index in range(0, playerManager.GetPlayerCount()):  
 | 
        curPlayer = playerManager.GetPlayerByIndex(index)  
 | 
        if curPlayer.GetID() == 0:  
 | 
            continue  
 | 
              
 | 
        isOK = __AddPlayerActionBuff(curPlayer, buffID, buffState, tick)  
 | 
        if isOK:  
 | 
            playerControl = PlayerControl.PlayerControl(curPlayer)  
 | 
            playerControl.RefreshPlayerAttrByBuff()  
 | 
    return  
 | 
  
 | 
## Íæ¼Ò»î¶¯buffÂß¼  
 | 
#  @param curPlayer  
 | 
#  @return None  
 | 
def DoPlayerActionBuffOnLogin(curPlayer):  
 | 
    tick = GameWorld.GetGameWorld().GetTick()  
 | 
    actionBuffList = ReadChConfig.GetEvalChConfig("PlayerActionBuff")  
 | 
    isNeedRefresh = False  
 | 
    for buffID in actionBuffList:  
 | 
        stateKey = ShareDefine.Def_Notify_WorldKey_ActionBuffState % buffID  
 | 
        buffState = GameWorld.GetGameWorld().GetGameWorldDictByKey(stateKey)  
 | 
        isOK = __AddPlayerActionBuff(curPlayer, buffID, buffState, tick)  
 | 
        isNeedRefresh = True if isOK else isNeedRefresh  
 | 
      
 | 
    if isNeedRefresh:  
 | 
        playerControl = PlayerControl.PlayerControl(curPlayer)  
 | 
        playerControl.RefreshPlayerAttrByBuff()  
 | 
    return  
 | 
  
 | 
## Ìí¼ÓÍæ¼Ò»î¶¯buff  
 | 
#  @param curPlayer  
 | 
#  @param buffID  
 | 
#  @param isAddBuff ÊÇ·ñÌí¼Ó  
 | 
#  @return None  
 | 
def __AddPlayerActionBuff(curPlayer, buffID, isAddBuff, tick):  
 | 
      
 | 
    if isAddBuff:  
 | 
        skillInfo = SkillCommon.FindBuffByID(curPlayer, buffID)  
 | 
        findBuff, buffManager, buffType, findSkill = skillInfo  
 | 
        if findBuff == None:  
 | 
            if not findSkill:  
 | 
                return False  
 | 
              
 | 
            return BuffSkill.AddBuffNoRefreshState(curPlayer, buffType, findSkill, tick, [], curPlayer)  
 | 
    else:  
 | 
        return BuffSkill.DelBuffBySkillID(curPlayer, buffID, tick)  
 | 
      
 | 
    return False  
 | 
  
 |