From 43ec61799c5cc015c49ca6d0ace4b356f50a95af Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 16 五月 2019 15:40:25 +0800
Subject: [PATCH] 6805 【后端】【2.0】副本前端化(增加可否进入自定义场景通用判断,增加回包,木桩怪上限调整为10个)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_196.py | 354 +++++++++++++++-------------------------------------------
1 files changed, 91 insertions(+), 263 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_196.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_196.py
index c3c6f73..d77b4ee 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_196.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_196.py
@@ -1,70 +1,38 @@
#!/usr/bin/python
# -*- coding: GBK -*-
-#---------------------------------------------------------------------
+#-------------------------------------------------------------------------------
#
-#---------------------------------------------------------------------
-##@package AIType_196
-# @todo: 盗宝哥布林AI
+##@package NPCAI.AIType_196
#
-# @author: hxp
-# @date 2013-11-05
-# @version 1.9
+# @todo:盗宝哥布林/宝箱怪
+# @author hxp
+# @date 2019-04-18
+# @version 1.0
#
-# @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 修改不掉落物品由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
+# 详细描述: 盗宝哥布林/宝箱怪
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2019-04-18 15:00"""
+#-------------------------------------------------------------------------------
+
+import GameMap
+import ChConfig
import GameWorld
import NPCCommon
-import ChConfig
-import ReadChConfig
-import PetControl
-import GameMap
-import DataRecordPack
+import IPY_GameWorld
import PlayerControl
+import IpyGameDataPY
+import AttackCommon
+import ItemCommon
+import GameObj
+import ChItem
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 = (
@@ -87,9 +55,7 @@
# @remarks 函数详细说明.
def DoInit(curNPC):
curNPC.GetNPCAngry().Init(ChConfig.Def_NormalNPCAngryCount)
- curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, 0) # 设置被攻击时间
-
- DoHideGoblin(curNPC)
+ #curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, 0) # 设置被攻击时间
return
@@ -99,15 +65,13 @@
# @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)
@@ -116,10 +80,8 @@
__CheckCorrectGoblinPos(curNPC)
return
- aiConfig = __GetGoblinConfig(curNPC.GetNPCID())
-
# 一定时间内未被攻击,则停止
- if tick - attackedTick >= aiConfig[Def_StopTime]:
+ if tick - attackedTick >= 3000:
__GoblinStop(curNPC)
return
@@ -127,7 +89,7 @@
# 如果不是移动状态,则执行移动
if curNPCAction != IPY_GameWorld.laNPCMove:
__Runaway(curNPC, npcControl, tick)
-
+
return
@@ -157,7 +119,7 @@
dist = ChConfig.Def_Screen_Area * 2
cPosX, cPosY = 0, 0
- for i in range(0, dist * dist):
+ for _ in xrange(0, dist * dist):
cPosX = random.randint(posX - dist, posX + dist)
cPosY = random.randint(posY - dist, posY + dist)
@@ -176,11 +138,7 @@
return
-## 哥布林移动走开
-# @param curNPC 当前npc
-# @param npcControl
-# @param tick
-# @return None
+## 移动走开
def __Runaway(curNPC, npcControl, tick):
posX = curNPC.GetPosX()
posY = curNPC.GetPosY()
@@ -189,7 +147,7 @@
tagPosX, tagPosY = 0, 0
# 寻找目标坐标点
- for i in range(len(MoveDirList)):
+ for _ 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):
@@ -247,7 +205,7 @@
GameWorld.ErrLog("moveDir=%s not in MoveDirList" % moveDir)
return (0, 0)
- for i in range(0, dist * dist):
+ for _ in range(0, dist * dist):
if moveDir == Def_MoveDir_Up: # 上
resultX = posX
resultY = posY + dist
@@ -288,210 +246,80 @@
# @param tick
# @return 具体伤害值
def OnAttacked(atkObj, curNPC, skill, tick):
+ npcControl = NPCCommon.NPCControl(curNPC)
+ if GameObj.GetHP(curNPC) < GameObj.GetMaxHP(curNPC) / 2:
+ GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC))
+ GameWorld.DebugLog("半血回满血!")
curNPC.SetDict(Def_NPCKey_Goblin_AttackedTick, tick) # 设置被攻击时间
# 每次被攻击掉落物品
- __OnAttackedDropItem(atkObj, curNPC)
+ __OnAttackedDropItem(atkObj, curNPC, npcControl)
return
+
+def OnCheckCanDie(atkObj, curNPC, skill, tick):
+ ## 检查NPC是否可死亡
+ GameObj.SetHP(curNPC, GameObj.GetMaxHP(curNPC))
+ GameWorld.DebugLog("死亡回满血!")
+ return False
## 每次被攻击掉落物品
# @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")
+def __OnAttackedDropItem(atkObj, curNPC, npcControl):
+ attackPlayer, npcObjType = AttackCommon.GetAttackPlayer(atkObj)
+ if npcObjType:
return
- aiConfig = __GetGoblinConfig(curNPC.GetNPCID())
- dropItemIDList = [] # [[itemID, count],...]
+ if not attackPlayer:
+ return
+ npcID = curNPC.GetNPCID()
+ ipyData = IpyGameDataPY.GetIpyGameDataNotLog("TreasureNPC", npcID)
+ if not ipyData:
+ return
+ attackCountDropWeightInfo = ipyData.GetAttackCountDropWeightInfo()
+ attackDropWeightList = ipyData.GetAttackDropWeightList()
+ attackDropWeightListEx = ipyData.GetAttackDropWeightListEx()
+ dropCountEx = ipyData.GetDropCountEx()
+ alchemyDiffLV = ipyData.GetAlchemyDiffLV()
- # 道具掉落个数
- dropGoodsCount = GameWorld.GetResultByRandomList(aiConfig[Def_DieDropGoodsCountRate])
- for i in range(dropGoodsCount):
- goodsID = GameWorld.GetResultByRandomList(aiConfig[Def_DropGoodsRate])
- dropItemIDList.append([goodsID, 1]) # 增加一个掉落道具
+ mainItemWeightList = []
+ if attackCountDropWeightInfo:
+ maxCount = max(attackCountDropWeightInfo)
+ attackCount = attackPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCAttackCount % npcID) + 1
+ if attackCount <= maxCount:
+ if attackCount in attackCountDropWeightInfo:
+ mainItemWeightList = attackCountDropWeightInfo[attackCount]
+ NPCCommon.UpdateNPCAttackCount(attackPlayer, npcID, attackCount, maxCount)
+
+ if mainItemWeightList:
+ mainItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, mainItemWeightList, alchemyDiffLV)
+ elif attackDropWeightList:
+ mainItemWeightList = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, attackDropWeightList, alchemyDiffLV)
- # 装备掉落个数
- dropEquipCount = GameWorld.GetResultByRandomList(aiConfig[Def_DieDropEquipCountRate])
- for i in range(dropEquipCount):
- equipID = __GetRadomDropEquipID(aiConfig[Def_DropEquipModelNum])
- dropItemIDList.append([equipID, 1]) # 增加一个掉落装备
+ mainItemInfo = GameWorld.GetResultByWeightList(mainItemWeightList)
- # 掉落总个数
- 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()])
+ if not mainItemInfo:
+ notDropNotify = ipyData.GetNotDropNotify()
+ if notDropNotify:
+ PlayerControl.NotifyCode(attackPlayer, notDropNotify)
+ return
+
+ dropItemList = []
+ if mainItemInfo:
+ dropItemList.append(mainItemInfo)
+
+ if attackDropWeightListEx and dropCountEx:
+ weightListEx = ItemCommon.GetWeightItemListByAlchemyDiffLV(attackPlayer, attackDropWeightListEx, alchemyDiffLV)
+ for _ in xrange(dropCountEx):
+ itemInfo = GameWorld.GetResultByWeightList(weightListEx)
+ if itemInfo:
+ dropItemList.append(itemInfo)
+
+ if not dropItemList:
+ return
+
+ dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()
+ ChItem.DoMapDropItem(attackPlayer, dropItemList, npcID, dropPosX, dropPosY, isOnlySelfSee=False)
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
--
Gitblit v1.8.0