| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package EquipZhuXian  | 
| #  | 
| # @todo:ÖïÏÉ×°±¸  | 
| # @author hxp  | 
| # @date 2019-01-22  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ÖïÏÉ×°±¸  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2019-01-22 15:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import ItemCommon  | 
| import ShareDefine  | 
| import PlayerControl  | 
| import DataRecordPack  | 
| import IPY_GameWorld  | 
| import ItemControler  | 
| import IpyGameDataPY  | 
| import NetPackCommon  | 
| import ChPyNetSendPack  | 
| import SkillCommon  | 
| import PyGameData  | 
| import ChConfig  | 
| import ChEquip  | 
|   | 
| import random  | 
|   | 
|   | 
| def GetZhuXianEquipIndexByPlace(equipPlace):  | 
|     ## »ñÈ¡ÖïÏÉ×°±¸Î»¶ÔÓ¦µÄË÷Òý  | 
|     return equipPlace - 1 - 120  | 
|   | 
|   | 
| def GetZhuXianEquipPlaceByIndex(equipIndex):  | 
|     ## »ñÈ¡ÖïÏÉ×°±¸Ë÷Òý¶ÔӦװ±¸Î»  | 
|     return equipIndex + 1 + 120  | 
|   | 
|   | 
| def GetZhuXianEquipPlaceIndexIsUnlock(curPlayer, equipPlaceIndex):  | 
|     ## »ñÈ¡ÖïÏÉ×°±¸Î»ÊÇ·ñ½âËø  | 
|     # @param equipPlaceIndex: ×¢Òâ´«ÈëµÄ²ÎÊýÊÇ×°±¸Î»Ë÷Òý  | 
|     equipPlace = GetZhuXianEquipPlaceByIndex(equipPlaceIndex)  | 
|     placeUnlockDict = IpyGameDataPY.GetConfigEx("EquipZhuXianUnlock") # ÖïÏÉ×°±¸Î»¶ÔÓ¦½âËøËùÐèÖïÏÉËþ²ãÊý {"×°±¸Î»":ÖïÏÉËþ²ãÊý, ...} Ã»ÅäµÄĬÈϽâËø  | 
|     if not placeUnlockDict:  | 
|         placeUnlockDict = {}  | 
|         ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|         for index in xrange(ipyDataMgr.GetZhuXianTowerCount()):  | 
|             ipyData = ipyDataMgr.GetZhuXianTowerByIndex(index)  | 
|             unlockEquipPlace = ipyData.GetUnLockEquipPlace()  | 
|             if not unlockEquipPlace:  | 
|                 continue  | 
|             towerID = ipyData.GetID()  | 
|             placeUnlockDict[unlockEquipPlace] = towerID  | 
|         IpyGameDataPY.SetConfigEx("EquipZhuXianUnlock", placeUnlockDict)  | 
|         GameWorld.DebugLog("¼ÓÔØÖïÏÉËþ½âËø×°±¸Î»: placeUnlockDict=%s" % placeUnlockDict)  | 
|     if equipPlace not in placeUnlockDict:  | 
|         return True  | 
|     needTowerLV = placeUnlockDict[equipPlace]  | 
|     curTowerLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ZhuXianTowerPassLV)  # Òѹý¹ØµÄÖïÏÉËþ²ãÊý  | 
|     return curTowerLV >= needTowerLV  | 
|   | 
|   | 
| def CheckLearnZhuXianSkill(curPlayer, skillID):  | 
|     ## ¼ì²éÖïÏÉ×°±¸Î»×°±¸½×Êý  | 
|       | 
|     zhuxianSkillCondition = IpyGameDataPY.GetFuncEvalCfg("EquipZhuXian", 3, {})  | 
|     if str(skillID) not in zhuxianSkillCondition:  | 
|         return True  | 
|     classLVPlaceListDict = zhuxianSkillCondition[str(skillID)]  | 
|     zhuXianEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptZhuXianEquip)  | 
|     for classLV, placeList in classLVPlaceListDict.items():  | 
|         needClassLV = int(classLV)  | 
|         for equipPlace in placeList:  | 
|             placeIndex = GetZhuXianEquipIndexByPlace(equipPlace)  | 
|             if placeIndex < 0 or placeIndex >= zhuXianEquipPack.GetCount():  | 
|                 return  | 
|             curEquip = zhuXianEquipPack.GetAt(placeIndex)  | 
|             if curEquip.IsEmpty():  | 
|                 GameWorld.DebugLog("ÖïÏÉ×°±¸Î»ÎÞ×°±¸£¬ÎÞ·¨¼¤»îÉñ¼¼! equipPlace=%s" % equipPlace)  | 
|                 return  | 
|             curClassLV = ItemCommon.GetItemClassLV(curEquip)  | 
|             if curClassLV < needClassLV:  | 
|                 GameWorld.DebugLog("ÖïÏÉ×°±¸Î»×°±¸½×¼¶²»×㣬ÎÞ·¨¼¤»îÉñ¼¼! equipPlace=%s,curClassLV=%s < needClassLV=%s" % (equipPlace, curClassLV, needClassLV))  | 
|                 return  | 
|               | 
|     return True  | 
|   | 
|   | 
| #// A3 30 ×°±¸ÖïÏÉ×°±¸ #tagCMEquipZhuXianItem  | 
| #  | 
| #struct    tagCMEquipZhuXianItem  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        EquipIndex;    //×°±¸ÔÚÖïÏÉ×°±¸±³°üÖеÄË÷Òý  | 
| #    BYTE        ItemIndex;    //×°±¸ÔÚÖïÏÉÎïÆ·±³°üÖеÄË÷Òý  | 
| #};  | 
| def OnEquipZhuXianItem(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     reqEquipPlaceIndex = clientData.EquipIndex  | 
|     itemIndex = clientData.ItemIndex  | 
|       | 
|     GameWorld.DebugLog("´©´÷ÖïÏÉ×°±¸: EquipIndex=%s,ItemIndex=%s" % (reqEquipPlaceIndex, itemIndex), playerID)  | 
|       | 
|     zhuXianItemPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptZhuXianItem)  | 
|     curEquip = zhuXianItemPack.GetAt(itemIndex)  | 
|     if not ItemCommon.CheckItemCanUse(curEquip):  | 
|         GameWorld.DebugLog("ÎïÆ·Îª¿Õ»ò²»¿ÉÓÃ: itemIndex=%s" % itemIndex, playerID)  | 
|         return  | 
|     if not ItemCommon.GetIsZhuXianEquip(curEquip):  | 
|         GameWorld.DebugLog("·ÇÖïÏÉ×°±¸: itemIndex=%s" % itemIndex, playerID)  | 
|         return  | 
|       | 
|     equipPlace = curEquip.GetEquipPlace()  | 
|     equipPlaceIndex = GetZhuXianEquipIndexByPlace(equipPlace)  | 
|     if reqEquipPlaceIndex != equipPlaceIndex:  | 
|         reqEquipPlace = GetZhuXianEquipPlaceByIndex(reqEquipPlaceIndex)  | 
|         canPlace = False  | 
|         for sharePlaceList in ShareDefine.ShareEquipPlace:  | 
|             if reqEquipPlace in sharePlaceList and equipPlace in sharePlaceList:  | 
|                 canPlace = True  | 
|                 break  | 
|         if not canPlace:  | 
|             GameWorld.DebugLog("¸Ã×°±¸Î»²»¿É×°±¸¸ÃÎïÆ·!equipPlace=%s,equipPlaceIndex=%s != reqEquipPlaceIndex=%s" % (equipPlace, equipPlaceIndex, reqEquipPlaceIndex), playerID)  | 
|             return  | 
|       | 
|     zhuXianEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptZhuXianEquip)  | 
|     if reqEquipPlaceIndex < 0 or reqEquipPlaceIndex >= zhuXianEquipPack.GetCount():  | 
|         GameWorld.ErrLog("ÖïÏÉ×°±¸±³°üË÷ÒýÒì³£: EquipIndex=%s" % (reqEquipPlaceIndex), playerID)  | 
|         return  | 
|       | 
|     if not GetZhuXianEquipPlaceIndexIsUnlock(curPlayer, reqEquipPlaceIndex):  | 
|         GameWorld.DebugLog("ÖïÏÉ×°±¸Î»Î´½âËø: equipPlace=%s,EquipIndex=%s" % (equipPlace, reqEquipPlaceIndex))  | 
|         return  | 
|       | 
|     destEquip = zhuXianEquipPack.GetAt(reqEquipPlaceIndex)  | 
|     desItemID, desUserData = [0, ''] if destEquip.IsEmpty() else [destEquip.GetItemTypeID(), destEquip.GetUserData()]  | 
|     srcItemID, srcUserData = curEquip.GetItemTypeID(), curEquip.GetUserData()  | 
|     if not ItemCommon.DoLogicSwitchItem(curPlayer, destEquip, curEquip, ShareDefine.rptZhuXianEquip):  | 
|         return  | 
|     dataDict = {'dotype':'EquipZhuXianItem', 'desItemID':desItemID, 'desUserData':desUserData, 'srcItemID':srcItemID, 'srcUserData':srcUserData}  | 
|     DataRecordPack.Cache_FightPowerChangeInfo(curPlayer, ChConfig.PowerDownType_EquipChange, dataDict)  | 
|       | 
|     RefreshZhuXianAttr(curPlayer)     | 
|     return  | 
|   | 
|   | 
| #// A3 31 Ð¶ÏÂÖïÏÉ×°±¸ #tagCMUnEquipZhuXianItem  | 
| #  | 
| #struct    tagCMUnEquipZhuXianItem  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        EquipIndex;    //×°±¸ÔÚÖïÏÉ×°±¸±³°üÖеÄË÷Òý  | 
| #};  | 
| def OnUnEquipZhuXianItem(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     EquipIndex = clientData.EquipIndex  | 
|       | 
|     GameWorld.DebugLog("жÏÂÖïÏÉ×°±¸: EquipIndex=%s" % (EquipIndex), playerID)  | 
|       | 
|     zhuXianEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptZhuXianEquip)  | 
|     if EquipIndex < 0 or EquipIndex >= zhuXianEquipPack.GetCount():  | 
|         GameWorld.ErrLog("ÖïÏÉ×°±¸±³°üË÷ÒýÒì³£: EquipIndex=%s" % (EquipIndex), playerID)  | 
|         return  | 
|     curEquip = zhuXianEquipPack.GetAt(EquipIndex)  | 
|     if not ItemCommon.CheckItemCanUse(curEquip):  | 
|         GameWorld.DebugLog("ÖïÏÉ×°±¸Îª¿Õ»ò²»¿ÉÓÃ: EquipIndex=%s" % EquipIndex, playerID)  | 
|         return  | 
|       | 
|     emptyIndex = ItemCommon.GetEmptyIndexInPack(curPlayer, ShareDefine.rptZhuXianItem)  | 
|     if not ItemCommon.DoLogicSwitchItemEx(curPlayer, ShareDefine.rptZhuXianEquip, ShareDefine.rptZhuXianItem, EquipIndex, emptyIndex):  | 
|         GameWorld.DebugLog("ÖïÏÉжÏÂ×°±¸Ê§°Ü: EquipIndex=%s" % (EquipIndex), playerID)  | 
|         return  | 
|     RefreshZhuXianAttr(curPlayer)  | 
|     return  | 
|   | 
|   | 
| def RefreshZhuXianAttr(curPlayer):  | 
|     CalcZhuXianAttr(curPlayer)  | 
|     PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()   | 
|     return  | 
|   | 
|   | 
| def CalcZhuXianAttr(curPlayer):  | 
|     ## Ë¢ÐÂÖïÏÉÊôÐÔ  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     PyGameData.g_zhuXianSkillAddPerDict.pop(playerID, None)  | 
|     PyGameData.g_zhuXianSkillReducePerDict.pop(playerID, None)  | 
|       | 
|     allAttrList = [{} for _ in range(4)]  | 
|     allAttrListZXSuit = [{} for _ in range(4)]  | 
|     allAttrListZXStone = [{} for _ in range(4)]  | 
|     equipScoreTotal = 0  #Ϊ½â¾ö×°±¸ÆÀ·Ö¡¢Õ½Á¦²»Ò»ÖµÄÇé¿ö£¬×°±¸Õ½Á¦¸ÄΪÓÉÆÀ·Ö×÷Ϊ²ÎÊý¼ÆËãÕ½Á¦  | 
|     equipPlaceClassLVDict = {}  #×°±¸Î»¶ÔӦװ±¸½× {×°±¸Î»:½×, ...}  | 
|     equipPlaceBaseAttrDict = {}  #×°±¸Î»¶ÔÓ¦»ù´¡ÊôÐÔ×Öµä {×°±¸Î»:{ÊôÐÔID:value, ...}, ...}  | 
|     equipPlaceStoneLVDict = {}  #×°±¸Î»¶ÔÓ¦±¦Ê¯µÈ¼¶ {×°±¸Î»:[±¦Ê¯µÈ¼¶,..], ...}  | 
|     attrIDSkillPlusDict = IpyGameDataPY.GetFuncEvalCfg("SkillPlusAttrID", 1, {})  # ÊôÐÔID¶ÔÓ¦Ó°ÏìµÄ¼¼ÄÜTypeIDÁбí {ÊôÐÔID:[¼¼ÄÜTypeIDÁбí, ...], ...}  | 
|     addAttrIDList = range(ShareDefine.Def_Effect_SkillAddPer1, ShareDefine.Def_Effect_SkillAddPer7 + 1)  | 
|     reduceAttrIDList = range(ShareDefine.Def_Effect_SkillReducePer1, ShareDefine.Def_Effect_SkillReducePer7 + 1)  | 
|     zxSkillPlusAttrDict = {}  # Íæ¼ÒÖïÏÉ×°±¸Ó°Ïì¼¼ÄÜTypeIDÊôÐÔ×Öµä {ÊôÐÔID:Öµ, ...}  | 
|       | 
|     zhuXianEquipPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptZhuXianEquip)  | 
|     equipPackCount = zhuXianEquipPack.GetCount()  | 
|       | 
|     for equipIndex in range(len(ShareDefine.ZhuXianEquipPlace)):  | 
|         if equipIndex < 0 or equipIndex >= equipPackCount:  | 
|             break  | 
|         curEquip = zhuXianEquipPack.GetAt(equipIndex)              | 
|         if curEquip.IsEmpty():  | 
|             continue  | 
|         equipScoreTotal += ItemCommon.GetEquipGearScore(curEquip)  | 
|         equipPlace = GetZhuXianEquipPlaceByIndex(equipIndex)  | 
|         equipPlaceClassLVDict[equipPlace] = ItemCommon.GetItemClassLV(curEquip)  | 
|           | 
|         # »ù´¡ÊôÐÔ  | 
|         baseAttrDict = {}  | 
|         for effIndex in xrange(curEquip.GetEffectCount()):  | 
|             curEffect = curEquip.GetEffectByIndex(effIndex)  | 
|             if not curEffect or not curEffect.GetEffectID():  | 
|                 break  | 
|             effID = curEffect.GetEffectID()  | 
|             if not effID:  | 
|                 continue  | 
|             effValue = curEffect.GetEffectValue(0)  | 
|             PlayerControl.CalcAttrDict_Type(effID, effValue, allAttrList)  | 
|             baseAttrDict[effID] = baseAttrDict.get(effID, 0) + effValue  | 
|         equipPlaceBaseAttrDict[equipPlace] = baseAttrDict  | 
|           | 
|         # ´«ÆæÊôÐÔ  | 
|         if curEquip.GetUserAttrCount(ShareDefine.Def_IudetLegendAttrID) == curEquip.GetUserAttrCount(ShareDefine.Def_IudetLegendAttrValue):  | 
|             for i in xrange(curEquip.GetUserAttrCount(ShareDefine.Def_IudetLegendAttrID)):  | 
|                 legendAttrID = curEquip.GetUserAttrByIndex(ShareDefine.Def_IudetLegendAttrID, i)  | 
|                 legendAttrValue = curEquip.GetUserAttrByIndex(ShareDefine.Def_IudetLegendAttrValue, i)  | 
|                 if legendAttrID in attrIDSkillPlusDict:  | 
|                     zxSkillPlusAttrDict[legendAttrID] = zxSkillPlusAttrDict.get(legendAttrID, 0) + legendAttrValue  | 
|                 else:  | 
|                     PlayerControl.CalcAttrDict_Type(legendAttrID, legendAttrValue, allAttrList)  | 
|         #±¦Ê¯ÊôÐÔ  | 
|         gemlvList = ChEquip.CalcEquipStone_Effect(curPlayer, equipPlace, allAttrListZXStone)  | 
|         equipPlaceStoneLVDict[equipPlace] = gemlvList  | 
|               | 
|           | 
| #    GameWorld.DebugLog("ÖïÏÉ×°±¸ÊôÐÔ: allAttrList=%s" % (allAttrList))  | 
| #    GameWorld.DebugLog("    zxSkillPlusAttrDict=%s" % (zxSkillPlusAttrDict))  | 
| #    GameWorld.DebugLog("    equipPlaceClassLVDict=%s" % (equipPlaceClassLVDict))  | 
|       | 
|     # »º´æ¼¼ÄÜÔöÇ¿±ÈÀý£¬Ä¿Ç°ÔÝдËÀ¶ÔÖ¸¶¨¼¼ÄÜÉ˺¦°Ù·Ö±ÈÌáÉý  | 
|     for attrID, plusValue in zxSkillPlusAttrDict.items():  | 
|         if attrID not in attrIDSkillPlusDict:  | 
|             continue  | 
|         skillTypeIDList = attrIDSkillPlusDict[attrID]  | 
|         for skillTypeID in skillTypeIDList:  | 
|             if attrID in addAttrIDList:  | 
|                 skillAddPerDict = PyGameData.g_zhuXianSkillAddPerDict.get(playerID, {})  | 
|                 skillAddPerDict[skillTypeID] = plusValue  | 
|                 PyGameData.g_zhuXianSkillAddPerDict[playerID] = skillAddPerDict  | 
|             elif attrID in reduceAttrIDList:  | 
|                 skillReducePerDict = PyGameData.g_zhuXianSkillReducePerDict.get(playerID, {})  | 
|                 skillReducePerDict[skillTypeID] = plusValue  | 
|                 PyGameData.g_zhuXianSkillReducePerDict[playerID] = skillReducePerDict  | 
|                   | 
| #    GameWorld.DebugLog("    PyGameData.g_zhuXianSkillAddPerDict=%s" % PyGameData.g_zhuXianSkillAddPerDict)  | 
| #    GameWorld.DebugLog("    PyGameData.g_zhuXianSkillReducePerDict=%s" % PyGameData.g_zhuXianSkillReducePerDict)  | 
|       | 
|     # ¼ÆËãÌ××°£¬Ä¿Ç°ÔÝдËÀ¶ÔÖïÏÉ×°±¸²¿Î»»ù´¡ÊôÐÔÌáÉý  | 
|     suitAttrIDPlusPlaceDict = {  | 
|                                ShareDefine.Def_Effect_ZXCloakAttrPer:ShareDefine.zxetCloak,  | 
|                                ShareDefine.Def_Effect_ZXMaskAttrPer:ShareDefine.zxetMask,  | 
|                                ShareDefine.Def_Effect_ZXGloveAttrPer:ShareDefine.zxetGlove,  | 
|                                ShareDefine.Def_Effect_ZXRuyiAttrPer:ShareDefine.zxetRuyi,  | 
|                                ShareDefine.Def_Effect_ZXPendantAttrPer:ShareDefine.zxetPendant,  | 
|                                ShareDefine.Def_Effect_ZXRingAttrPer:ShareDefine.zxetRing,  | 
|                                ShareDefine.Def_Effect_ZXWeaponAttrPer:ShareDefine.zxetWeapon1,  | 
|                                ShareDefine.Def_Effect_LXWeaponAttrPer:ShareDefine.zxetWeapon2,  | 
|                                ShareDefine.Def_Effect_XXWeaponAttrPer:ShareDefine.zxetWeapon3,  | 
|                                ShareDefine.Def_Effect_JXWeaponAttrPer:ShareDefine.zxetWeapon4,  | 
|                                }  | 
|     suitPlaceGroupDict = IpyGameDataPY.GetFuncEvalCfg("EquipZhuXian", 2, {})  | 
|     for suitType, placeGroupList in suitPlaceGroupDict.items():  | 
|         suitType = int(suitType)  | 
|         suitLV = 0  | 
|         isSuit = True  | 
|         for place in placeGroupList:  | 
|             if place not in equipPlaceClassLVDict:  | 
|                 isSuit = False  | 
|                 #GameWorld.DebugLog("    Î´´©´÷×°±¸£¬ÎÞ·¨¼¤»îÖïÏÉÌ××°! suitType=%s,placeGroupList=%s,place=%s" % (suitType, placeGroupList, place))  | 
|                 break  | 
|             if not suitLV:  | 
|                 suitLV = equipPlaceClassLVDict[place]  | 
|             else:  | 
|                 suitLV = min(suitLV, equipPlaceClassLVDict[place])  | 
|                   | 
|         if not isSuit or not suitLV:  | 
|             continue  | 
|           | 
|         GameWorld.DebugLog("    ¼¤»îÖïÏÉÌ××°: suitType=%s, suitLV=%s" % (suitType, suitLV))  | 
|         suitAttrIpyData = IpyGameDataPY.GetIpyGameData("ZhuXianSuitAttr", suitType, suitLV)  | 
|         if not suitAttrIpyData:  | 
|             continue  | 
|         suitAttrIDList = suitAttrIpyData.GetSuitAttrIDList()  | 
|         suitAttrValueList = suitAttrIpyData.GetSuitAttrValueList()  | 
|         if len(suitAttrIDList) != len(suitAttrValueList):  | 
|             continue  | 
|         for i, suitEffID in enumerate(suitAttrIDList):  | 
|             suitEffValue = suitAttrValueList[i]  | 
|             #GameWorld.DebugLog("        suitEffID=%s,suitEffValue=%s" % (suitEffID, suitEffValue))  | 
|             if suitEffID in suitAttrIDPlusPlaceDict:  | 
|                 plusPlace = suitAttrIDPlusPlaceDict[suitEffID]  | 
|                 if plusPlace not in equipPlaceBaseAttrDict:  | 
|                     continue  | 
|                 plusEffDict = equipPlaceBaseAttrDict[plusPlace]  | 
|                 #GameWorld.DebugLog("            plusPlace=%s,plusEffDict=%s" % (plusPlace, plusEffDict))  | 
|                 for plusEffID, plusEffValue in plusEffDict.items():  | 
|                     addValue = int(plusEffValue * (10000 + suitEffValue) / 10000.0)  | 
|                     #GameWorld.DebugLog("                plusEffID=%s,plusEffValue=%s,addValue=%s" % (plusEffID, plusEffValue, addValue))  | 
|                     PlayerControl.CalcAttrDict_Type(plusEffID, addValue, allAttrListZXSuit)  | 
|             else:  | 
|                 PlayerControl.CalcAttrDict_Type(suitEffID, suitEffValue, allAttrListZXSuit)  | 
|     #±¦Ê¯¹²ÃùÊôÐÔ  | 
|     #GameWorld.DebugLog('equipPlaceStoneLVDict=%s'%equipPlaceStoneLVDict)  | 
|     needStoneCnt = IpyGameDataPY.GetFuncCfg('GemResonance')  | 
|     for suitType, placeGroupList in suitPlaceGroupDict.items():  | 
|         suitType = int(suitType)  | 
|         groupStoneLVList = []  | 
|         for place in placeGroupList:  | 
|             groupStoneLVList += equipPlaceStoneLVDict.get(place, [])  | 
|           | 
|         if len(groupStoneLVList) < needStoneCnt:  | 
|             continue  | 
|         groupStoneLVList.sort(reverse=True)  | 
|         shareStoneLV = min(groupStoneLVList[:needStoneCnt])  | 
|         GameWorld.DebugLog("    ¼¤»îÖïÏɱ¦Ê¯¹²Ãù: suitType=%s, shareStoneLV=%s" % (suitType, shareStoneLV))  | 
|         stoneAttrIpyData = IpyGameDataPY.GetIpyGameData("ZhuXianStoneAttr", suitType, shareStoneLV)  | 
|         if not stoneAttrIpyData:  | 
|             continue  | 
|         attrIDList = stoneAttrIpyData.GetAttrIDList()  | 
|         attrValueList = stoneAttrIpyData.GetAttrValueList()  | 
|         if len(attrIDList) != len(attrValueList):  | 
|             continue  | 
|         for i, effID in enumerate(attrIDList):  | 
|             effValue = attrValueList[i]  | 
|             if effID in suitAttrIDPlusPlaceDict:  | 
|                 plusPlace = suitAttrIDPlusPlaceDict[effID]  | 
|                 if plusPlace not in equipPlaceBaseAttrDict:  | 
|                     continue  | 
|                 plusEffDict = equipPlaceBaseAttrDict[plusPlace]  | 
|                 #GameWorld.DebugLog("            plusPlace=%s,plusEffDict=%s" % (plusPlace, plusEffDict))  | 
|                 for plusEffID, plusEffValue in plusEffDict.items():  | 
|                     addValue = int(plusEffValue * (10000 + effValue) / 10000.0)  | 
|                     #GameWorld.DebugLog("                plusEffID=%s,plusEffValue=%s,addValue=%s" % (plusEffID, plusEffValue, addValue))  | 
|                     PlayerControl.CalcAttrDict_Type(plusEffID, addValue, allAttrListZXStone)  | 
|             else:  | 
|                 PlayerControl.CalcAttrDict_Type(effID, effValue, allAttrListZXStone)  | 
|           | 
|     # ±£´æ¼ÆËãÖµ  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_ZXEquip, allAttrList)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_ZXEquipSuit, allAttrListZXSuit)  | 
|     PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_ZXEquipStone, allAttrListZXStone)  | 
|       | 
|     #¼ÆËã×°±¸»ù´¡ÊôÐÔ¸½¼ÓÕ½Á¦ (Ŀǰ×é³É: ÆÀ·ÖÕ½Á¦ + ...)  | 
|     equipFightPowerEx = eval(IpyGameDataPY.GetFuncCompileCfg("FightpowerFormula", 2))  | 
|     GameWorld.DebugLog("ÖïÏÉ×°±¸ÆÀ·ÖÕ½Á¦: equipScoreTotal=%s,equipFightPowerEx=%s" % (equipScoreTotal, equipFightPowerEx))  | 
|     curPlayer.SetDict(ChConfig.Def_PlayerKey_MFPEx % ShareDefine.Def_MFPType_ZhuXian, equipFightPowerEx)  | 
|     return  | 
|   | 
|   | 
| def GetZhuXianEquipSkillAddPer(playerID, skillTypeID):  | 
|     ## »ñÈ¡ÖïÏÉ×°±¸É˺¦°Ù·Ö±ÈÌáÉýÖµ  | 
|     if playerID not in PyGameData.g_zhuXianSkillAddPerDict:  | 
|         return 0  | 
|     skillAddPerDict = PyGameData.g_zhuXianSkillAddPerDict[playerID]  | 
|     if skillTypeID not in skillAddPerDict:  | 
|         return 0  | 
|     return skillAddPerDict[skillTypeID]  | 
|   | 
|   | 
| def GetZhuXianEquipSkillReducePer(playerID, skillTypeID):  | 
|     ## »ñÈ¡ÖïÏÉ×°±¸¼õÉ˰ٷֱÈÌáÉýÖµ  | 
|     if playerID not in PyGameData.g_zhuXianSkillReducePerDict:  | 
|         return 0  | 
|     skillReducePerDict = PyGameData.g_zhuXianSkillReducePerDict[playerID]  | 
|     if skillTypeID not in skillReducePerDict:  | 
|         return 0  | 
|     return skillReducePerDict[skillTypeID]  | 
|   | 
|   | 
| #// A3 32 ÖïÏÉ×°±¸·Ö½â #tagCMZhuXianEquipDecompose  | 
| #  | 
| #struct    tagCMZhuXianEquipDecompose  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        Count;        //²ÄÁÏËùÔÚ±³°üË÷ÒýµÄÊýÁ¿  | 
| #    WORD        IndexList[Count];    //²ÄÁÏËùÔÚ±³°üË÷ÒýÁÐ±í  | 
| #    DWORD        ItemIDList[Count];    //²ÄÁÏËùÔÚ±³°üÎïÆ·IDÁÐ±í  | 
| #    BYTE        IsAuto;        //ÊÇ·ñ×Ô¶¯·Ö½â  | 
| #};  | 
| ## ÖïÏÉ×°±¸·Ö½â   | 
| #  @param playerIndex Íæ¼ÒË÷Òý    | 
| #  @param clientData ¿Í»§¶Ë·â°ü    | 
| #  @param tick Ê±¼ä  | 
| #  @return None  | 
| def OnZhuXianEquipDecompose(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     if not clientData.Count:  | 
|         return  | 
|     playerID = curPlayer.GetID()  | 
|     eatIndexList = clientData.IndexList  | 
|     eatItemIDList = clientData.ItemIDList  | 
|     isAuto = clientData.IsAuto  | 
|     giveItemDict = {} #·Ö½âµÃµ½ÎïÆ·  | 
|       | 
|     itemPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptZhuXianItem)  | 
|     for i, index in enumerate(eatIndexList):  | 
|         eatItem = itemPack.GetAt(index)  | 
|         if not eatItem or eatItem.IsEmpty():  | 
|             continue  | 
|         eatItemID = eatItem.GetItemTypeID()  | 
|         if eatItemID != eatItemIDList[i]:  | 
|             GameWorld.Log('ÖïÏÉ×°±¸·Ö½â ·¢µÄÎïÆ·ID²»¶ÔÓ¦index=%s eatItemID=%s,ItemIDList[i]=%s' % (index, eatItemID, eatItemIDList[i]), playerID)  | 
|             continue  | 
|         if eatItem.GetType() not in ChConfig.Def_ZhuXianEquiipType:  | 
|             GameWorld.Log('ÖïÏÉ×°±¸·Ö½â ·¢µÄÎïÆ·²»ÊÇÖïÏÉ×°±¸  eatItemID=%s' % eatItemID, playerID)  | 
|             continue  | 
|           | 
|         itemClassLV = ItemCommon.GetItemClassLV(eatItem)  | 
|         ipyData = IpyGameDataPY.GetIpyGameData('ZhuXianEquipDecompose', itemClassLV)  | 
|         if not ipyData:  | 
|             GameWorld.DebugLog('ZhuXianEquipDecompose Î´ÅäÖøý׼¶·Ö½âitemClassLV=%s' % itemClassLV, playerID)  | 
|             continue  | 
|         decomposeInfoDict = ipyData.GetDecomposeInfo()  | 
|         getItemDict = {}  | 
|         for itemIDList, rateList in decomposeInfoDict.items():  | 
|             giveitemCnt = GameWorld.GetResultByRandomList(rateList, 0)  | 
|             if not giveitemCnt:  | 
|                 continue  | 
|             if isinstance(itemIDList, tuple):  | 
|                 itemID = random.choice(itemIDList)  | 
|             else:  | 
|                 itemID = itemIDList  | 
|             giveItemDict[itemID] = giveItemDict.get(itemID, 0) + giveitemCnt  | 
|             getItemDict[itemID] = getItemDict.get(itemID, 0) + giveitemCnt  | 
|         saveDataDict = {'getItemDict':getItemDict, 'isAuto':isAuto}  | 
|         ItemCommon.DelItem(curPlayer, eatItem, 1, True, ChConfig.ItemDel_ZhuXianDecompose, saveDataDict)  | 
|     if giveItemDict:  | 
|         needSpace = len(giveItemDict)  | 
|         packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)  | 
|         if packSpace < needSpace:  | 
|             prizeItemList = [[giveItemID, itemCnt, 1] for giveItemID, itemCnt in giveItemDict.items()]  | 
|             PlayerControl.SendMailByKey("DefaultLackSpace", [curPlayer.GetPlayerID()], prizeItemList)  | 
|         else:  | 
|             for giveItemID, itemCnt in giveItemDict.items():  | 
|                 ItemControler.GivePlayerItem(curPlayer, giveItemID, itemCnt, True, [IPY_GameWorld.rptItem], True)  | 
|       | 
|     #֪ͨ½á¹û  | 
|     packData = ChPyNetSendPack.tagMCZhuXianDecomposeResult()  | 
|     packData.Clear()  | 
|     packData.ItemList = []  | 
|     for itemID, itemCnt in giveItemDict.items():  | 
|         itemInfo = ChPyNetSendPack.tagMCZhuXianDecomposeItem()  | 
|         itemInfo.ItemID = itemID  | 
|         itemInfo.ItemCnt = itemCnt  | 
|         itemInfo.IsBind = 1  | 
|         packData.ItemList.append(itemInfo)  | 
|     packData.Cnt = len(packData.ItemList)  | 
|     NetPackCommon.SendFakePack(curPlayer, packData)  | 
|     return  |