| #!/usr/bin/python | 
| # -*- coding: GBK -*- | 
| #------------------------------------------------------------------------------- | 
| # | 
| ##@package TurnAttack | 
| # | 
| # @todo:»ØºÏÖÆ¹¥»÷Âß¼ | 
| # @author hxp | 
| # @date 2023-11-30 | 
| # @version 1.0 | 
| # | 
| # ÏêϸÃèÊö: »ØºÏÖÆ¹¥»÷Âß¼£¬¾ùʹÓÃNPCʵÀý×÷Ϊս¶·Ö÷Ìå | 
| # | 
| #------------------------------------------------------------------------------- | 
| #"""Version = 2023-11-30 15:30""" | 
| #------------------------------------------------------------------------------- | 
|   | 
| import ChConfig | 
| import AICommon | 
| import BaseAttack | 
| import PlayerState | 
| import IpyGameDataPY | 
| import IPY_GameWorld | 
| import ChPyNetSendPack | 
| import PlayerViewCacheTube | 
| import NetPackCommon | 
| import PlayerControl | 
| import SkillCommon | 
| import NPCCommon | 
| import GameWorld | 
| import GameObj | 
| import PetControl | 
| import SkillShell | 
| import BuffSkill | 
| import FBCommon | 
| import PassiveBuffEffMng | 
| import FBLogic | 
| import ShareDefine | 
|   | 
| # »ØºÏÕ½¶·Á÷³Ì״̬ | 
| ( | 
| FightState_Start, # 0 Æðʼ״̬£¬ÎÞÌØÊâÒâÒ壬½ö´ú±í¿ªÊ¼ÁË£¬ÓëOver¶ÔÓ¦ | 
| FightState_PrepareOK, # 1 ×¼±¸Íê±Ï£¬°üº¬¶ÔÕ½NPCÕÙ»½OK¡¢ÆäËûµÈ | 
| FightState_Fighting, # 2 Õ½¶·ÖÐ | 
| FightState_FightEnd, # 3 Õ½¶·½áÊø | 
| FightState_Award, # 4 ½áËã½±Àø | 
| FightState_Over, # 5 ½áÊø×´Ì¬£¬ÎÞÌØÊâÒâÒ壬½ö´ú±íËùÓд¦Àí½áÊøÁË£¬ÓëStart¶ÔÓ¦ | 
| ) = range(6) | 
|   | 
| # »ØºÏÕ½¶·¸´»îÀàÐÍ | 
| ( | 
| RebornType_PetSkill, # ÁéÊÞ¸´»î£¬°üº¬Áé³è×ÔÉí¼¼ÄÜ »ò ÓÉÁé³è´¥·¢µÄ¼¼ÄÜ | 
| RebornType_ElfSkill, # ¾«¹Ö¸´»î | 
| RebornType_ShentongSkill, # Éñͨ¸´»î - ÓÉÖ÷½Ç×Ô¼º´¥·¢£¬Áé³è´¥·¢µÄÉñͨ¼¼ÄܹéΪÁé³è¸´»î | 
| ) = range(1, 1 + 3) | 
|   | 
| Def_FactionA = 1 | 
| Def_FactionB = 2 | 
|   | 
| class TurnFightBattle(): | 
|      | 
|     def __init__(self): | 
|         self.CleaerBat() | 
|         return | 
|      | 
|     def CleaerBat(self): | 
|         self.curPlayer = None | 
|         self.mapID = 0 | 
|         self.funcLineID = 0 | 
|         self.tagType = 0 | 
|         self.tagID = 0 | 
|         self.valueList = [] | 
|          | 
|         self.factionObjListDict = {} # ÕóÓªËùÓÐÕ½¶·ÊµÀý£¬°üº¬Ö÷Ìå¡¢Áé³è {ÕóÓª:[obj, ...], ...} | 
|         self.factionMainObjListDict = {} # ÕóÓªËùÓÐÕ½¶·Ö÷Ì壬 {ÕóÓª:[obj, ...], ...} | 
|         self.objTotalHurtDict = {} # Õ½¶·ÊµÀýÀÛ¼ÆÊä³ö {objID:totalHurtValue, ...} | 
|         self.factionTotalHurtDict = {} # ÕóÓªÀÛ¼ÆÊä³ö {faction:totalHurtValue, ...} | 
|         self.fbData = {} # Õ½¶·¹ØÁª¸±±¾×Ô¶¨ÒåÏà¹ØÊý¾Ý {key:value, ...} | 
|         return | 
|      | 
|     def SetBattle(self, curPlayer, mapID, funcLineID, tagType, tagID, valueList): | 
|         self.curPlayer = curPlayer | 
|         self.mapID = mapID | 
|         self.funcLineID = funcLineID | 
|         self.tagType = tagType | 
|         self.tagID = tagID | 
|         self.valueList = valueList | 
|         return | 
|      | 
|     def SetFactionObj(self, faction, objList, mainObjList): | 
|         self.factionObjListDict[faction] = objList | 
|         self.factionMainObjListDict[faction] = mainObjList | 
|         return | 
|      | 
|     def GetTagMainObj(self): | 
|         ## »ñÈ¡¶Ô·½Õ½¶·Ö÷Ìå | 
|         if Def_FactionB not in self.factionMainObjListDict: | 
|             return | 
|         mainObjList = self.factionMainObjListDict[Def_FactionB] | 
|         if not mainObjList: | 
|             return | 
|         return mainObjList[0] | 
|      | 
|     def AddObjHurtValue(self, curObj, hurtValue): | 
|         objID = curObj.GetID() | 
|         faction = GameObj.GetFaction(curObj) | 
|         updHurtValue = self.objTotalHurtDict.get(objID, 0) + hurtValue | 
|         self.objTotalHurtDict[objID] = updHurtValue | 
|          | 
|         factionHurtValue = self.factionTotalHurtDict.get(faction, 0) + hurtValue | 
|         self.factionTotalHurtDict[faction] = factionHurtValue | 
|          | 
|         # Íæ¼ÒÕóÓª | 
|         if faction == Def_FactionA: | 
|             FBLogic.OnTurnFightPlayerFactionHurt(self.curPlayer, self.mapID, self.funcLineID, curObj, hurtValue, factionHurtValue) | 
|         return updHurtValue | 
|      | 
| g_turnFightBattle = TurnFightBattle() | 
| def GetTurnFightBattle(): | 
|     global g_turnFightBattle | 
|     return g_turnFightBattle | 
|   | 
| def GetObjName(gameObj): | 
|     objName = gameObj.GetName() | 
|     faction = GameObj.GetFaction(gameObj) | 
|     fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) | 
|     curID = gameObj.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID) | 
|     if not curID and gameObj.GetGameObjType() == IPY_GameWorld.gotNPC: | 
|         curID = gameObj.GetNPCID() | 
|     return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", fightPlaceNum, objName, gameObj.GetID(), curID) | 
|   | 
| #// B4 10 »ØºÏÖÆÕ½¶· #tagCMTurnFight | 
| # | 
| #struct    tagCMTurnFight | 
| #{ | 
| #    tagHead        Head; | 
| #    DWORD        MapID;    // ×Ô¶¨ÒåµØÍ¼ID£¬¿ÉÓÃÓÚ°ó¶¨Õ½¶·³¡¾°¹¦ÄÜ£¨ÈçÒ°Íâ¹Ø¿¨£¬ÅÀËþ¹¦ÄÜ£¬¾º¼¼³¡µÈ£© | 
| #    WORD        FuncLineID; | 
| #    BYTE        TagType;    // Õ½¶·Ä¿±êÀàÐÍ£¬0-NPC£¬1-Íæ¼Ò£¬2-¶ÓÎé | 
| #    DWORD        TagID;    // Õ½¶·Ä¿±êÀàÐͶÔÓ¦µÄID | 
| #    BYTE        ValueCount; | 
| #    DWORD        ValueList[ValueCount]; // ¸½¼ÓÖµÁÐ±í£¬¿ÉÑ¡£¬¾ßÌ庬ÒåÓÉMapID¾ö¶¨ | 
| #}; | 
| def OnTurnFight(index, clientData, tick): | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) | 
|     mapID = clientData.MapID | 
|     funcLineID = clientData.FuncLineID | 
|     tagType = clientData.TagType | 
|     tagID = clientData.TagID | 
|     valueList = clientData.ValueList | 
|      | 
|     playerID = curPlayer.GetPlayerID() | 
|     if tagType == ChConfig.TurnBattle_TagType_Player: | 
|         if tagID == playerID: | 
|             GameWorld.DebugLog("²»ÄÜ´ò×Ô¼º!", playerID) | 
|             return | 
|          | 
|     fbIpyData = FBCommon.GetFBIpyData(mapID) | 
|     fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, funcLineID) | 
|     if fbIpyData or fbLineIpyData: | 
|         if FBCommon.CheckCanEnterFBComm(curPlayer, mapID, funcLineID, fbIpyData, fbLineIpyData) != ShareDefine.EntFBAskRet_OK: | 
|             return | 
|          | 
|     reqRet = FBLogic.OnTurnFightRequest(curPlayer, mapID, funcLineID, tagType, tagID, valueList) | 
|     if not reqRet: | 
|         return | 
|      | 
|     # ÐèÒª·¢Ë͵½GameServerÑéÖ¤ | 
|     if mapID in ChConfig.Def_TFMapID_SendToGameServer: | 
|         SendToGameServer_TurnFight(curPlayer, "TurnFightRequest", [mapID, funcLineID, tagType, tagID, valueList]) | 
|         return | 
|      | 
|     DoTurnFightProcess(curPlayer, mapID, funcLineID, tagType, tagID, valueList, tick) | 
|     return | 
|   | 
| def SendToGameServer_TurnFight(curPlayer, msgType, dataMsg=""): | 
|     playerID = curPlayer.GetPlayerID() | 
|     msgList = str([msgType, dataMsg]) | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "TurnFight", msgList, len(msgList)) | 
|     GameWorld.Log("»ØºÏÕ½¶··¢ËÍGameServer: %s, %s" % (msgType, dataMsg), playerID) | 
|     return | 
|   | 
| def GameServer_TurnFight_DoResult(curPlayer, msgData, tick): | 
|      | 
|     msgType, dataMsg, ret = msgData | 
|      | 
|     if not ret: | 
|         return | 
|      | 
|     if msgType == "TurnFightRequest": | 
|         mapID, funcLineID, tagType, tagID, valueList = dataMsg | 
|         DoTurnFightProcess(curPlayer, mapID, funcLineID, tagType, tagID, valueList, tick) | 
|          | 
|     elif msgType == "TurnFightOver": | 
|         mapID, funcLineID, tagType, tagID, valueList, fightRet, awardItemList = dataMsg | 
|         FBLogic.OnTurnFightOver_GameServerRet(curPlayer, mapID, funcLineID, tagType, tagID, valueList, fightRet, awardItemList, ret) | 
|          | 
|     return | 
|   | 
| def DoTurnFightProcess(curPlayer, mapID, funcLineID, tagType, tagID, valueList, tick): | 
|     ## Ö´ÐлغÏÖÆÕ½¶·µÄÍêÕûÁ÷³Ì | 
|      | 
|     if curPlayer.GetSightLevel() != curPlayer.GetID(): | 
|         PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID()) | 
|          | 
|     SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_Start) | 
|      | 
|     if tagType == ChConfig.TurnBattle_TagType_Player: | 
|         PlayerViewCacheTube.GetPlayerPropDataCall(curPlayer, tagID, DoTrunFightVSPlayer, [mapID, funcLineID, valueList], True) | 
|         return | 
|      | 
|     DoTrunFight(curPlayer, mapID, funcLineID, tagType, tagID, valueList, tick) | 
|      | 
|     SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_Over) | 
|     return | 
|   | 
| def DoTrunFightVSPlayer(curPlayer, tagPlayerID, callData, PropDict): | 
|     tagType = ChConfig.TurnBattle_TagType_Player | 
|     tagID = tagPlayerID | 
|     mapID, funcLineID, valueList = callData | 
|     if PropDict and curPlayer.GetPlayerID() != tagPlayerID: | 
|         tick = GameWorld.GetGameWorld().GetTick() | 
|         DoTrunFight(curPlayer, mapID, funcLineID, tagType, tagID, valueList, tick) | 
|     SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_Over) | 
|     return | 
|   | 
| def DoTrunFight(curPlayer, mapID, funcLineID, tagType, tagID, valueList, tick): | 
|     if not tagID: | 
|         return | 
|     playerID = curPlayer.GetPlayerID() | 
|     factionInfoA = GetPlayerFactionInfoByCache(playerID) | 
|     if tagType == ChConfig.TurnBattle_TagType_Player: | 
|         factionInfoB = GetPlayerFactionInfoByCache(tagID) | 
|     elif tagType == ChConfig.TurnBattle_TagType_NPC: | 
|         npcID = tagID | 
|         npcDataEx = NPCCommon.GetNPCDataEx(npcID) | 
|         petNPCIDList = npcDataEx.GetPetNPCIDList() | 
|         petCacheInfo = [] # ´ÓÅä±íÖжÁÈ¡×éºÏ£¬¼¼ÄÜĬÈÏÈ¡NPC±íÅäÖÃµÄ | 
|         for state, petNPCID in enumerate(petNPCIDList, 1): | 
|             petCacheInfo.append({"npcID":petNPCID, "state":state, "quality":0}) | 
|         skillIDExList = [] # NPCΪ¸½¼Ó¼¼ÄÜ£¬ÒòΪNPC±í±¾Éí¿ÉÄÜÓÐÅäÖü¼ÄÜ | 
|         skillIDExList.extend(npcDataEx.GetElfSkillIDList()) | 
|         skillIDExList.extend(npcDataEx.GetSTSkillIDList()) | 
|         factionInfoB = {"npcID":npcID, "pet":petCacheInfo, "skillIDExList":skillIDExList} | 
|     else: | 
|         return | 
|      | 
|     curPlayer.SetCanAttack(False) # ¸ÃÍæ¼ÒÉèÖÃΪ²»¿É±»¹¥»÷ | 
|     playerID = curPlayer.GetPlayerID() | 
|     sightLevel, posX, posY = playerID, curPlayer.GetPosX(), curPlayer.GetPosY() | 
|      | 
|     factionA, factionB, mainRolePlace = Def_FactionA, Def_FactionB, 1 | 
|     objRetA = __SummonFactionObjs(factionA, mainRolePlace, factionInfoA, sightLevel, posX, posY) | 
|     objRetB = __SummonFactionObjs(factionB, mainRolePlace, factionInfoB, sightLevel, posX, posY) | 
|     objA, petObjListA, factionSyncInfoA = objRetA if objRetA else (None, [], {}) | 
|     objB, petObjListB, factionSyncInfoB = objRetB if objRetB else (None, [], {}) | 
|     if not objA or not objB: | 
|         fightObjList = petObjListA + [objA] + petObjListB + [objB] | 
|         for gameObj in fightObjList: | 
|             TurnFightObjOverReset(gameObj, tick) | 
|         return | 
|      | 
|     tfBattle = GetTurnFightBattle() | 
|     tfBattle.CleaerBat() | 
|     tfBattle.SetBattle(curPlayer, mapID, funcLineID, tagType, tagID, valueList) | 
|      | 
|     playerIDA = objA.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID) # ¿ÉÄÜΪ0£¬·ÇÍæ¼Ò¾µÏñʱΪ0 | 
|     playerIDB = objB.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID) # ¿ÉÄÜΪ0£¬·ÇÍæ¼Ò¾µÏñʱΪ0 | 
|      | 
|     objNameA = GetObjName(objA) | 
|     objNameB = GetObjName(objB) | 
|     GameWorld.DebugLog("===== Ö´ÐлغÏÖÆÕ½¶·: %s VS %s =====" % (objNameA, objNameB)) | 
|      | 
|     turnMax = IpyGameDataPY.GetFuncCfg("TurnFight", 1) | 
|     # ³èÎïÏȹ¥»÷ | 
|     factionListA = petObjListA + [objA] | 
|     factionListB = petObjListB + [objB] | 
|     atkFactionList = [factionListA, factionListB] | 
|     tfBattle.SetFactionObj(factionA, factionListA, [objA]) | 
|     tfBattle.SetFactionObj(factionB, factionListB, [objB]) | 
|      | 
|     # ÉèÖÃÕ½¶·Ö÷Ìå | 
|     objA.SetDict(ChConfig.Def_Obj_Dict_TurnEnemyID, objB.GetID()) | 
|     objB.SetDict(ChConfig.Def_Obj_Dict_TurnEnemyID, objA.GetID()) | 
|      | 
|     # Õ½¶·Ç°³õʼ»¯£¬¿ÉÄÜ»á¸Ä±ä¹¥ËÙ£¬ËùÒÔÏȳõʼ»¯ | 
|     for factionObjList in atkFactionList: | 
|         for gameObj in factionObjList: | 
|             if not gameObj: | 
|                 continue | 
|             faction = GameObj.GetFaction(gameObj) | 
|             tagGameObj = objB if faction == Def_FactionA else objA | 
|             TurnFightObjStartInit(mapID, playerID, gameObj, tagGameObj, tick) | 
|              | 
|     #Ò»¸ö»ØºÏ¹¥»÷˳Ðò£¬ÎªÁ˺óÐøÂ߼ͳһ£¬¶¼ÊÇÏÈÈ·¶¨ºÃ˳Ðò | 
|     sortType = 2 # ¹¥»÷˳ÐòÅÅÐò·½Ê½ | 
|     fightObjList = [] | 
|     #·½Ê½1£º ´¿Óɹ¥»÷ËٶȾö¶¨£¬¹¥ËÙÏàͬÏÂÕóÓª1Ïȹ¥»÷£¬»¹ÏàͬÔòÓÉID¾ö¶¨ | 
|     if sortType == 1: | 
|         fightObjList = factionListA + factionListB | 
|         fightObjList.sort(key=lambda o: (GameObj.GetAtkSpeed(o), (10 - GameObj.GetFaction(o)), o.GetID()), reverse=True) | 
|     #·½Ê½2£º¸ù¾ÝÕóÓªÖ÷½Ç¹¥ËÙ¾ö¶¨ÏÈÊÖ£¬È»ºóÿ¸öÕóÓªÂÖÁ÷¹Ì¶¨Î»Öù¥»÷ | 
|     elif sortType == 2: | 
|         if GameObj.GetAtkSpeed(objA) < GameObj.GetAtkSpeed(objB): | 
|             atkFactionList = [factionListB, factionListA] | 
|         for i in range(len(factionListA)): | 
|             for factionObjList in atkFactionList: | 
|                 fightObjList.append(factionObjList[i]) | 
|                  | 
|     SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_PrepareOK, msg=[factionSyncInfoA, factionSyncInfoB]) | 
|      | 
|     isWin = None | 
|     for turnNum in range(1, turnMax + 1): | 
|         GameWorld.DebugLog("¡¾----- »ØºÏÖÆÕ½¶·ÂÖ´Î: %s -----¡¿" % turnNum) | 
|         SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_Fighting, turnNum, turnMax) | 
|          | 
|         # »ØºÏ¿ªÊ¼: ×öһЩÿ»ØºÏÖØÖÃÂß¼»òÕßijЩ¸ù¾Ý»ØºÏ´¥·¢µÄЧ¹ûµÈ | 
|         for gameObj in fightObjList: | 
|             if not gameObj: | 
|                 continue | 
|             faction = GameObj.GetFaction(gameObj) | 
|             tagGameObj = objB if faction == Def_FactionA else objA | 
|             TurnFightObjPerTurnStart(gameObj, tagGameObj, turnNum, tick) | 
|              | 
|         isWin = CheckIswin(objA, objB) | 
|         if isWin != None: | 
|             break | 
|          | 
|         # »ØºÏÕ½¶·£º ÂÖÁ÷ÒÀ´Î¹¥»÷ | 
|         for actionNum, gameObj in enumerate(fightObjList, 1): | 
|             if not gameObj: | 
|                 # Ã»ÓжÔÏó¿ÉÊÓΪûÓиýڵã | 
|                 continue | 
|              | 
|             for obj in fightObjList: | 
|                 TurnFightObjPerTurnActionnum(turnNum, actionNum, obj, tick) | 
|                  | 
|             objType = gameObj.GetGameObjType() | 
|             objID = gameObj.GetID() | 
|             SyncTurnFightObjAction(curPlayer, turnNum, objType, objID) | 
|              | 
|             if GameObj.GetHP(gameObj) <= 0: | 
|                 # ¸´»îʱ»úÔÚ×Ô¼ºÐж¯½Úµã | 
|                 if not DoReborn(gameObj): | 
|                     continue | 
|                  | 
|             faction = GameObj.GetFaction(gameObj) | 
|             objName = GetObjName(gameObj) | 
|             curHP = GameObj.GetHP(gameObj) | 
|              | 
|             tagGameObj = objB if faction == Def_FactionA else objA | 
|             tagObjType = tagGameObj.GetGameObjType() | 
|             tagObjID = tagGameObj.GetID() | 
|             tagHP = GameObj.GetHP(tagGameObj) | 
|              | 
|             GameWorld.DebugLog("¡ï»ØºÏ%s.%s %s Ðж¯ : objType-ID-HP(%s-%s-%s),curAtk=%s, tagType-ID-HP(%s-%s-%s)"  | 
|                                % (turnNum, actionNum, objName, objType, objID, curHP, gameObj.GetMaxAtk(), tagObjType, tagObjID, tagHP)) | 
|              | 
|             if not DoAttack(gameObj, tagGameObj, tick, checkUseXP=True): | 
|                 continue | 
|              | 
|             isWin = CheckIswin(objA, objB) | 
|             if isWin != None: | 
|                 break | 
|              | 
|         if isWin != None: | 
|             break | 
|          | 
|     isWin = FBLogic.OnTurnFightIsWin(curPlayer, mapID, funcLineID, tagType, tagID, valueList, isWin) | 
|     GameWorld.DebugLog("--- Õ½¶·½áÊø´¦Àí --- isWin=%s" % isWin) | 
|     isWin = 1 if isWin else 0 | 
|      | 
|     # Í³¼Æ×ÜÉ˺¦ | 
|     factionTotalHurtDict = tfBattle.factionTotalHurtDict | 
|     for gameObj in fightObjList: | 
|         if not gameObj: | 
|             continue | 
|         faction = GameObj.GetFaction(gameObj) | 
|         objName = GetObjName(gameObj) | 
|         objID = gameObj.GetID() | 
|         totalHurt = tfBattle.objTotalHurtDict.get(objID, 0) | 
|         GameWorld.DebugLog("%s objID=%s,faction=%s, ×ÜÊä³ö: %s" % (objName, objID, faction, totalHurt)) | 
|     for faction, totalHurt in factionTotalHurtDict.items(): | 
|         GameWorld.DebugLog("faction=%s, ÕóÓª×ÜÊä³ö: %s" % (faction, totalHurt)) | 
|          | 
|     GameWorld.DebugLog("AÊ£ÓàѪÁ¿: %s / %s" % (GameObj.GetHP(objA), GameObj.GetMaxHP(objA))) | 
|     GameWorld.DebugLog("BÊ£ÓàѪÁ¿: %s / %s" % (GameObj.GetHP(objB), GameObj.GetMaxHP(objB))) | 
|      | 
|     SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_FightEnd, turnNum, turnMax) | 
|          | 
|     playbackID = 0 # Õ½¶·»Ø·ÅID£¬¿É¸ù¾Ý¸ÃID²é¿´»Ø·Å | 
|     #playbackInfo = "" # Õ½¶·»Ø·ÅÐÅÏ¢ | 
|     #if isSavePlayback: | 
|     #    pass | 
|      | 
|     GameWorld.DebugLog("===== »ØºÏÖÆÕ½¶·½áÊø: mapID=%s,funcLineID=%s,playerIDA=%s,playerIDB=%s,isWin=%s"  | 
|                        % (mapID, funcLineID, playerIDA, playerIDB, isWin)) | 
|      | 
|     # Õ½¶·½áÊøºó´¦Àí | 
|     fightRet = [isWin, turnNum, turnMax, factionTotalHurtDict, playbackID] | 
|      | 
|     needSendGameServer, awardItemList, overInfoEx = False, [], {} | 
|     overRet = FBLogic.OnTurnFightOver(curPlayer, mapID, funcLineID, tagType, tagID, valueList, fightRet) | 
|     if overRet != None: | 
|         needSendGameServer, awardItemList, overInfoEx = overRet | 
|          | 
|     if needSendGameServer or mapID in ChConfig.Def_TFMapID_SendToGameServer: | 
|         SendToGameServer_TurnFight(curPlayer, "TurnFightOver", [mapID, funcLineID, tagType, tagID, valueList, fightRet, awardItemList]) | 
|          | 
|     overMsg = {"isWin":isWin, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(awardItemList), "totalHurt":factionTotalHurtDict.get(Def_FactionA, 0)} | 
|     playbackID and overMsg.update({"playbackID":playbackID}) | 
|     overInfoEx and overMsg.update(overInfoEx) | 
|     SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, FightState_Award, turnNum, turnMax, overMsg) | 
|      | 
|     # ¶¼´¦ÀíÍê±ÏÁË£¬»ØÊÕ¶ÔÏó£¬ÖØÖÃÊý¾Ý | 
|     for gameObj in fightObjList: | 
|         TurnFightObjOverReset(gameObj, tick) | 
|     tfBattle.CleaerBat() | 
|     return | 
|   | 
| def GetPlayerFactionInfoByCache(playerID): | 
|     ## ¸ù¾ÝÍæ¼Ò»º´æÊý¾Ý»ñÈ¡¶ÔÕóÍæ¼ÒÕóÓªÐÅÏ¢×Öµä | 
|     PropDict, PlusDict = PlayerViewCacheTube.GetPlayerPropPlusDictByID(playerID, True) # ´Ó»º´æÖлñÈ¡£¬Ç¿Ë¢Ò»´Î×îÐÂÊôÐÔ | 
|     skillIDList = [] | 
|     SkillInfo = PlusDict.get("SkillInfo", {}) | 
|     for _, skillLVDict in SkillInfo.items(): | 
|         for skillID, _ in skillLVDict.items(): | 
|             skillID = GameWorld.ToIntDef(skillID) | 
|             skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID) | 
|             if not skillData: | 
|                 continue | 
|             skillIDList.append(skillID) | 
|     return {"playerID":playerID, "pet":PlusDict.get("Pet"), "skillIDList":skillIDList, "ModelMark":PropDict.get("ModelMark", 0)} | 
|   | 
| def __SummonFactionObjs(faction, mainRolePlace, objInfo, sightLevel, posX, posY): | 
|     '''ÕÙ»½ÕóÓªÕ½¶·ÊµÀý | 
|     @param faction: ËùÊôÕóÓª£¬Ä¿Ç°Ö§³ÖÁ½¸öÕóÓª£¬1»ò2 | 
|     @param mainRolePlace: Õ½¶·Ö÷ÌåÔÚ¸ÃÕóÓªÉÏÕóλÖã¬1V1ʱĬÈÏ1£¬¶à¶Ô¶àʱ£¬´ú±íËùÔÚÕóӪλÖà | 
|     @param objInfo: ¸ÃÕ½¶·Ö÷Ìå³öÕ½ÐÅÏ¢ | 
|     ''' | 
|     factionSyncInfo = {} # Í¬²½Ç°¶ËµÄÕóÓªÐÅÏ¢£¬°üº¬Ö÷ID¡¢Áé³è¡¢ÆäËûÁéͨµÈ | 
|     playerID = objInfo.get("playerID") | 
|     npcID = objInfo.get("npcID") | 
|     skillIDList = objInfo.get("skillIDList") # ¼¼ÄÜIDÁбí | 
|     skillIDExList = objInfo.get("skillIDExList") # ¸½¼Ó¼¼ÄÜIDÁбí | 
|     if playerID: | 
|         npcID = ChConfig.Def_NPCID_PVP | 
|         mainObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=sightLevel, mirrorPlayerID=playerID, skillIDList=skillIDList, skillIDExList=skillIDExList) | 
|         factionSyncInfo["playerID"] = playerID | 
|         factionSyncInfo["ModelMark"] = objInfo.get("ModelMark", 0) | 
|     elif npcID: | 
|         mainObj = NPCCommon.SummonMapNpc(npcID, posX, posY, sightLevel=sightLevel, skillIDList=skillIDList, skillIDExList=skillIDExList) | 
|         factionSyncInfo["npcID"] = npcID | 
|     else: | 
|         return | 
|     if not mainObj: | 
|         return | 
|     GameObj.SetFaction(mainObj, faction) | 
|     mainObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace, mainRolePlace) | 
|     petObjList = PetControl.CalloutFightPet(mainObj, objInfo.get("pet")) | 
|     petObjIDList = [] | 
|     for petObj in petObjList: | 
|         if petObj: | 
|             petObjIDList.append(petObj.GetID()) | 
|     factionSyncInfo.update({"objID":mainObj.GetID(), "petObjIDList":petObjIDList}) | 
|     return mainObj, petObjList, factionSyncInfo | 
|   | 
| def CheckIswin(curPlayer, tagObj): | 
|     ## ¼ì²éÊÇ·ñ½áÊø | 
|     # @return: None-δ½áÊø£»True-»ñʤ£»False-ʧ°Ü | 
|     playerDead = GameObj.GetHP(curPlayer) <= 0 and GetRebornTypeInfo(curPlayer) == None | 
|     tagObjDead = (not tagObj or GameObj.GetHP(tagObj) <= 0) and GetRebornTypeInfo(tagObj) == None | 
|      | 
|     if not playerDead and not tagObjDead: | 
|         return | 
|      | 
|     isWin = None | 
|     if playerDead and tagObjDead: | 
|         isWin = False # Æ½¾ÖËãʧ°Ü | 
|         GameWorld.DebugLog("        Ë«·½±»»÷ɱ£¬Æ½¾ÖËãʧ°Ü: isWin=%s" % isWin) | 
|     elif playerDead: | 
|         isWin = False | 
|         GameWorld.DebugLog("        Íæ¼Ò±»»÷ɱ£¬Ê§°Ü: isWin=%s" % isWin) | 
|     elif tagObjDead: | 
|         isWin = True # Ê¤Àû | 
|         GameWorld.DebugLog("        ¶ÔÊÖ±»»÷ɱ£¬Ê¤Àû: isWin=%s" % isWin) | 
|          | 
|     return isWin | 
|   | 
| def SetKilled(gameObj, killer=None): | 
|     if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace): | 
|         #GameWorld.DebugLog("·Ç»ØºÏÕ½¶·Ö÷Ìå±»»÷ɱ: curID=%s" % gameObj.GetID()) | 
|         return | 
|      | 
|     GameWorld.DebugLog("        %s »ØºÏÕ½¶·Ö÷Ìå±»»÷ɱ: curID=%s" % (GetObjName(gameObj), gameObj.GetID())) | 
|     GameObj.SetHP(gameObj, 0) | 
|      | 
|     playerID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightID) | 
|     if not playerID: | 
|         return | 
|     curPlayer = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(playerID) | 
|     if not curPlayer: | 
|         return | 
|      | 
|     # Í¨ÖªÇ°¶Ë | 
|     clientPack = ChPyNetSendPack.tagMCTurnFightObjDead() | 
|     clientPack.ObjID = gameObj.GetID() | 
|     clientPack.ObjType = gameObj.GetGameObjType() | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack) | 
|     return True | 
|   | 
| def GetEnemyObj(gameObj): | 
|     ## »ñÈ¡»ØºÏ¶ÔÊÖʵÀý | 
|     tagID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnEnemyID) | 
|     if not tagID: | 
|         return | 
|     return GameWorld.FindNPCByID(tagID) | 
|   | 
| def GetRebornTypeInfo(gameObj): | 
|     ''' »ñÈ¡¿É¸´»îµÄ·½Ê½ÐÅÏ¢ | 
|     @return: None-´ú±í²»¿É¸´»î | 
|     ''' | 
|     if not gameObj: | 
|         return | 
|      | 
|     if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace): | 
|         # ½öÖ÷Ìå¿É¸´»î | 
|         return | 
|      | 
|     rebornCountMax = 1 | 
|     curRebornCount = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnRebornCount) | 
|     if curRebornCount >= rebornCountMax: | 
|         GameWorld.DebugLog("%s ÒѾ³¬¹ý¸´»î´ÎÊý£¬²»ÄÜÔÙ¸´»î! curID=%s,curRebornCount=%s" % (GetObjName(gameObj), gameObj.GetID(), curRebornCount)) | 
|         return | 
|                  | 
|     # ×Ô¼º¼¼ÄÜ  - È羫¹Ö | 
|     skillManager = gameObj.GetSkillManager() | 
|     for skillIndex in range(skillManager.GetSkillCount()): | 
|         skill = skillManager.GetSkillByIndex(skillIndex) | 
|         if skill.GetSkillType() != ChConfig.Def_SkillType_Revive: | 
|             continue | 
|         if skill.GetRemainTime(): | 
|             continue | 
|         isPetTrigger, triggerPet = GetTriggerRebornPet(gameObj, skill) # ¿ÉÄÜÓÉÁé³è´¥·¢µÄ | 
|         if isPetTrigger: | 
|             if triggerPet: | 
|                 return RebornType_PetSkill, triggerPet, skill | 
|             continue | 
|         if not CheckRoleStateCanUseRebornSkill(gameObj, skill): | 
|             continue | 
|         if skill.GetFuncType() == ChConfig.Def_SkillFuncType_ElfSkill: | 
|             return RebornType_ElfSkill, skill | 
|         if skill.GetFuncType() == ChConfig.Def_SkillFuncType_ShentongSkill: | 
|             return RebornType_ShentongSkill, skill | 
|          | 
|     # ¼ì²éÊÇ·ñÓÐÁé³è¸´»î¼¼ÄÜ | 
|     for index in range(gameObj.GetSummonCount()): | 
|         curSummonNPC = gameObj.GetSummonNPCAt(index) | 
|         if not curSummonNPC: | 
|             continue | 
|         if not PetControl.IsPetNPC(curSummonNPC): | 
|             continue | 
|         skillManager = curSummonNPC.GetSkillManager() | 
|         for skillIndex in range(skillManager.GetSkillCount()): | 
|             skill = skillManager.GetSkillByIndex(skillIndex) | 
|             if skill.GetSkillType() != ChConfig.Def_SkillType_Revive: | 
|                 continue | 
|             if not skill.GetRemainTime(): | 
|                 return RebornType_PetSkill, curSummonNPC, skill | 
|              | 
|     # ¼ì²éÆäËû¹¦Äܸ´»î£¬´ýÀ©Õ¹... | 
|      | 
|     #GameWorld.DebugLog("    Ã»ÓпÉÒÔ¸´»îµÄ·½Ê½!") | 
|     return | 
|   | 
| def GetTriggerRebornPet(gameObj, skill): | 
|     ## »ñÈ¡Áé³è´¥·¢µÄ¸´»îÐÅÏ¢ | 
|     # @return: ÊÇ·ñÓÉÁé³è´¥·¢, ´¥·¢µÄÁé³èʵÀý | 
|     isPetTrigger, triggerPet = False, None | 
|     if SkillShell.GetSkillAffectTag(skill) != ChConfig.Def_UseSkillTag_SummonMaster: | 
|         return isPetTrigger, triggerPet | 
|      | 
|     isPetTrigger = True | 
|     for index in range(gameObj.GetSummonCount()): | 
|         curSummonNPC = gameObj.GetSummonNPCAt(index) | 
|         if not curSummonNPC: | 
|             continue | 
|         if PetControl.IsPetNPC(curSummonNPC): | 
|             triggerPet = curSummonNPC | 
|             break | 
|     return isPetTrigger, triggerPet | 
|   | 
| def CheckRoleStateCanUseRebornSkill(gameObj, skill): | 
|     ## ¼ì²éÖ÷½Çµ±Ç°×´Ì¬ÊÇ·ñ¿ÉÒÔʹÓø´»î¼¼ÄÜ | 
|      | 
|     # ÔÝʱĬÈÏ¿ÉÒÔ£¬Ñ°µÀ±ù¶³×´Ì¬²»¿ÉÒÔ | 
|     return True | 
|   | 
| def DoReborn(gameObj, hpPer=ChConfig.Def_MaxRateValue): | 
|     ## Ö´Ðи´»î | 
|     rebornTypeInfo = GetRebornTypeInfo(gameObj) | 
|     if rebornTypeInfo == None: | 
|         return | 
|      | 
|     objName = GetObjName(gameObj) | 
|     objID = gameObj.GetID() | 
|     objType = gameObj.GetGameObjType() | 
|      | 
|     rebornType = rebornTypeInfo[0] | 
|     rebornValue1, rebornValue2 = 0, 0 | 
|     if rebornType == RebornType_PetSkill: | 
|         petNPC, skill = rebornTypeInfo[1:] | 
|         skill.SetRemainTime(skill.GetCoolDownTime()) | 
|         hpPer = skill.GetEffect(0).GetEffectValue(0) | 
|         rebornValue1 = petNPC.GetID() | 
|         rebornValue2 = skill.GetSkillID() | 
|     elif rebornType in [RebornType_ElfSkill, RebornType_ShentongSkill]: | 
|         skill = rebornTypeInfo[1] | 
|         skill.SetRemainTime(skill.GetCoolDownTime()) | 
|         hpPer = skill.GetEffect(0).GetEffectValue(0) | 
|         rebornValue1 = skill.GetSkillID() | 
|          | 
|     rebornCount = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnRebornCount) + 1 | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnRebornCount, rebornCount) | 
|     setHP = int(GameObj.GetMaxHP(gameObj) * hpPer / float(ChConfig.Def_MaxRateValue)) | 
|     GameObj.SetHP(gameObj, setHP) | 
|      | 
|     if objType == IPY_GameWorld.gotPlayer: | 
|         gameObj.ChangeAction(IPY_GameWorld.paNull) | 
|     else: | 
|         gameObj.ChangeAction(IPY_GameWorld.laNPCNull) | 
|          | 
|     curHP = GameObj.GetHP(gameObj) | 
|     GameWorld.DebugLog("¸´»î %s: rebornType=%s,objID=%s,hpPer=%s,curHP=%s,rebornCount=%s,rebornValue1=%s,rebornValue2=%s"  | 
|                        % (objName, rebornType, objID, hpPer, curHP, rebornCount, rebornValue1, rebornValue2)) | 
|      | 
|     playerID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightID) | 
|     if not playerID: | 
|         return | 
|     curPlayer = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(playerID) | 
|     if not curPlayer: | 
|         return | 
|      | 
|     # Í¨ÖªÇ°¶Ë | 
|     clientPack = ChPyNetSendPack.tagMCTurnFightObjReborn() | 
|     clientPack.ObjID = gameObj.GetID() | 
|     clientPack.ObjType = gameObj.GetGameObjType() | 
|     clientPack.HP = curHP % ChConfig.Def_PerPointValue | 
|     clientPack.HPEx = curHP / ChConfig.Def_PerPointValue | 
|     clientPack.RebornType = rebornType | 
|     clientPack.RebornValue1 = rebornValue1 | 
|     clientPack.RebornValue2 = rebornValue2 | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack) | 
|     return True | 
|   | 
| def GetTurnNum(timeline): return timeline / 100 | 
| def SetTimeline(gameObj, turnNum, actionNum): | 
|     '''ÉèÖûغÏÖÆÕ½¶·ËùÔÚʱ¼ä½Úµã | 
|     @param turnNum: µÚ¼¸»ØºÏ£¬Èç¹ûÔڻغÏÖÆÕ½¶·ÖУ¬Ôò»ØºÏÊýÒ»¶¨´óÓÚ0, | 
|     @param actionNum: µÚ¼¸¸öÐж¯½Úµã£¬Ã¿»ØºÏµÄÐж¯½Úµã»áÖØÖã¬Ò²¾ÍÊÇ˵Ðж¯½Úµã0¿ÉÊÓΪÿ»ØºÏµÄÆðʼ½Úµã£¬1λµÚÒ»¸öÐж¯Ä¿±ê½Úµã£¬ÒÔ´ËÀàÍÆ | 
|     ''' | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightTimeline, turnNum * 100 + actionNum) | 
|     return | 
|   | 
| def TurnFightObjStartInit(mapID, playerID, gameObj, tagObj, tick): | 
|     ## »ØºÏÖÆÕ½¶·ÊµÀý³õʼ»¯ | 
|     if not gameObj: | 
|         return | 
|     mainRolePlace = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightMapID, mapID) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightID, playerID) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnRebornCount, 0) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnSkillSuccessPetState, 0) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAttackOverPetState, 0) | 
|     SetTimeline(gameObj, 1, 0) | 
|     faction = GameObj.GetFaction(gameObj) | 
|     GameObj.SetHPFull(gameObj, True) | 
|     gameObj.RefreshView() | 
|      | 
|     objType = gameObj.GetGameObjType() | 
|     npcID = gameObj.GetNPCID() if objType == IPY_GameWorld.gotNPC else 0 | 
|     objName = GetObjName(gameObj) | 
|     fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) | 
|      | 
|     GameWorld.DebugLog("¡¾ %s ³õʼ»¯ %s ¡¿ objID=%s,npcID=%s,atkSpeed=%s,faction=%s,mainRolePlace=%s"  | 
|                        % (objName, BaseAttack.GetObjAttackName(gameObj), gameObj.GetID(), npcID, GameObj.GetAtkSpeed(gameObj), faction, mainRolePlace)) | 
|      | 
|     haveXPSkill = False | 
|     # ÖØÖü¼ÄÜCD¡¢Õ½¶·buff | 
|     if objType == IPY_GameWorld.gotPlayer:             | 
|         skillManager = gameObj.GetSkillManager() | 
|         for i in range(skillManager.GetSkillCount()): | 
|             curSkill = skillManager.GetSkillByIndex(i) | 
|             curSkill.SetRemainTime(0) | 
|              | 
|     elif objType == IPY_GameWorld.gotNPC: | 
|         skillIDList = [] | 
|         skillManager = gameObj.GetSkillManager() | 
|         for i in range(skillManager.GetSkillCount()): | 
|             curSkill = skillManager.GetSkillByIndex(i) | 
|             if not curSkill: | 
|                 continue | 
|             if mainRolePlace and curSkill.GetXP(): | 
|                 haveXPSkill = True | 
|             skillIDList.append(curSkill.GetSkillID()) | 
|             if fightPlaceNum: | 
|                 if curSkill.GetSkillType() != ChConfig.Def_SkillType_Revive: | 
|                     # Áé³è¼¼ÄÜ¿ªÊ¼Ê±Ö±½Ó½øÈëCD | 
|                     curSkill.SetLastUseTick(tick) | 
|                     curSkill.SetRemainTime(curSkill.GetCoolDownTime()) | 
|         GameWorld.DebugLog("    NPC¼¼ÄÜ: npcID=%s,skillIDList=%s" % (npcID, skillIDList)) | 
|          | 
|     if haveXPSkill: | 
|         GameObj.SetMaxXP(gameObj, IpyGameDataPY.GetFuncCfg("TurnFightXP", 1)) | 
|         GameObj.SetXP(gameObj, 0) # ½øÐÐÉèÖÃÒ»´Î֪ͨǰ¶Ë£¬ÊÓΪ¸æÖªÇ°¶Ë¸ÃʵÀýÓÐXP | 
|         gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, 0) | 
|         gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPFullTimeline, 0) | 
|          | 
|     PassiveBuffEffMng.OnPassiveSkillTrigger(gameObj, tagObj, None, ChConfig.TriggerType_TurnFightStart, tick) | 
|      | 
|     __logGameObjAttr(gameObj) | 
|     return | 
|   | 
| def __logGameObjAttr(gameObj): | 
|     GameWorld.DebugLog("    HP=%s/%s,atk=%s~%s,Def=%s,atkSpeed=%s"  | 
|                        % (GameObj.GetHP(gameObj), GameObj.GetMaxHP(gameObj), gameObj.GetMinAtk(), gameObj.GetMaxAtk(), | 
|                           gameObj.GetDef(), GameObj.GetAtkSpeed(gameObj))) | 
|     if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRolePlace): | 
|         return | 
|     GameWorld.DebugLog("    ÉÁ(%s,%s),±©(%s,%s),ÔÎ(%s,%s),Á¬(%s,%s),·´(%s,%s),Îü(%s,%s)"  | 
|                        % (GameObj.GetMissRate(gameObj), GameObj.GetMissDefRate(gameObj), | 
|                           GameObj.GetSuperHitRate(gameObj), GameObj.GetSuperHitRateReduce(gameObj), | 
|                           GameObj.GetFaintRate(gameObj), GameObj.GetFaintDefRate(gameObj), | 
|                           GameObj.GetComboRate(gameObj), GameObj.GetComboDefRate(gameObj), | 
|                           GameObj.GetAtkBackRate(gameObj), GameObj.GetAtkBackDefRate(gameObj), | 
|                           GameObj.GetSuckHPPer(gameObj), GameObj.GetSuckHPDefPer(gameObj), | 
|                           )) | 
|     GameWorld.DebugLog("    XP=%s/%s,Ç¿ÁÆ=%s,ÈõÁÆ=%s,Ç¿Áé=%s,ÈõÁé=%s,Ç¿±©=%s,Èõ±©=%s"  | 
|                        % (GameObj.GetXP(gameObj), GameObj.GetMaxXP(gameObj), GameObj.GetCurePer(gameObj), GameObj.GetCureDefPer(gameObj),  | 
|                           GameObj.GetPetStrengthenPer(gameObj), GameObj.GetPetWeakenPer(gameObj), | 
|                           GameObj.GetSuperHitHurtPer(gameObj), GameObj.GetSuperHitHurtDefPer(gameObj), | 
|                           )) | 
|     return | 
|   | 
| def TurnFightObjPerTurnStart(gameObj, tagObj, turnNum, tick): | 
|     ## »ØºÏÖÆÕ½¶·ÊµÀý - Ã¿»ØºÏ¿ªÊ¼Ê±´¦Àí | 
|     if not gameObj: | 
|         return | 
|      | 
|     SetTimeline(gameObj, turnNum, 0) | 
|     # ÖØÖÃÁ¬»÷¡¢·´»÷Êý | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, 0) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, 0) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 0) | 
|     gameObj.SetDict(ChConfig.Def_PlayerKey_AttrFaintCD, 0) # »÷ÔÎCD | 
|      | 
|     objType = gameObj.GetGameObjType() | 
|     objID = gameObj.GetID() | 
|     objName = GetObjName(gameObj) | 
|     GameWorld.DebugLog("ObjPerTurnStart: »ØºÏ%s, %s objType-ID-HP(%s-%s-%s)" % (turnNum, objName, objType, objID, GameObj.GetHP(gameObj))) | 
|      | 
|     # Ã¿»ØºÏ¿ªÊ¼¼õ¼¼ÄÜCD | 
|     skillManager = gameObj.GetSkillManager() | 
|     for i in range(skillManager.GetSkillCount()): | 
|         skill = skillManager.GetSkillByIndex(i) | 
|         remainTime = skill.GetRemainTime() | 
|         if not remainTime: | 
|             continue | 
|         skillID = skill.GetSkillID() | 
|         updRemainTime = max(0, remainTime - ChConfig.Def_PerTurnTick) | 
|         skill.SetRemainTime(updRemainTime) | 
|         GameWorld.DebugLog("    skillID=%s,remainTime=%s,updRemainTime=%s" % (skillID, remainTime, updRemainTime)) | 
|          | 
|     # Ë¢Ð¶¨Ê±´¦ÀíµÄbuffЧ¹û | 
|     SkillShell.ProcessPersistBuff(gameObj, tick) | 
|      | 
|     PassiveBuffEffMng.OnPassiveSkillTrigger(gameObj, tagObj, None, ChConfig.TriggerType_TurnNum, tick) | 
|      | 
|     __logGameObjAttr(gameObj) | 
|     return | 
|   | 
| def TurnFightObjPerTurnActionnum(turnNum, actionNum, gameObj, tick): | 
|     ## »ØºÏÖÆÕ½¶·ÊµÀý - Ã¿¸öÐж¯½Úµã´¦Àí | 
|     if not gameObj: | 
|         return | 
|      | 
|     SetTimeline(gameObj, turnNum, actionNum) | 
|      | 
|     objType = gameObj.GetGameObjType() | 
|     if objType == IPY_GameWorld.gotPlayer: | 
|         #Ë¢ÐÂÍæ¼ÒBuffʱ³¤ | 
|         gameObj.SetTickByType(ChConfig.TYPE_Player_Tick_Buff, 0) | 
|         reFlashBuff = PlayerState.ProcessRefreshBuffState(gameObj, tick) | 
|         #SkillShell.ProcessPersistBuff(gameObj, tick) # ¶¨Ê±´¦ÀíµÄÔÚÿ¸öʱ¼ä½ÚµãÓÐÐèÒªÔÙ¿ªÆô£¬Ä¿Ç°Ä¬ÈϻغϿªÊ¼´¦Àí | 
|          | 
|         attrBuffResult, actBuffResult = PlayerState.ProcessRefreshActionBuffState(gameObj, tick) | 
|         playerControl = PlayerControl.PlayerControl(gameObj) | 
|         if actBuffResult: | 
|             playerControl.RefreshPlayerActionState() | 
|              | 
|         #´Ë´¦²ÅÊÇÕæÕýµÄË¢ÐÂÈËÎïÊôÐÔÖµ£¬ÐèË¢ÊôÐÔÂß¼Ó¦ÔÚ´ËÐÐǰµ÷Óà | 
|         if not playerControl.RefreshPlayerAttrStateEx(): | 
|             if reFlashBuff or attrBuffResult: | 
|                 playerControl.RefreshPlayerAttrByBuff() | 
|             # Ö»Ë¢BUFFÇé¿ö | 
|             playerControl.RefreshPlayerAttrByBuffEx()  | 
|              | 
|     elif objType == IPY_GameWorld.gotNPC: | 
|         gameObj.SetTickByType(ChConfig.TYPE_NPC_Tick_Buff, 0) | 
|         gameObj.SetTickByType(ChConfig.TYPE_NPC_Tick_Buff_Timely, 0) | 
|          | 
|         npcControl = NPCCommon.NPCControl(gameObj) | 
|         npcControl.RefreshBuffState(tick) | 
|          | 
|     return | 
|   | 
| def TurnFightObjOverReset(gameObj, tick): | 
|     ## »ØºÏÖÆÕ½¶·ÊµÀý½áÊøÖØÖà | 
|     if not gameObj: | 
|         return | 
|      | 
|     objType = gameObj.GetGameObjType() | 
|      | 
|     #NPCÖ±½Ó»ØÊÕ | 
|     if objType == IPY_GameWorld.gotNPC: | 
|         RecycleObj(gameObj) | 
|         return | 
|      | 
|     if objType != IPY_GameWorld.gotPlayer: | 
|         return | 
|      | 
|     timeline = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline) | 
|     isDelRefresh = ClearTurnFightBuff(gameObj, timeline, tick) | 
|     SetTimeline(gameObj, 0, 0) | 
|     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) | 
|     GameObj.SetFaction(gameObj, 0) | 
|     GameObj.SetHPFull(gameObj) | 
|     if isDelRefresh: | 
|         playerControl = PlayerControl.PlayerControl(gameObj) | 
|         playerControl.RefreshPlayerAttrByBuff() | 
|     return | 
|   | 
| def ClearTurnFightBuff(gameObj, timeLine, tick): | 
|     ## Çå³ý»ØºÏÖÆÕ½¶·Ïà¹Øbuff | 
|     isDelRefresh = False | 
|     objType = gameObj.GetGameObjType() | 
|     objID = gameObj.GetID() | 
|     for buffType in range(IPY_GameWorld.bfBuff, IPY_GameWorld.btBufMax): | 
|         if objType != IPY_GameWorld.gotPlayer and buffType in ChConfig.Def_BuffType_OnlyPlayer: | 
|             continue | 
|         buffTuple = SkillCommon.GetBuffManagerByBuffType(gameObj, buffType) | 
|         if buffTuple == (): | 
|             continue | 
|         buffState = buffTuple[0] | 
|         for i in range(0, buffState.GetBuffCount())[::-1]: | 
|             curBuff = buffState.GetBuff(i) | 
|             curSkill = curBuff.GetSkill() | 
|             buffSkillID = curSkill.GetSkillID() | 
|             if not buffSkillID: | 
|                 continue | 
|             if curBuff.GetCalcStartTick() > timeLine: | 
|                 # »ØºÏÖÆÖвúÉúµÄbuffÊÇÒÔtimeline×÷ΪCalcStartTickµÄ£¬ËùÒÔ³¬¹ýtimelineµÄ¿ÉÊÓΪ·Ç»ØºÏÖÆbuff | 
|                 continue | 
|             GameWorld.DebugLog("    É¾³ý»ØºÏÖÆbuff: objID=%s,buffSkillID=%s" % (objID, buffSkillID)) | 
|             ownerID, ownerType = curBuff.GetOwnerID(), curBuff.GetOwnerType() | 
|             BuffSkill.DoBuffDisApper(gameObj, curBuff, tick) | 
|             buffState.DeleteBuffByIndex(i) | 
|             SkillShell.ClearBuffEffectBySkillID(gameObj, buffSkillID, ownerID, ownerType) | 
|             #ɾ³ýδ֪BUFF£¬Ë¢ÐÂÊôÐÔ | 
|             isDelRefresh = True | 
|     return isDelRefresh | 
|   | 
| def RecycleObj(gameObj): | 
|     ## ÊͷŻغÏÖÆÕ½¶·¶ÔÏó | 
|      | 
|     #Áé³è¸úÕÙ»½ÊÞÓÉÖ÷ÈË»ØÊÕʱ´¥·¢»ØÊÕ£¬²»È»»áµ¼Ö±¨´í | 
|     npcObjType = gameObj.GetGameNPCObjType() | 
|     if npcObjType == IPY_GameWorld.gnotPet: | 
|         #GameWorld.DebugLog("RecycleObj Áé³è²»»ØÊÕ objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID())) | 
|         return | 
|     if npcObjType == IPY_GameWorld.gnotSummon: | 
|         curOwner = NPCCommon.GetSummonOwnerDetel(gameObj) | 
|         if curOwner and curOwner.GetGameObjType() == IPY_GameWorld.gotNPC: | 
|             #GameWorld.DebugLog("RecycleObj ÕÙ»½ÊÞÖ÷ÈËÊÇNPC²»»ØÊÕ objID=%s,npcObjType=%s,%s,ownerID=%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID(), curOwner.GetID())) | 
|             return | 
|          | 
|     #GameWorld.DebugLog("RecycleObj: objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID())) | 
|     NPCCommon.SetDeadEx(gameObj) | 
|     return | 
|   | 
| def AddTurnObjHurtValue(curObj, tagObj, hurtType, hurtValue, lostHP, curSkill=None): | 
|     if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline): | 
|         return | 
|     tfBattle = GetTurnFightBattle() | 
|     curID = curObj.GetID() | 
|     tagID = tagObj.GetID() | 
|     skillID = curSkill.GetSkillID() if curSkill else 0 | 
|     if curID != tagID: | 
|         totalHurt = tfBattle.AddObjHurtValue(curObj, hurtValue) | 
|         GameWorld.DebugLog("        ÉËѪ: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,totalHurt=%s,lostHP=%s,tagHP=%s"  | 
|                            % (curID, tagID, skillID, hurtType, hurtValue, totalHurt, lostHP, GameObj.GetHP(tagObj))) | 
|     else: | 
|         # È绻ѪÀ༼ÄÜ£¬×ԲеÄÉ˺¦²»ËãÊä³ö | 
|         GameWorld.DebugLog("        ×Ô²Ð: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,totalHurt=%s,lostHP=%s,curHP=%s"  | 
|                            % (curID, tagID, skillID, hurtType, hurtValue, totalHurt, lostHP, GameObj.GetHP(curObj)))         | 
|      | 
|     if lostHP and curID != tagID: | 
|         AddTurnFightXP(tagObj, __GetAddXP_Defender(tagObj, lostHP), "skillID:%s" % skillID) | 
|         AddTurnFightXP(curObj, __GetAddXP_Attack(curObj, curSkill), "skillID:%s" % skillID) | 
|     return | 
|   | 
| def __GetAddXP_Attack(attack, curSkill): | 
|     ## ¹¥»÷·½Ôö¼ÓµÄXPÖµ¸ù¾ÝÖ÷¶¯¹¥»÷´ÎÊý»ñµÃ | 
|     isAddXPSkill = not curSkill or curSkill.GetSkillType() == ChConfig.Def_SkillType_Atk | 
|     if not isAddXPSkill: | 
|         return 0 | 
|     atkAddXPCount = attack.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount) | 
|     addXPList = IpyGameDataPY.GetFuncEvalCfg("TurnFightXP", 2) | 
|     if atkAddXPCount >= len(addXPList): | 
|         return 0 | 
|     attack.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, atkAddXPCount + 1) | 
|     return addXPList[atkAddXPCount] | 
|   | 
| def __GetAddXP_Defender(defender, lostHP): | 
|     ## µôѪ·½Ôö¼ÓµÄXPÖµ¸ù¾ÝµôѪ°Ù·Ö±È»ñµÃ | 
|     maxXP = GameObj.GetMaxXP(defender) | 
|     if not maxXP: | 
|         return 0 | 
|     maxHP = GameObj.GetMaxHP(defender) | 
|     lostHPPer = lostHP / float(maxHP) | 
|     #GameWorld.DebugLog("        lostHP=%s,lostHPPer=%s" % (lostHP, lostHPPer)) | 
|     return eval(IpyGameDataPY.GetFuncCompileCfg("TurnFightXP", 3)) | 
|   | 
| def AddTurnFightXP(gameObj, addXP, reason=""): | 
|     ## »ØºÏÕ½¶·Ôö¼ÓXP | 
|     if not addXP: | 
|         #GameWorld.DebugLog("        Ã»ÓÐÔö¼ÓXP! curID=%s" % (gameObj.GetID())) | 
|         return | 
|     maxXP = GameObj.GetMaxXP(gameObj) | 
|     if not maxXP: | 
|         #GameWorld.DebugLog("        ÎÞ×î´óXPÖµ£¬²»¸üÐÂ! curID=%s" % (gameObj.GetID())) | 
|         return | 
|     curXP = GameObj.GetXP(gameObj) | 
|     if curXP >= maxXP: | 
|         #GameWorld.DebugLog("        XPÖµÒÑÂú£¬²»¸üÐÂ! curID=%s,curXP=%s" % (gameObj.GetID(), curXP)) | 
|         return | 
|     updXP = min(curXP + addXP, maxXP) | 
|     GameObj.SetXP(gameObj, updXP) | 
|     GameWorld.DebugLog("        ¸üÐÂXP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason)) | 
|     return | 
|   | 
| def __CheckUseXPSkill(curObj, tagObj, tick): | 
|     ## Ê¹ÓÃXP¼¼ÄÜ - µÀ·¨¼¼ÄÜ | 
|     maxXP = GameObj.GetMaxXP(curObj) | 
|     curXP = GameObj.GetXP(curObj) | 
|     if not maxXP or curXP < maxXP: | 
|         #GameWorld.DebugLog("        Ã»ÓÐXP»òXPδÂú£¬ÎÞ·¨ÊÍ·ÅXP! curID=%s,curXP=%s" % (curObj.GetID(), curXP)) | 
|         return | 
|     turnNum = GetTurnNum(curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)) | 
|     xpFullTurnNum = GetTurnNum(curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnXPFullTimeline)) | 
|     if turnNum <= xpFullTurnNum: | 
|         #GameWorld.DebugLog("        XP¼¼ÄÜÔÚ±¾»ØºÏÎÞ·¨ÊÍ·Å! curID=%s, turnNum=%s <= %s" % (curObj.GetID(), turnNum, xpFullTurnNum)) | 
|         return | 
|      | 
|     curObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 1) # ÉèÖÿÉÓà | 
|      | 
|     tagDist = 0 | 
|     skillManager = curObj.GetSkillManager() | 
|     for index in range(0, skillManager.GetSkillCount()): | 
|         curSkill = skillManager.GetSkillByIndex(index) | 
|         if not curSkill or curSkill.GetSkillTypeID() == 0: | 
|             break | 
|         skillID = curSkill.GetSkillID() | 
|         #±»¶¯¼¼ÄÜÎÞ·¨Ê¹Óà | 
|         if SkillCommon.isPassiveSkill(curSkill): | 
|             continue | 
|         #»¹ÔÚÀäȴʱ¼äÄÚÎÞ·¨ÊÍ·Å | 
|         if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0: | 
|             continue | 
|         needXP = curSkill.GetXP() | 
|         if not needXP or needXP < curXP: | 
|             continue | 
|         curID = curObj.GetID() | 
|         tagID = tagObj.GetID() | 
|         if not AICommon.DoNPCUseSkill(curObj, tagObj, curSkill, tagDist, tick): | 
|             GameWorld.DebugLog("        XP¼¼Äܹ¥»÷ʧ°Ü: curID=%s,tagID=%s,skillID=%s" % (curID, tagID, skillID)) | 
|             continue | 
|         GameWorld.DebugLog("        XP¼¼Äܹ¥»÷³É¹¦: curID=%s,tagID=%s,skillID=%s" % (curID, tagID, skillID)) | 
|         curObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 2) # ÉèÖÃÒÑÓÃ | 
|         return skillID | 
|      | 
|     return | 
|   | 
| def DoAttack(curObj, tagObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal, checkUseXP=False): | 
|     curID = curObj.GetID() | 
|     tagID = tagObj.GetID() | 
|     objName = GetObjName(curObj) | 
|     GameWorld.DebugLog("    ¡ñ %s DoAttack: curID=%s,tagID=%s,turnBattleType=%s" % (objName, curID, tagID, turnBattleType)) | 
|     if checkUseXP: | 
|         if __CheckUseXPSkill(curObj, tagObj, tick): | 
|             return True | 
|          | 
|     if turnBattleType == ChConfig.TurnBattleType_AtkBack: | 
|         PassiveBuffEffMng.OnPassiveSkillTrigger(curObj, tagObj, None, ChConfig.TriggerType_AtkBackBef, tick) | 
|          | 
|     curObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType) | 
|     if curObj.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|         atkOK = PlayerAttack(curObj, tagObj, tick) | 
|     elif curObj.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID): | 
|         atkOK = PlayerMirrorAttack(curObj, tagObj, tick) | 
|     else: | 
|         atkOK = NPCAttack(curObj, tagObj, tick) | 
|     curObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # ÎÞÂÛ¹¥»÷³É¹¦Óë·ñ¶¼ÖØÖÃÕ½¶·ÀàÐÍ | 
|      | 
|     if not atkOK: | 
|         return | 
|      | 
|     curHP = GameObj.GetHP(curObj) | 
|     tagHP = GameObj.GetHP(tagObj) | 
|     GameWorld.DebugLog("            curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP)) | 
|     if tagHP <= 0 or curHP <= 0: | 
|         return True | 
|      | 
|     # ·´»÷£¬·´»÷¿É´ò¶ÏÁ¬»÷£¬ËùÒÔÓÅÏÈÅÐ¶Ï | 
|     if CanAtkBack(curObj, tagObj): | 
|         DoAttack(tagObj, curObj, tick, ChConfig.TurnBattleType_AtkBack) | 
|         return True | 
|      | 
|     # Á¬»÷ | 
|     if CanCombo(curObj, tagObj): | 
|         DoAttack(curObj, tagObj, tick, ChConfig.TurnBattleType_Combo) | 
|          | 
|     return True | 
|   | 
| def CanAtkBack(atkObj, defObj): | 
|     ## ¿É·ñ·´»÷ | 
|     if atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) > 0: | 
|         #GameWorld.DebugLog("            ±»Áé³è¹¥»÷ʱÎÞ·¨´¥·¢·´»÷") | 
|         return False | 
|     defAtkBackRate = GameObj.GetAtkBackRate(defObj) # ·À·½·´»÷ÂÊ | 
|     atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # ÒÑ·´»÷´ÎÊý | 
|     if atkBackNum > 10: | 
|         # ÄÚÖÃ×î¸ß·´»÷Êý·À·¶ | 
|         return False | 
|     if atkBackNum > 0: | 
|         validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 4) | 
|         vaildPer = validPerList[atkBackNum - 1] if len(validPerList) >= atkBackNum else 0 | 
|         defAtkBackRate = int(defAtkBackRate * vaildPer / 100.0) | 
|          | 
|     atkAtkBackDefRate = GameObj.GetAtkBackDefRate(atkObj) # ¹¥·½µÖ¿¹·´»÷ÂÊ | 
|     atkBackRate = max(0, defAtkBackRate - atkAtkBackDefRate) | 
|     if atkBackRate <= 0 or not GameWorld.CanHappen(atkBackRate): | 
|         GameWorld.DebugLog("            ÎÞ·¨·´»÷: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)"  | 
|                            % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate)) | 
|         return False | 
|     GameWorld.DebugLog("            ¿ÉÒÔ·´»÷: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)"  | 
|                        % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate)) | 
|     return True | 
|   | 
| def CanCombo(atkObj, defObj): | 
|     ## ¿É·ñÁ¬»÷ | 
|      | 
|     atkComboRate = GameObj.GetComboRate(atkObj) # ¹¥·½Á¬»÷ÂÊ | 
|     comboNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum) # ÒÑÁ¬»÷´ÎÊý | 
|     if comboNum > 10: | 
|         # ÄÚÖÃ×î¸ßÁ¬»÷Êý·À·¶ | 
|         return False | 
|     if comboNum > 0: | 
|         validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 3) | 
|         vaildPer = validPerList[comboNum - 1] if len(validPerList) >= comboNum else 0 | 
|         atkComboRate = int(atkComboRate * vaildPer / 100.0) | 
|          | 
|     defComboReduce = GameObj.GetComboDefRate(defObj) # ·À·½µÖ¿¹Á¬»÷ÂÊ | 
|     comboRate = max(0, atkComboRate - defComboReduce) | 
|     if comboRate <= 0 or not GameWorld.CanHappen(comboRate): | 
|         GameWorld.DebugLog("            ÎÞ·¨Á¬»÷: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)"  | 
|                            % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce)) | 
|         return False | 
|     GameWorld.DebugLog("            ¿ÉÒÔÁ¬»÷: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)"  | 
|                        % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce)) | 
|     return True | 
|   | 
| def NPCAttack(curObj, tagObj, tick): | 
|     ## NPC¹¥»÷ | 
|     if not curObj: | 
|         return | 
|      | 
|     #ÓÐÖµ´ú±íÁé³èÉÏÕóλÖã¬ÅжÏÊÇ·ñÓиÅÂʹ¥»÷ | 
|     fightPlaceNum = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum) | 
|     if fightPlaceNum > 0: | 
|         fightRateList = IpyGameDataPY.GetFuncEvalCfg("PetGoOutFight", 2) | 
|         if fightPlaceNum > len(fightRateList): | 
|             return | 
|         fightRatePer = fightRateList[fightPlaceNum - 1] | 
|          | 
|         qualityAddRateInfo = IpyGameDataPY.GetFuncEvalCfg("PetGoOutFight", 3, {}) | 
|         petQuality = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetQuality) | 
|         qualityAddPer = qualityAddRateInfo.get(str(petQuality), 0) | 
|         fightRatePer += qualityAddPer | 
|         if fightRatePer < 100 and not GameWorld.CanHappen(fightRatePer, 100): | 
|             GameWorld.DebugLog("        Áé³è¸ÅÂʲ»¹¥»÷: curID=%s,fightPlaceNum=%s,petQuality=%s,fightRatePer=%s"  | 
|                                % (curObj.GetID(), fightPlaceNum, petQuality, fightRatePer)) | 
|             return | 
|          | 
|     tagDist = 0 | 
|     atkOK = AICommon.DoAutoUseSkill(curObj, tagObj, tagDist, tick) | 
|     #---ÓÅÏÈÊͷż¼ÄÜ--- | 
|     if not atkOK: | 
|         if fightPlaceNum: | 
|             GameWorld.DebugLog("        Áé³è²»¿ÉÆÕͨ¹¥»÷: curID=%s,fightPlaceNum=%s" % (curObj.GetID(), fightPlaceNum)) | 
|         else: | 
|             #ÆÕͨ¹¥»÷ | 
|             atkOK = BaseAttack.Attack(curObj, tagObj, None, tick) | 
|             if atkOK: | 
|                 GameWorld.DebugLog("        ÆÕͨ¹¥»÷: curID=%s,tagID=%s,atkOK=%s" % (curObj.GetID(), tagObj.GetID(), atkOK)) | 
|             else: | 
|                 GameWorld.DebugLog("        ¹¥»÷ʧ°Ü: curID=%s,tagID=%s,atkOK=%s" % (curObj.GetID(), tagObj.GetID(), atkOK)) | 
|     else: | 
|         GameWorld.DebugLog("        ¼¼Äܹ¥»÷: curID=%s,tagID=%s,atkOK=%s" % (curObj.GetID(), tagObj.GetID(), atkOK)) | 
|     return atkOK | 
|   | 
| def PlayerMirrorAttack(playerNPC, tagObj, tick): | 
|     ## Íæ¼Ò¾µÏñ¹¥»÷ | 
|      | 
|     playerID = playerNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MirrorPlayerID) | 
|     tagObjID = tagObj.GetID() | 
|      | 
|     autoUseSkillTypeIDList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 2, {}) | 
|      | 
|     tagDist = 0 | 
|     skillManager = playerNPC.GetSkillManager() | 
|     for skillTypeID in autoUseSkillTypeIDList: | 
|         curSkill = skillManager.FindSkillBySkillTypeID(skillTypeID) | 
|         if not curSkill: | 
|             continue | 
|         skillID = curSkill.GetSkillID() | 
|          | 
|         #±»¶¯¼¼ÄÜÎÞ·¨Ê¹Óà | 
|         if SkillCommon.isPassiveSkill(curSkill): | 
|             continue | 
|         #»¹ÔÚÀäȴʱ¼äÄÚÎÞ·¨ÊÍ·Å | 
|         if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0: | 
|             continue | 
|          | 
|         if not AICommon.DoNPCUseSkill(playerNPC, tagObj, curSkill, tagDist, tick): | 
|             continue | 
|         GameWorld.DebugLog("        ¼¼Äܹ¥»÷³É¹¦: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) | 
|         return skillID | 
|      | 
|     #ÆÕͨ¹¥»÷ | 
|     atkOK = BaseAttack.Attack(playerNPC, tagObj, None, tick) | 
|     if atkOK: | 
|         GameWorld.DebugLog("        ÆÕͨ¹¥»÷: curID=%s,tagID=%s,atkOK=%s" % (playerID, tagObjID, atkOK)) | 
|     else: | 
|         GameWorld.DebugLog("        ¹¥»÷ʧ°Ü: curID=%s,tagID=%s,atkOK=%s" % (playerID, tagObjID, atkOK)) | 
|          | 
|     return atkOK | 
|   | 
| def PlayerAttack(curPlayer, tagObj, tick): | 
|     ## Íæ¼Ò¹¥»÷£¬ ²Î¿¼¼¼ÄÜʹÓà#def UseSkillEx(index, clientData, tick): | 
|     playerID = curPlayer.GetPlayerID() | 
|     autoUseSkillTypeIDList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 2, {}) | 
|      | 
|     posX, posY = tagPosX, tagPosY = curPlayer.GetPosX(), curPlayer.GetPosY() | 
|     tagObjType, tagObjID = tagObj.GetGameObjType(), tagObj.GetID() | 
|      | 
|     curPlayer.ClearUseSkillRec() | 
|     curPlayer.SetAttackTargetPos(posX, posY) | 
|     curPlayer.SetUseSkillPosX(tagPosX) | 
|     curPlayer.SetUseSkillPosY(tagPosY) | 
|     curPlayer.SetUseSkillTagType(tagObjType) | 
|     curPlayer.SetUseSkillTagID(tagObjID) | 
|      | 
|     #PlayerControl.SetIsNeedProcess(curPlayer, True) | 
|     #PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paAttack) | 
|      | 
|     useSkillResult = False | 
|     skillMgr = curPlayer.GetSkillManager() | 
|     for skillTypeID in autoUseSkillTypeIDList: | 
|         curSkill = skillMgr.FindSkillBySkillTypeID(skillTypeID) | 
|         if not curSkill: | 
|             continue | 
|         skillID = curSkill.GetSkillID() | 
|          | 
|         #CheckSkillCondition | 
|         #±»¶¯¼¼ÄÜÎÞ·¨Ê¹Óà | 
|         if SkillCommon.isPassiveSkill(curSkill): | 
|             continue | 
|         #»¹ÔÚÀäȴʱ¼äÄÚÎÞ·¨ÊÍ·Å | 
|         if SkillCommon.RefreshSkillRemainTime(curSkill, tick) != 0: | 
|             continue | 
|          | 
|         curPlayer.SetUseSkill(curSkill.GetSkillData()) | 
|         useSkillData = curPlayer.GetUseSkill() | 
|         if not PlayerState.__DoClientUseSkillEx(curPlayer, useSkillData, tick): | 
|             GameWorld.DebugLog("        ¼¼Äܹ¥»÷ʧ°Ü: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) | 
|             continue | 
|         useSkillResult = True | 
|         GameWorld.DebugLog("        ¼¼Äܹ¥»÷³É¹¦: playerID=%s,tagID=%s,skillID=%s" % (playerID, tagObjID, skillID)) | 
|          | 
|         break | 
|      | 
|     curPlayer.ClearUseSkillRec() | 
|      | 
|     if not useSkillResult: | 
|         #ÆÕͨ¹¥»÷ | 
|         atkOK = BaseAttack.Attack(curPlayer, tagObj, None, tick) | 
|         if atkOK: | 
|             useSkillResult = True | 
|             GameWorld.DebugLog("        ÆÕͨ¹¥»÷: curID=%s,tagID=%s,atkOK=%s" % (playerID, tagObjID, atkOK)) | 
|         else: | 
|             GameWorld.DebugLog("        ¹¥»÷ʧ°Ü: curID=%s,tagID=%s,atkOK=%s" % (playerID, tagObjID, atkOK)) | 
|     return useSkillResult | 
|   | 
| def SyncTurnFightState(curPlayer, mapID, funcLineID, tagType, tagID, state, turnNum=0, turnMax=0, msg=""): | 
|     if not curPlayer: | 
|         return | 
|     clientPack = ChPyNetSendPack.tagMCTurnFightState() | 
|     clientPack.Clear() | 
|     clientPack.MapID = mapID | 
|     clientPack.FuncLineID = funcLineID | 
|     clientPack.TagType = tagType | 
|     clientPack.TagID = tagID | 
|     clientPack.State = state | 
|     clientPack.TurnNum = turnNum | 
|     clientPack.TurnMax = turnMax | 
|     clientPack.Msg = str(msg) | 
|     clientPack.Len = len(clientPack.Msg)     | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack) | 
|     return | 
|   | 
| def SyncTurnFightObjAction(curPlayer, turnNum, objType, objID): | 
|     if not curPlayer: | 
|         return | 
|     clientPack = ChPyNetSendPack.tagMCTurnFightObjAction() | 
|     clientPack.Clear() | 
|     clientPack.TurnNum = turnNum | 
|     clientPack.ObjID = objID | 
|     clientPack.ObjType = objType | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack) | 
|     return |