| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package NPCRealmRefresh  | 
| #  | 
| # @todo:¾³½çNPCË¢¹Ö  | 
| # @author hxp  | 
| # @date 2022-08-23  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: tagNPCRefresh.txt py¶ÁÈ¡¸Ã±íË¢¹Ö¹æÔò  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2022-08-23 19:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import PyGameData  | 
| import IpyGameDataPY  | 
| import PlayerControl  | 
| import NPCCommon  | 
| import ChConfig  | 
|   | 
| import os  | 
|   | 
| class IPY_ChRefreshPos():  | 
|       | 
|     def __init__(self):  | 
|         self.posX = 0  | 
|         self.posY = 0  | 
|         self.area = 0  | 
|         self.moveDist = 0  | 
|         return  | 
|       | 
|     def GetRandPosX(self): return self.posX  | 
|     def GetRandPosY(self): return self.posY  | 
|     def GetPosX(self): return self.posX  | 
|     def GetPosY(self): return self.posY  | 
|     def GetArea(self): return self.area  | 
|     def GetMoveDist(self): return self.moveDist  | 
|       | 
| class tagNPCRefresh():  | 
|       | 
|     def __init__(self, RefreshID):  | 
|         self.RefreshID = RefreshID  | 
|         self.NPCID = 0  | 
|         self.RefreshPoint = IPY_ChRefreshPos()  | 
|         self.RefreshTotal = 0  | 
|         self.RefreshCount = 0  | 
|         self.RefreshTime = 0  | 
|         self.RebornState = 0 # ÊÇ·ñ¸´»î״̬  | 
|         self.DeadTick = 0 # ÉÏ´ÎËÀÍötick  | 
|         return  | 
|       | 
|     def GetRefreshID(self): return self.RefreshID  | 
|     def GetNPCID(self): return self.NPCID  | 
|     def GetRefreshPoint(self): return self.RefreshPoint  | 
|     def GetRefreshTotal(self): return self.RefreshTotal  | 
|     def GetRefreshCount(self): return self.RefreshCount  | 
|     def GetRefreshTime(self): return self.RefreshTime  | 
|     def GetRebornState(self): return self.RebornState  | 
|     def GetDeadTick(self): return self.DeadTick  | 
|     def SetReborn(self):  | 
|         self.RebornState = 1  | 
|         return  | 
|     def SetDead(self, tick):  | 
|         self.RebornState = 0  | 
|         self.DeadTick = tick  | 
|         return  | 
|       | 
| def GetTagNPCRefresh(curNPC):  | 
|     realmDiff = curNPC.GetSightLevel()  | 
|     refreshID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonRefreshID)  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     key = (lineID, realmDiff)  | 
|       | 
|     obj = None  | 
|     if key in PyGameData.g_realmDiffNPCRefresh:  | 
|         mapNPCRefresh = PyGameData.g_realmDiffNPCRefresh[key]  | 
|         if refreshID in mapNPCRefresh:  | 
|             obj = mapNPCRefresh[refreshID]  | 
|     else:  | 
|         if False:  | 
|             obj = tagNPCRefresh(refreshID) # ÕâÁ½ÐдúÂëÎÞÓã¬Ö»ÊÇΪÁË·½±ã . ³ö´úÂëÌáʾ  | 
|               | 
|     return obj  | 
|   | 
| def GetMapRealmNPCRefresh(realm):  | 
|     ''' ¼ÓÔØ±¾µØÍ¼  tagNPCRefresh.txt Ë¢¹Ö¹æÔò  | 
|     '''  | 
|       | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     key = (lineID, realm)  | 
|       | 
|     if key in PyGameData.g_realmDiffNPCRefresh:  | 
|         return PyGameData.g_realmDiffNPCRefresh[key]  | 
|       | 
|     filePath = os.path.join(ChConfig.GetDBPath(), "SysDB", "tagNPCRefresh.txt")  | 
|     if not os.path.isfile(filePath):  | 
|         GameWorld.ErrLog("can not find file = %s" % filePath)  | 
|         raise Exception("can not find file = %s" % filePath)  | 
|           | 
|     mapNPCRefresh = {}  | 
|     curMapID = GameWorld.GetMap().GetMapID()  | 
|     fileObj = open(filePath, 'rb')  | 
|     content = fileObj.read()  | 
|     fileObj.close()  | 
|     infoList = content.split('\r\n')  | 
|     for line in xrange(len(infoList)):  | 
|         if line == 0:  | 
|             continue  | 
|         if not infoList[line]:  | 
|             continue  | 
|         rowList = infoList[line].split('\t')  | 
|         if len(rowList) != 17:  | 
|             continue  | 
|         try:  | 
|             MapID = int(rowList[2])  | 
|             if curMapID != MapID:  | 
|                 continue  | 
|             RefreshID = int(rowList[0])  | 
|             NPCID = int(rowList[1])  | 
|             if not NPCID:  | 
|                 continue  | 
|             RefreshPos = eval(rowList[4])  | 
|             RefreshTotal = int(rowList[5])  | 
|             RefreshCount = int(rowList[6])  | 
|             RefreshTime = int(rowList[8])  | 
|             if not (type(RefreshPos) in [list, tuple] and len(RefreshPos) == 4 and isinstance(RefreshPos[0], int)):  | 
|                 GameWorld.ErrLog("tagNPCRefresh.txt line(%s) not processed." % (line + 1))  | 
|                 continue  | 
|             refreshObj = tagNPCRefresh(RefreshID)  | 
|             refreshObj.NPCID = NPCID  | 
|             refreshObj.RefreshPoint.posX = RefreshPos[0]  | 
|             refreshObj.RefreshPoint.posY = RefreshPos[1]  | 
|             refreshObj.RefreshPoint.area = RefreshPos[2]  | 
|             refreshObj.RefreshPoint.moveDist = RefreshPos[3]  | 
|             refreshObj.RefreshTotal = RefreshTotal  | 
|             refreshObj.RefreshCount = RefreshCount  | 
|             refreshObj.RefreshTime = RefreshTime  | 
|             mapNPCRefresh[RefreshID] = refreshObj  | 
|         except:  | 
|             GameWorld.ErrLog("tagNPCRefresh.txt line(%s) error." % (line + 1))  | 
|             continue  | 
|           | 
|     PyGameData.g_realmDiffNPCRefresh[key] = mapNPCRefresh  | 
|     GameWorld.Log("LoadMapRealmNPCRefresh mapID=%s,lineID=%s,realm=%s,refreshIDList=%s" % (curMapID, lineID, realm, mapNPCRefresh.keys()))  | 
|     return mapNPCRefresh  | 
|   | 
| def ProcessRealmNPCRefresh(gameWorld, tick):  | 
|     mapID = gameWorld.GetMapID()  | 
|     mapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)  | 
|     if mapID not in mapIDList:  | 
|         return  | 
|       | 
|     playerDict = {}  | 
|     copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()  | 
|     for realmDiff, playerIDList in PyGameData.g_realmDiffPlayerDict.items():  | 
|         if not playerIDList:  | 
|             continue  | 
|           | 
|         mapNPCRefresh = GetMapRealmNPCRefresh(realmDiff)  | 
|         if not mapNPCRefresh:  | 
|             continue  | 
|           | 
|         for refreshID, refreshObj in mapNPCRefresh.items():  | 
|             if not refreshObj:  | 
|                 continue  | 
|             if refreshObj.GetRebornState():  | 
|                 continue  | 
|               | 
|             DeadTick = refreshObj.GetDeadTick()  | 
|             RefreshTime = refreshObj.GetRefreshTime()  | 
|             if DeadTick and RefreshTime:  | 
|                 if (tick - DeadTick) < RefreshTime:  | 
|                     continue  | 
|                   | 
|             NPCID = refreshObj.GetNPCID()  | 
|             npcData = GameWorld.GetGameData().FindNPCDataByID(NPCID)  | 
|             if not npcData:  | 
|                 continue  | 
|               | 
|             refreshPoint = refreshObj.GetRefreshPoint()  | 
|             posX, posY = refreshPoint.GetPosX(), refreshPoint.GetPosY()  | 
|             canRefresh = False  | 
|             # ÅжÏÍæ¼ÒÊÇ·ñ¿ÉÊÓ  | 
|             for playerID in playerIDList:  | 
|                 if playerID in playerDict:  | 
|                     player = playerDict[playerID]  | 
|                 else:  | 
|                     player = copyPlayerMgr.FindPlayerByID(playerID)                    | 
|                 if not player:  | 
|                     continue  | 
|                 playerDict[playerID] = player  | 
|                 playerRealm = PlayerControl.GetRealmDifficulty(player)  | 
|                 if playerRealm != realmDiff:  | 
|                     continue  | 
|                 sight = player.GetSight()  | 
|                 playerPosX, playerPosY = player.GetPosX(), player.GetPosY()  | 
|                 if GameWorld.GetDist(posX, posY, playerPosX, playerPosY) <= sight:  | 
|                     canRefresh = True  | 
|                     break  | 
|                   | 
|             if not canRefresh:  | 
|                 continue  | 
|               | 
|             if NPCCommon.SummonMapNpc(NPCID, posX, posY, npcData.GetAIType(), sightLevel=realmDiff, refreshID=refreshID):  | 
|                 refreshObj.SetReborn()  | 
|                 #GameWorld.DebugLog("ProcessNPCRefresh realmDiff=%s,NPCID=%s,posX=%s,posY=%s" % (realmDiff, NPCID, posX, posY), refreshID)  | 
|                 continue  | 
|               | 
|     return  | 
|   | 
|       |