| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #---------------------------------------------------------------------  | 
| #  | 
| #---------------------------------------------------------------------  | 
| ##@package AIType_196  | 
| # @todo: µÁ±¦¸ç²¼ÁÖAI  | 
| #  | 
| # @author: hxp  | 
| # @date 2013-11-05  | 
| # @version 1.9  | 
| #  | 
| # @note:   | 
| # @change: "2013-11-08 18:00" hxp ÐÞ¸ÄÂß¼  | 
| # @change: "2013-11-12 14:50" hxp µôÂ侨Õó¸ÄΪ°´µôÂä¸öÊýµôÂä  | 
| # @change: "2013-12-27 12:40" hxp Ôö¼ÓµØ¾«¶á±¦µØÍ¼²»¹ã²¥   | 
| # @change: "2014-01-17 11:00" hxp Ð޸IJ»µôÂäÎïÆ·ÓÉNPCÊÇ·ñµôÂä¾ö¶¨£¬Ôö¼ÓÖ¸¶¨¿ÉµôÂäÅäÖà  | 
| # @change: "2015-03-05 11:30" hxp ÐÞ¸´¿ÉÄÜ»áÍ£ÔÚÎÞ·¨¹¥»÷ÇøÓòµÄÎÊÌâ  | 
| # @change: "2015-03-30 19:30" hxp Ôö¼Ó»÷ɱÁ÷Ïò; »÷ɱ¹ã²¥¿ÉÅäÖÃÌØÊâNPCID¶ÔÓ¦¹ã²¥  | 
| # @change: "2015-04-21 16:00" hxp ¼ì²é¾ÀÕý¸ç²¼ÁÖλÖÃ(·ÀÖ¹´¦ÓÚ°²È«Çø»òÕϰµã)  | 
| # @change: "2015-04-22 11:20" xmnathan NPCËÀÍöʱ·À·¶È¡µ½NPCIDΪ0µÄÇé¿ö  | 
| # @change: "2015-07-13 11:30" ljd ·ÇÒ»ÏßÒþ²Ø¸ç²¼ÁÖ  | 
| #---------------------------------------------------------------------  | 
| """Version = 2015-07-13 11:30"""  | 
| #---------------------------------------------------------------------  | 
| import IPY_GameWorld  | 
| import GameWorld  | 
| import NPCCommon  | 
| import ChConfig  | 
| import ReadChConfig  | 
| import PetControl  | 
| import GameMap  | 
| import DataRecordPack  | 
| import PlayerControl  | 
|   | 
| import random  | 
| #---------------------------------------------------------------------  | 
| #---SetDict NPC×ÖµäKEY£¬²»´æÓÚÊý¾Ý¿â---  | 
| Def_NPCKey_Goblin_AttackedTick = 'Goblin_AttackedTick'  # ¸ç²¼ÁÖ±»¹¥»÷ʱ¼ä  | 
| Def_NPCKey_Goblin_MoveDir = 'Goblin_MoveDir'  # ¸ç²¼ÁÖÒÆ¶¯·½Ïò  | 
|   | 
| (  | 
| Def_DropItemType_Money, # µôÂäÎïÆ·ÀàÐÍ - ½ðÇ®  | 
| Def_DropItemType_Goods, # µôÂäÎïÆ·ÀàÐÍ - µÀ¾ß  | 
| Def_DropItemType_Equip, # µôÂäÎïÆ·ÀàÐÍ - ×°±¸  | 
| ) = range(3)  | 
|   | 
| (  | 
| Def_StopTime, # ¶à³¤Ê±¼äδ±»¹¥»÷Ôò½øÈë´ôÖÍ״̬£¬ºÁÃë  | 
| Def_AttackedDropItemCountRate, # Ã¿´Î±»¹¥»÷µôÂäµÄÎïÆ·¸öÊý±ýͼ¸ÅÂÊ  | 
| Def_AttackedDropItemTypeRate, # Ã¿´Î±»¹¥»÷µôÂäµÄÎïÆ·ÀàÐͱýͼ¸ÅÂÊ  | 
| Def_DieDropGoodsCountRate, # ËÀÍöµôÂäµÄµÀ¾ß¸öÊý±ýͼ¸ÅÂÊ  | 
| Def_DieDropEquipCountRate, # ËÀÍöµôÂäµÄ×°±¸¸öÊý±ýͼ¸ÅÂÊ  | 
| Def_DieDropCountRate, # ËÀÍöµôÂäÎïÆ·×ܸöÊý±ýͼ¸ÅÂÊ  | 
| Def_DropGoodsRate, # Òƶ¯/ËÀÍöµôÂäµÄµÀ¾ßµôÂä±ýͼ¸ÅÂʼ°µÀ¾ßid  | 
| Def_DropEquipModelNum, # Òƶ¯/ËÀÍöµôÂä×°±¸¹æÔòÄ£°å±àºÅ£¬Ä£°åÎļþGoblinDropEquip_Ä£°åÎļþ±àºÅ.txt  | 
| ) = range(8)  | 
|   | 
|   | 
| g_filterEquipDict = {} # ×°±¸µôÂä¹ýÂË×ֵ仺´æ  | 
| (  | 
| Def_EquipModel_EquipType, # µôÂä×°±¸ÀàÐÍ  | 
| Def_EquipModel_LVLimit, # µôÂä×°±¸µÈ¼¶ÏÞÖÆ  | 
| Def_EquipModel_QualityRate, # µôÂä×°±¸Æ·ÖʸÅÂÊ  | 
| Def_EquipModel_DropItemList, # NPC²»µôÂ䣬µ«ÕâÀï¿ÉµôÂäµÄÎïÆ·idÁÐ±í  | 
| ) = range(4)  | 
|   | 
|   | 
| # Òƶ¯·½Ïò  | 
| MoveDirList = (  | 
| Def_MoveDir_Up, # ÉÏ  | 
| Def_MoveDir_Down, # ÏÂ  | 
| Def_MoveDir_Left, # ×ó  | 
| Def_MoveDir_Right, # ÓÒ  | 
| Def_MoveDir_LeftUp, # ×óÉÏ  | 
| Def_MoveDir_LeftDown, # ×óÏÂ  | 
| Def_MoveDir_RightUp, # ÓÒÉÏ  | 
| Def_MoveDir_RightDown, # ÓÒÏÂ  | 
| ) = range(8)  | 
|   | 
| #---------------------------------------------------------------------  | 
|   | 
|   | 
| ## ³õʼ»¯  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def DoInit(curNPC):  | 
|     curNPC.GetNPCAngry().Init(ChConfig.Def_NormalNPCAngryCount)  | 
|     curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, 0) # ÉèÖñ»¹¥»÷ʱ¼ä  | 
|       | 
|     DoHideGoblin(curNPC)  | 
|     return  | 
|   | 
|   | 
| ## Ö´ÐÐAI  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def ProcessAI(curNPC, tick):  | 
|     if DoHideGoblin(curNPC):  | 
|         return  | 
|       | 
|     npcControl = NPCCommon.NPCControl(curNPC)  | 
|     if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():  | 
|         #NPCËÀÍö, ½øÈëËÀÍöµ¹¼ÆÊ±  | 
|         if npcControl.DieTick(tick) == 0:  | 
|             return  | 
|   | 
|     # ÉÏÒ»´Î±»¹¥»÷ʱ¼ä  | 
|     attackedTick = curNPC.GetDictByKey(Def_NPCKey_Goblin_AttackedTick)  | 
|       | 
|     # Î´±»¹¥»÷£¬Õ¾Á¢²»¶¯  | 
|     if attackedTick <= 0:  | 
|         __CheckCorrectGoblinPos(curNPC)  | 
|         return  | 
|       | 
|     aiConfig = __GetGoblinConfig(curNPC.GetNPCID())  | 
|       | 
|     # Ò»¶¨Ê±¼äÄÚδ±»¹¥»÷£¬ÔòÍ£Ö¹  | 
|     if tick - attackedTick >= aiConfig[Def_StopTime]:  | 
|         __GoblinStop(curNPC)  | 
|         return  | 
|       | 
|     curNPCAction = curNPC.GetCurAction()  | 
|     # Èç¹û²»ÊÇÒÆ¶¯×´Ì¬£¬ÔòÖ´ÐÐÒÆ¶¯  | 
|     if curNPCAction != IPY_GameWorld.laNPCMove:  | 
|         __Runaway(curNPC, npcControl, tick)  | 
|   | 
|     return  | 
|   | 
|   | 
| ## ¼ì²é²¢¾ÀÕý¸ç²¼ÁÖλÖà  | 
| #  @param curNPC   | 
| #  @return None  | 
| def __CheckCorrectGoblinPos(curNPC):  | 
|     curNPCAction = curNPC.GetCurAction()  | 
|     if curNPCAction != IPY_GameWorld.laNPCNull:  | 
|         return  | 
|       | 
|     gameMap = GameWorld.GetMap()  | 
|     posX = curNPC.GetPosX()  | 
|     posY = curNPC.GetPosY()  | 
|       | 
|     isCorrectPos = False  | 
|     if GameMap.GetAreaTypeByMapPos(posX, posY) == IPY_GameWorld.gatSafe:  | 
|         isCorrectPos = True  | 
|         GameWorld.DebugLog("µ±Ç°´¦ÔÚ°²È«Çø!(%s,%s)" % (posX, posY))  | 
|           | 
|     if not gameMap.CanMove(posX, posY):  | 
|         isCorrectPos = True  | 
|         GameWorld.DebugLog("µ±Ç°Õϰµã²»¿ÉÒÆ¶¯!(%s,%s)" % (posX, posY))  | 
|             | 
|     if not isCorrectPos:  | 
|         return  | 
|       | 
|     dist = ChConfig.Def_Screen_Area * 2  | 
|     cPosX, cPosY = 0, 0  | 
|     for i in range(0, dist * dist):  | 
|         cPosX = random.randint(posX - dist, posX + dist)  | 
|         cPosY = random.randint(posY - dist, posY + dist)  | 
|           | 
|         if gameMap.CanMove(cPosX, cPosY) and GameMap.GetAreaTypeByMapPos(cPosX, cPosY) != IPY_GameWorld.gatSafe:  | 
|             curNPC.ResetPos(cPosX, cPosY)  | 
|             GameWorld.Log("¸ç²¼ÁÖ´¦ÓÚ²»¿ÉÒÆ¶¯µã£¬ÖØÖÃλÖã¡(%s,%s) to (%s,%s)" % (posX, posY, cPosX, cPosY))  | 
|             break  | 
|     return  | 
|   | 
| ## ¸ç²¼ÁÖÍ£Ö¹ÒÆ¶¯  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @return None  | 
| def __GoblinStop(curNPC):  | 
|     #curNPC.Move(curNPC.GetPosX(), curNPC.GetPosY()) # Í£Ö¹ÔÚµ±Ç°µã  | 
|     curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, 0) # ÉèÖñ»¹¥»÷ʱ¼ä  | 
|     return  | 
|   | 
|   | 
| ## ¸ç²¼ÁÖÒÆ¶¯×ß¿ª  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @param npcControl   | 
| #  @param tick   | 
| #  @return None  | 
| def __Runaway(curNPC, npcControl, tick):  | 
|     posX = curNPC.GetPosX()  | 
|     posY = curNPC.GetPosY()  | 
|     moveArea = curNPC.GetMoveArea() # µ¥´ÎÒÆ¶¯·¶Î§  | 
|     moveDir = curNPC.GetDictByKey(Def_NPCKey_Goblin_MoveDir) # µ±Ç°·½Ïò  | 
|     tagPosX, tagPosY = 0, 0  | 
|       | 
|     # Ñ°ÕÒÄ¿±ê×ø±êµã  | 
|     for i in range(len(MoveDirList)):  | 
|         tagPosX, tagPosY = __GetRandomPos(posX, posY, moveArea, moveDir)  | 
|         # Èç¹û·µ»Ø0,0µã£¬»òÕßλÖò»±ä£¬Ôò¸Ä±äÒÆ¶¯·½Ïò  | 
|         if (tagPosX == 0 and tagPosY == 0) or (tagPosX == posX and tagPosY == posY):  | 
|             moveDir = __ChangeMoveDir(curNPC, moveDir)  | 
|           | 
|         # Èç¹ûÕÒµ½Ä¿±êµãÔòÌø³ö  | 
|         else:  | 
|             break  | 
|               | 
|     # ÉèÖÃΪ¼«ËÙ״̬  | 
|     # NPCCommon.ChangeNPCMoveType(curNPC, IPY_GameWorld.mtRun, True)  | 
|     # Òƶ¯µ½Ä¿±êµã  | 
|     curNPC.Move(tagPosX, tagPosY)  | 
|     return  | 
|   | 
| ## ¸ù¾Ýµ±Ç°·½Ïò¸Ä±äÒÆ¶¯·½Ïò  | 
| #  @param curNPC µ±Ç°npc  | 
| #  @param moveDir µ±Ç°·½Ïò  | 
| #  @return ¸Ä±äºóµÄ·½Ïò  | 
| def __ChangeMoveDir(curNPC, moveDir):  | 
|       | 
|     if moveDir == Def_MoveDir_Up: # ÉÏ  | 
|         nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Right, Def_MoveDir_LeftDown, Def_MoveDir_RightDown])  | 
|     elif moveDir == Def_MoveDir_Down: # ÏÂ  | 
|         nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Right, Def_MoveDir_LeftUp, Def_MoveDir_RightUp])  | 
|     elif moveDir == Def_MoveDir_Left: # ×ó  | 
|         nextDir = random.choice([Def_MoveDir_Up, Def_MoveDir_Down, Def_MoveDir_RightUp, Def_MoveDir_RightDown])  | 
|     elif moveDir == Def_MoveDir_Right: # ÓÒ  | 
|         nextDir = random.choice([Def_MoveDir_Up, Def_MoveDir_Down, Def_MoveDir_LeftUp, Def_MoveDir_LeftDown])  | 
|     elif moveDir == Def_MoveDir_LeftUp: # ×óÉÏ  | 
|         nextDir = random.choice([Def_MoveDir_Right, Def_MoveDir_Down, Def_MoveDir_RightUp, Def_MoveDir_LeftDown])  | 
|     elif moveDir == Def_MoveDir_LeftDown: # ×óÏÂ  | 
|         nextDir = random.choice([Def_MoveDir_Right, Def_MoveDir_Up, Def_MoveDir_RightDown, Def_MoveDir_LeftUp])  | 
|     elif moveDir == Def_MoveDir_RightUp: # ÓÒÉÏ  | 
|         nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Down, Def_MoveDir_LeftUp, Def_MoveDir_RightDown])  | 
|     elif moveDir == Def_MoveDir_RightDown: # ÓÒÏÂ  | 
|         nextDir = random.choice([Def_MoveDir_Left, Def_MoveDir_Up, Def_MoveDir_LeftDown, Def_MoveDir_RightUp])  | 
|     else:  | 
|         nextDir = random.choice(MoveDirList)  | 
|           | 
|     curNPC.SetDict(Def_NPCKey_Goblin_MoveDir, nextDir) # ÉèÖÃз½Ïò  | 
|     return nextDir  | 
|   | 
|   | 
| ##  Ëæ»ú»ñµÃµ±Ç°µØÍ¼¸ø¶¨×ø±êµÄx,yÔÚdist·¶Î§ÄڵĿÉÒÔÒÆ¶¯µÄÒ»µã Èç¹ûûÓÐÒ»µã¿ÉÒÔÒÆ¶¯Ôò·µ»Ø 0, 0  | 
| #   @param posX: ×ø±êX  | 
| #   @param posY: ×ø±êY  | 
| #   @param dist: ÖÜΧµÄ¾àÀë    | 
| #   @param moveDir: Ïà¶Ô¸ø¶¨×ø±ê·½Ïò    | 
| #   @return: posX,posY ×ø±ê Èç¹ûûÓÐÕÒµ½·µ»Ø0, 0  | 
| #   @remarks: Èç¹û·µ»Ø0, 0ÔÚµ÷Óøú¯ÊýµÄÄ£¿éÖÐÐèÒª×öÅж¨£¬Èç¹ûÊÇ0, 0×öÌØÊâ´¦Àí  | 
| def __GetRandomPos(posX, posY, dist, moveDir):  | 
|       | 
|     if moveDir not in MoveDirList:  | 
|         GameWorld.ErrLog("moveDir=%s not in MoveDirList" % moveDir)  | 
|         return (0, 0)  | 
|        | 
|     for i in range(0, dist * dist):  | 
|         if moveDir == Def_MoveDir_Up: # ÉÏ  | 
|             resultX = posX  | 
|             resultY = posY + dist  | 
|         elif moveDir == Def_MoveDir_Down: # ÏÂ  | 
|             resultX = posX  | 
|             resultY = posY - dist  | 
|         elif moveDir == Def_MoveDir_Left: # ×ó  | 
|             resultX = posX - dist  | 
|             resultY = posY  | 
|         elif moveDir == Def_MoveDir_Right: # ÓÒ  | 
|             resultX = posX + dist  | 
|             resultY = posY  | 
|         elif moveDir == Def_MoveDir_LeftUp: # ×óÉÏ  | 
|             resultX = posX - dist  | 
|             resultY = posY + dist  | 
|         elif moveDir == Def_MoveDir_LeftDown: # ×óÏÂ  | 
|             resultX = posX - dist  | 
|             resultY = posY - dist  | 
|         elif moveDir == Def_MoveDir_RightUp: # ÓÒÉÏ  | 
|             resultX = posX + dist  | 
|             resultY = posY + dist  | 
|         elif moveDir == Def_MoveDir_RightDown: # ÓÒÏÂ  | 
|             resultX = posX + dist  | 
|             resultY = posY - dist  | 
|           | 
|         # ¿ÉÒÆ¶¯£¬·Ç°²È«Çø  | 
|         if GameMap.GetAreaTypeByMapPos(resultX, resultY) \  | 
|                                                         != IPY_GameWorld.gatSafe:  | 
|             newPoint = GameWorld.GetMap().LineNearToPos(posX, posY, resultX, resultY, 0)  | 
|             return (newPoint.GetPosX(), newPoint.GetPosY())  | 
|   | 
|     return (0, 0)  | 
|   | 
| ## Ã¿´Î±»¹¥»÷´¦Àí½á¹û  | 
| #  @param atkObj ¹¥»÷·¢ÆðÕß  | 
| #  @param defObj ±»¹¥»÷Õß  | 
| #  @param skill ¹¥»÷¼¼ÄÜ  | 
| #  @param tick   | 
| #  @return ¾ßÌåÉ˺¦Öµ  | 
| def OnAttacked(atkObj, curNPC, skill, tick):  | 
|     curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, tick) # ÉèÖñ»¹¥»÷ʱ¼ä  | 
|       | 
|     # Ã¿´Î±»¹¥»÷µôÂäÎïÆ·  | 
|     __OnAttackedDropItem(atkObj, curNPC)  | 
|     return  | 
|   | 
|   | 
| ## Ã¿´Î±»¹¥»÷µôÂäÎïÆ·  | 
| #  @param atkObj ¹¥»÷·¢ÆðÕß  | 
| #  @param curNPC ±»¹¥»÷NPC  | 
| #  @return None  | 
| def __OnAttackedDropItem(atkObj, curNPC):  | 
|     npcControl = NPCCommon.NPCControl(curNPC)  | 
|     dropType = ChConfig.Def_NPCHurtTypeAll  | 
|     ownerID = 0  | 
|       | 
|     atkObjType = atkObj.GetGameObjType()  | 
|       | 
|     # Èç¹ûÊÇÍæ¼Ò£¬ÔòÎïÆ·ÓµÓÐÕßÊôÓÚ¸ÃÍæ¼Ò  | 
|     if atkObjType == IPY_GameWorld.gotPlayer:  | 
|         dropType = ChConfig.Def_NPCHurtTypePlayer  | 
|         ownerID = atkObj.GetPlayerID()  | 
|           | 
|     # Èç¹ûÊÇÕÙ»½ÊÞ»ò³èÎÔòÎïÆ·ÓµÓÐÕßÊôÓÚ¶ÔÓ¦Ö÷ÈË  | 
|     elif atkObjType == IPY_GameWorld.gotNPC:  | 
|         npcObjType = atkObj.GetGameNPCObjType()  | 
|         # ÅжÏÕÙ»½ÊÞÖ÷ÈË  | 
|         if npcObjType == IPY_GameWorld.gnotSummon:  | 
|             curNPCDetail = GameWorld.GetObjDetail(atkObj)  | 
|               | 
|             if curNPCDetail != None:  | 
|                 curNPCOwner = curNPCDetail.GetOwner()  | 
|                 summonOwner = GameWorld.GetObjDetail(curNPCOwner)  | 
|                 if summonOwner != None:  | 
|                     # ÕÙ»½ÊÞÖ÷ÈËÎªÍæ¼Ò  | 
|                     if summonOwner.GetGameObjType() == IPY_GameWorld.gotPlayer:  | 
|                         dropType = ChConfig.Def_NPCHurtTypePlayer  | 
|                         ownerID = summonOwner.GetPlayerID()  | 
|                           | 
|         # ÅжϳèÎïÖ÷ÈË  | 
|         elif npcObjType == IPY_GameWorld.gnotPet:  | 
|             curPlayer = PetControl.GetPetOwner(atkObj)  | 
|             if curPlayer != None:  | 
|                 dropType = ChConfig.Def_NPCHurtTypePlayer  | 
|                 ownerID = curPlayer.GetPlayerID()  | 
|       | 
|     aiConfig = __GetGoblinConfig(curNPC.GetNPCID())  | 
|     # µôÂä¸öÊý  | 
|     dropCount = GameWorld.GetResultByRandomList(aiConfig[Def_AttackedDropItemCountRate])  | 
|       | 
| ## µôÂ乿ÔòÐ޸ģ¬ÔÝÆÁ±Î£¬Ö®ºóÓÐÓõ½¸ÃAIÔÙ×öÐÞ¸Ä  | 
| #    # Ñ»·µôÂä  | 
| #    for i in range(dropCount):  | 
| #        dropItemType = GameWorld.GetResultByRandomList(aiConfig[Def_AttackedDropItemTypeRate])  | 
| #          | 
| #        # ½ðÇ®  | 
| #        if dropItemType == Def_DropItemType_Money:  | 
| #            npcControl.DropMoney(ChConfig.Def_NPCMapDropRate, dropType, ownerID)  | 
| #        # µÀ¾ß  | 
| #        elif dropItemType == Def_DropItemType_Goods:  | 
| #            goodsID = GameWorld.GetResultByRandomList(aiConfig[Def_DropGoodsRate])  | 
| #            npcControl.DropItem(goodsID, dropType, ownerID)  | 
| #        # ×°±¸  | 
| #        elif dropItemType == Def_DropItemType_Equip:  | 
| #            equipID = __GetRadomDropEquipID(aiConfig[Def_DropEquipModelNum])  | 
| #            npcControl.DropItem(equipID, dropType, ownerID)  | 
|     return  | 
|   | 
|   | 
| ## NPCËÀÍö´¦Àí  | 
| #  @param curNPC ËÀÍöNPC  | 
| #  @param HurtType µôÂäÀàÐÍ  | 
| #  @param HurtID ¶ÔÓ¦ÓµÓÐÕßid  | 
| #  @param modulus µôÂäϵÊý  | 
| #  @return None  | 
| def OnDie(curNPC, HurtType, HurtID):  | 
|     #GameWorld.DebugLog("OnDieDropItem...dropType=%s, ownerID=%s" % (dropType, ownerID))  | 
|     # ¸ÃËÀÍöµôÂäÎÞÎïÆ·±£»¤  | 
|     dropType = ChConfig.Def_NPCHurtTypeAll  | 
|     ownerID = 0  | 
|     npcControl = NPCCommon.NPCControl(curNPC)  | 
|       | 
|     if curNPC.GetNPCID() == 0:  | 
|         GameWorld.ErrLog("AIType_196 OnDie NPCID=0")  | 
|         return  | 
|     aiConfig = __GetGoblinConfig(curNPC.GetNPCID())  | 
|     dropItemIDList = [] # [[itemID, count],...]  | 
|       | 
|     # µÀ¾ßµôÂä¸öÊý  | 
|     dropGoodsCount = GameWorld.GetResultByRandomList(aiConfig[Def_DieDropGoodsCountRate])  | 
|     for i in range(dropGoodsCount):  | 
|         goodsID = GameWorld.GetResultByRandomList(aiConfig[Def_DropGoodsRate])  | 
|         dropItemIDList.append([goodsID, 1]) # Ôö¼ÓÒ»¸öµôÂäµÀ¾ß  | 
|           | 
|     # ×°±¸µôÂä¸öÊý  | 
|     dropEquipCount = GameWorld.GetResultByRandomList(aiConfig[Def_DieDropEquipCountRate])  | 
|     for i in range(dropEquipCount):  | 
|         equipID = __GetRadomDropEquipID(aiConfig[Def_DropEquipModelNum])  | 
|         dropItemIDList.append([equipID, 1]) # Ôö¼ÓÒ»¸öµôÂä×°±¸  | 
|       | 
|     # µôÂä×ܸöÊý  | 
|     dropCount = GameWorld.GetResultByRandomList(aiConfig[Def_DieDropCountRate])  | 
|     # npc³¬±¬  | 
|     #npcControl.NPCSuperDropByItemIDExMoney(dropItemIDList, dropType, ownerID, dropCount)  | 
|     # È«·þ¹ã²¥  | 
|     mapID = GameWorld.GetMap().GetMapID()  | 
|     if mapID not in []:  | 
|         notifyMarkDict = ReadChConfig.GetEvalChConfig("GoblinNotify")  | 
|         notifyMark = notifyMarkDict.get(curNPC.GetNPCID())  | 
|         if notifyMark:  | 
|             PlayerControl.WorldNotify(0, notifyMark, [GameWorld.GetMap().GetMapID()])    | 
|     return  | 
|   | 
|   | 
| ## Íæ¼Ò»÷ɱ¸ç²¼ÁÖ  | 
| #  @param curNPC  | 
| #  @param curPlayer  | 
| #  @param skill  | 
| #  @return   | 
| def OnAttackDieByPlayer(curNPC, curPlayer, skill):  | 
|     DataRecordPack.DR_KillNPC(curPlayer, "Goblin", curNPC.GetNPCID())  | 
|     return  | 
|   | 
|   | 
| ## »ñÈ¡¶ÔÓ¦¸ç²¼ÁÖÅäÖà  | 
| #  @param npcID  | 
| #  @return ÅäÖÃÐÅÏ¢  | 
| def __GetGoblinConfig(npcID):  | 
|     return ReadChConfig.GetEvalChConfig('Goblin_%s' % npcID)  | 
|   | 
|   | 
| ## »ñÈ¡Ëæ»úµôÂä×°±¸id  | 
| #  @param dropEquipModelNum ×°±¸µôÂ乿ÔòÄ£°å±àºÅ  | 
| #  @return >0µôÂä×°±¸id£¬·µ»Ø0±íʾÎÞ·¨»ñÈ¡µôÂä×°±¸id  | 
| def __GetRadomDropEquipID(dropEquipModelNum):  | 
|     global g_filterEquipDict  | 
|       | 
|     dropEquipModel = ReadChConfig.GetEvalChConfig('GoblinDropEquip_%s' % dropEquipModelNum)  | 
|       | 
|     filterItemList = g_filterEquipDict.get(dropEquipModelNum)  | 
|     # Èç¹ûûÓУ¬Ôò¼ÓÔØ  | 
|     if not filterItemList:  | 
|         GameWorld.DebugLog("¼ÓÔØ¸ç²¼ÁÖµôÂä×°±¸Ä£°åGoblinDropEquip_%s.txt" % dropEquipModelNum)  | 
|         itemTypeList = dropEquipModel[Def_EquipModel_EquipType]  | 
|         itemMinLV = dropEquipModel[Def_EquipModel_LVLimit][0]  | 
|         itemMaxLV = dropEquipModel[Def_EquipModel_LVLimit][1]  | 
|         dropIDList = dropEquipModel[Def_EquipModel_DropItemList]  | 
|         filterItemList = __FilterItemFromDB(itemTypeList, itemMinLV, itemMaxLV, dropIDList)  | 
|         g_filterEquipDict[dropEquipModelNum] = filterItemList  | 
|       | 
|     # Ëæ»úÊÇ·ñ׿Խ  | 
|     quality = GameWorld.GetResultByRandomList(dropEquipModel[Def_EquipModel_QualityRate])  | 
|       | 
|     dropEquipIdList = filterItemList[quality]  | 
|       | 
|     if not dropEquipIdList:  | 
|         GameWorld.ErrLog("__GetRadomDropEquipID() can not find filter equip£¬" + \  | 
|                          "please check GoblinDropEquip_%s.txt!!!" % dropEquipModelNum)  | 
|         return 0  | 
|       | 
|     return random.choice(dropEquipIdList)  | 
|   | 
|   | 
| ## ´ÓÊý¾Ý¿âÖвéÕÒÂú×ãÒªÇóµÄÎïÆ·ID  | 
| #  @param itemTypeList: »ñµÃµÄÎïÆ·ÀàÐÍÁÐ±í  | 
| #  @param itemMinLV: »ñµÃµÄÎïÆ·×îµÍµÈ¼¶  | 
| #  @param itemMaxLV: »ñµÃµÄÎïÆ·×î¸ßµÈ¼¶  | 
| #  @param dropIDList: NPC²»µôÂ䣬µ«ÕâÀï¿ÉµôÂäµÄÎïÆ·idÁÐ±í  | 
| #  @return ÕÒµ½µÄÎïÆ·IDÁÐ±í£º[[·Ç׿ԽװidÁбí], [׿ԽװidÁбí]]  | 
| def __FilterItemFromDB(itemTypeList, itemMinLV, itemMaxLV, dropIDList):  | 
|     findItemIdList = [[], []] # [[·Ç׿Խװ], [׿Խװ]]  | 
|       | 
|     for itemType in itemTypeList:  | 
|       | 
|         gameData = GameWorld.GetGameData()  | 
|         gameData.FilterItemByType(itemType) # ¹ýÂËÎïÆ·ÀàÐÍ  | 
|         for i in range(0, gameData.GetFilterItemCount()):  | 
|             curFindItem = gameData.GetFilterItem(i)  | 
|             itemID = curFindItem.GetItemTypeID()  | 
|               | 
|             # NPC²»µôÂäµÄ£¬ÇÒ²»ÔÚÌØ¶¨µôÂäidÁбíÀïµÄ²»µôÂä  | 
|             if not curFindItem.GetCanNPCDrop() and itemID not in dropIDList:  | 
|                 continue  | 
|               | 
|             # ²»ÔÚ¹ýÂ˵ȼ¶ÄÚ£¬Ìø¹ý  | 
|             if curFindItem.GetLV() < itemMinLV or curFindItem.GetLV() > itemMaxLV:  | 
|                 continue  | 
|   | 
|             findItemIdList[1 if curFindItem.GetItemQuality() else 0].append(curFindItem.GetItemTypeID())  | 
|       | 
|     GameWorld.DebugLog("¸ç²¼ÁÖµôÂä×°±¸idÁбí=%s£¬×¿Ô½×°±¸idÁбí=%s" % (str(findItemIdList[0]), str(findItemIdList[1])))  | 
|     return findItemIdList  | 
|   | 
| ## Òþ²ØNPC  | 
| def DoHideGoblin(curNPC):  | 
|       | 
|     # Ö»ÔÚÒ»ÏßË¢, ·ÇÒ»ÏßÉèÖøÃNPCÒþÉí  | 
|     lineID = GameWorld.GetGameWorld().GetLineID()  | 
|     if lineID != 0:  | 
|         goblinNPCIDList = [30000,30001,30002,30003,30004,30005,30006,30007,30008,30009]  | 
|         npcID = curNPC.GetNPCID()  | 
|         if npcID in goblinNPCIDList and curNPC.GetVisible():  | 
|             curNPC.SetVisible(False)  | 
|             GameWorld.Log("·ÇÒ»Ïߣ¬Òþ²Ø¸ÃNPCID=%s£¡" % npcID)  | 
|             return True  | 
|           | 
|     return False  |