From b965081066ea579c45c73f08cd9cd61bc157ac9f Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 09 五月 2019 11:15:45 +0800
Subject: [PATCH] 6459 【后端】【2.0】缥缈仙域开发单(防范跨服妖王关闭线路时导致的报错)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 646 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 584 insertions(+), 62 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
index 15d6446..30c0148 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -44,14 +44,13 @@
import PlayerActivity
import PlayerSuccess
import BossHurtMng
-import PlayerSuperMarket
import GameLogic_FamilyInvade
import GameLogic_GatherSoul
import FormulaControl
-import PlayerMagicWeapon
import PlayerBossReborn
import PlayerFairyCeremony
import PlayerNewFairyCeremony
+import GameLogic_CrossGrassland
import PlayerWeekParty
import PlayerActLogin
import FamilyRobBoss
@@ -96,8 +95,6 @@
#初始化处理间隔
curNPC.SetIsNeedProcess(False)
- #设定致命一击伤害百分比
- curNPC.SetSuperHit(ChConfig.Def_SuperHitPercent)
#初始化这个NPC的时钟
curNPC.SetTickTypeCount(ChConfig.TYPE_NPC_Tick_Count)
return
@@ -1225,7 +1222,7 @@
itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
if not itemData:
continue
- itemJob = itemData.GetJobLimit() / 100
+ itemJob = itemData.GetJobLimit()
if itemJob and itemJob != curPlayer.GetJob():
# 非本职业可用,不掉落
GameWorld.DebugLog("全服击杀次数必掉,非本职业可用,不掉落! itemID=%s" % itemID)
@@ -1239,7 +1236,7 @@
itemData = GameWorld.GetGameData().GetItemByTypeID(rItemID)
if not itemData:
continue
- itemJob = itemData.GetJobLimit() / 100
+ itemJob = itemData.GetJobLimit()
if itemJob and itemJob != curPlayer.GetJob():
# 非本职业可用,不掉落
GameWorld.DebugLog("全服击杀次数必掉随机,非本职业可用,不掉落! rItemID=%s" % rItemID)
@@ -1278,7 +1275,7 @@
if itemData.GetItemColor() != color:
continue
suiteID = itemData.GetSuiteID()
- itemJob = itemData.GetJobLimit() / 100
+ itemJob = itemData.GetJobLimit()
itemPlace = itemData.GetEquipPlace()
itemID = itemData.GetItemTypeID()
if itemPlace not in filterItemIDDict:
@@ -1404,7 +1401,7 @@
if not itemData:
GameWorld.ErrLog("掉落物品ID不存在, dropItemID=%s" % dropItemID)
continue
- itemJob = itemData.GetJobLimit() / 100
+ itemJob = itemData.GetJobLimit()
if isJobLimit and itemJob and itemJob != curPlayer.GetJob():
# 非本职业可用,不掉落
#GameWorld.DebugLog("非本职业可用,不掉落! dropItemID=%s" % dropItemID)
@@ -1943,6 +1940,67 @@
return
+#// B4 0C 召唤私有专属木桩怪 #tagCMSummonPriWoodPile
+#
+#struct tagCMSummonPriWoodPile
+#{
+# tagHead Head;
+# DWORD NPCID;
+# BYTE Count; //默认1个,最多5个
+#};
+def OnSummonPriWoodPile(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ npcID = clientData.NPCID
+ count = clientData.Count
+ SummonPriWoodPile(curPlayer, npcID, count)
+ return
+
+def SummonPriWoodPile(curPlayer, npcID, count):
+ ''' 召唤私有专属木桩怪
+ '''
+
+ maxCount = 5
+ nowCount = 0
+ # 只允许存在一个私有木桩
+ indexList = range(curPlayer.GetSummonCount())
+ for index in indexList[::-1]:
+ summonNPC = curPlayer.GetSummonNPCAt(index)
+ if not summonNPC:
+ continue
+ npcType = summonNPC.GetType()
+ if npcType not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
+ continue
+ if nowCount >= maxCount or summonNPC.GetNPCID() != npcID:
+ SetDeadEx(summonNPC)
+ else:
+ nowCount += 1
+
+ summonCount = min(count, maxCount - nowCount)
+ #GameWorld.DebugLog("召唤: count=%s,maxCount=%s,nowCount=%s,summonCount=%s"
+ # % (count, maxCount, nowCount, summonCount))
+ if summonCount <= 0:
+ return
+
+ for _ in xrange(summonCount):
+ summonNPC = curPlayer.SummonNewNPC()
+
+ #设置召唤兽基础信息
+ summonNPC.SetNPCTypeID(npcID)
+ #初始化
+ InitNPC(summonNPC)
+
+ #玩家召唤兽列表添加召唤兽,召唤兽添加主人
+ summonNPC.SetOwner(curPlayer)
+ summonNPC.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, curPlayer.GetPlayerID())
+
+ #将召唤兽召唤出来
+ #玩家周围随机出生点
+ #技能召唤坐标 ChConfig.Def_SummonAppearDist
+ summonPos = GameMap.GetEmptyPlaceInArea(curPlayer.GetPosX(), curPlayer.GetPosY(), 3)
+ summonNPC.Reborn(summonPos.GetPosX(), summonPos.GetPosY())
+
+ return
+
## 设置npc死亡及自身处理(请不要将游戏逻辑加在此函数中)
# @param curNPC:npc实例
# @return
@@ -1997,31 +2055,34 @@
return
def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):
- dataMapID = GameWorld.GetGameWorld().GetMapID()
+ mapID = GameWorld.GetGameWorld().GetMapID()
realMapID = GameWorld.GetGameWorld().GetRealMapID()
copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
- killMsg = str([bossID, killPlayerName, hurtValue, isNotify, realMapID, dataMapID, copyMapID, killerIDList])
+ killMsg = str([bossID, killPlayerName, hurtValue, isNotify, mapID, realMapID, copyMapID, killerIDList])
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'KillGameWorldBoss', killMsg, len(killMsg))
- GameWorld.DebugLog("Boss被击杀: bossID=%s,dataMapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s" % (bossID, dataMapID, realMapID, copyMapID, killerIDList))
+ GameWorld.DebugLog("Boss被击杀: bossID=%s,mapID=%s,realMapID=%s,copyMapID=%s,killerIDList=%s" % (bossID, mapID, realMapID, copyMapID, killerIDList))
return
def GameServe_GameWorldBossState(bossID, isAlive):
- dataMapID = GameWorld.GetGameWorld().GetMapID()
+ mapID = GameWorld.GetGameWorld().GetMapID()
realMapID = GameWorld.GetGameWorld().GetRealMapID()
copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
- stateMsg = str([bossID, isAlive, dataMapID, realMapID, copyMapID])
+ stateMsg = str([bossID, isAlive, mapID, realMapID, copyMapID])
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState', '%s' % stateMsg, len(stateMsg))
- GameWorld.DebugLog("Boss状态变更: bossID=%s,isAlive=%s,dataMapID=%s,realMapID=%s,copyMapID=%s"
- % (bossID, isAlive, dataMapID, realMapID, copyMapID))
+ GameWorld.DebugLog("Boss状态变更: bossID=%s,isAlive=%s,mapID=%s,realMapID=%s,copyMapID=%s"
+ % (bossID, isAlive, mapID, realMapID, copyMapID))
if not isAlive:
- if dataMapID in ChConfig.Def_CrossZoneMapTableName:
- tableName = ChConfig.Def_CrossZoneMapTableName[dataMapID]
+ if mapID in ChConfig.Def_CrossZoneMapTableName:
+ tableName = ChConfig.Def_CrossZoneMapTableName[mapID]
realMapID = GameWorld.GetGameWorld().GetRealMapID()
copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
- zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID)
+ zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, mapID, copyMapID)
if not zoneIpyData:
return
zoneID = zoneIpyData.GetZoneID()
+ GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0)
+ elif mapID in ChConfig.Def_CrossDynamicLineMap:
+ zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID), 0)
else:
GameWorld.GetGameWorld().SetGameWorldDict(ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID, 0)
@@ -2224,8 +2285,9 @@
moveDestY = resultPos.GetPosY()
if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove and \
- (GameWorld.GetGameWorld().GetTick() - curNPC.GetActionTick()) < 1200:
- # Move接口调用太快会导致不移动
+ (GameWorld.GetGameWorld().GetTick() - curNPC.GetActionTick()) < 800:
+ # .Move( 接口调用太快会导致移动时间不够长(不足一格)导致无法移动 或者移动过慢问题
+ # SetDestPos 调用会导致反向移动偏快
curNPC.SetDestPos(moveDestX, moveDestY)
return
#=======================================================================
@@ -3554,14 +3616,13 @@
def DoHPPerLogic(self, dropType, ownerID):
curNPC = self.__Instance
curNPCID = curNPC.GetNPCID()
- hpPerLogicNPCIDList = ReadChConfig.GetEvalChConfig('HPPerLogicNPCIDList')
- if curNPCID not in hpPerLogicNPCIDList:
+
+ hpPerLogicNPCIDDict = IpyGameDataPY.GetFuncEvalCfg('BossHPInformation', 1, {})
+ hpPerLogicList = GameWorld.GetDictValueByKey(hpPerLogicNPCIDDict, curNPCID)
+ if not hpPerLogicList:
return
-
- hpPerLogicDict = ReadChConfig.GetEvalChConfig('HPPerLogic_%s' % curNPCID)
-
- hpPerList = sorted(hpPerLogicDict.keys(), reverse=True)
-
+ hpPerList, sysMark = hpPerLogicList
+ hpPerList = sorted(hpPerList, reverse=True)
nowHPPer = GameObj.GetHP(curNPC) * 100 / GameObj.GetMaxHP(curNPC) # 当前百分比
hpPerLogicMark = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_HPPerLogicMark)
logicHPPerList = hpPerList[hpPerLogicMark:]
@@ -3574,16 +3635,12 @@
#GameWorld.DebugLog("DoHPPerLogic npcID=%s,hpPerLogicDict=%s,nowHPPer=%s,hpPerLogicMark=%s,logicHPPerList=%s"
# % (curNPCID, str(hpPerLogicDict), nowHPPer, hpPerLogicMark, str(logicHPPerList)))
- isNotify, dropItemTemplate, addPrestigeFormat = hpPerLogicDict[hpPer]
- if isNotify:
- PlayerControl.WorldNotify(0, "FB_liubo_0", [GameWorld.GetMap().GetMapID(), curNPCID, hpPer])
+
+ PlayerControl.WorldNotify(0, sysMark, [curNPCID, hpPer])
# if dropItemTemplate > 0:
# self.__DropItemByTemplate(dropItemTemplate, dropType, ownerID)
# PlayerControl.WorldNotify(0, "GeRen_admin_481766", [GameWorld.GetMap().GetMapID(), curNPCID, curNPCID])
-
- if addPrestigeFormat != '':
- self.__GiveNearbyPlayerPrestige(addPrestigeFormat, ChConfig.Def_Matrix_Six)
hpPerLogicMark += 1
#GameWorld.DebugLog("DoHPPerLogic update hpPerLogicMark=%s" % (hpPerLogicMark))
@@ -3708,7 +3765,6 @@
############################################
#初始化状态
curNPC.SetSpeed(curNPC.GetOrgSpeed())
- curNPC.SetSuperHit(ChConfig.Def_SuperHitPercent)
curNPC.SetAtkInterval(curNPC.GetBaseAtkInterval())
# #先清空异常
@@ -3894,11 +3950,11 @@
#杀死NPC, 触发任务
self.__EventKillNpc()
- #mapID = GameWorld.GetMap().GetMapID()
+ mapID = GameWorld.GetMap().GetMapID()
killerName = "" if not self.__Killer else self.__Killer.GetPlayerName()
# 记录boss击杀信息的NPC
bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID)
- if bossIpyData:
+ if bossIpyData and mapID not in [ChConfig.Def_FBMapID_ZhuXianBoss, ChConfig.Def_FBMapID_SealDemon]:
if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID)
#KillerJob = 0 if not self.__Killer else self.__Killer.GetJob()
@@ -4102,10 +4158,10 @@
mapID = GameWorld.GetMap().GetMapID()
mapID = FBCommon.GetRecordMapID(mapID)
isGameBoss = ChConfig.IsGameBoss(curNPC)
+ if mapID in [ChConfig.Def_FBMapID_MunekadoTrial, ChConfig.Def_FBMapID_DemonKing]:
+ return
if isGameBoss:
GameWorld.Log("NPC开始掉落: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID())
- if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
- return
ipyDrop = GetNPCDropIpyData(npcID)
if not ipyDrop:
if isGameBoss:
@@ -5087,6 +5143,354 @@
return
return curItem
+ ##----------------------------------------- 归属 -----------------------------------------------
+
+ def RefreshDropOwner(self, tick, refreshInterval=3000, isDead=False):
+ ## 刷新boss掉落归属
+ # @return: 可攻击的掉落归属目标玩家
+
+ curNPC = self.__Instance
+ tagObj = None # 即将攻击的目标, 归属最大伤血取最大伤血玩家或队伍队员,其他取最大仇恨
+ ownerType, ownerID = 0, 0
+ dropOwnerType = GetDropOwnerType(curNPC)
+ if isDead:
+ GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s"
+ % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))
+ if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
+ maxHurtObj = self.RefreshHurtList(tick, refreshInterval)
+ if maxHurtObj:
+ ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID()
+ if ownerType == ChConfig.Def_NPCHurtTypeTeam:
+ tagObj = self.__GetMaxHurtTeamPlayer(ownerID, isDead)
+ elif ownerType == ChConfig.Def_NPCHurtTypePlayer:
+ tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
+
+ elif dropOwnerType == ChConfig.DropOwnerType_Family:
+ ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval)
+ if ownerInfo:
+ tagObj, ownerFamilyID = ownerInfo
+ ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID
+
+ elif dropOwnerType == ChConfig.DropOwnerType_Contend:
+ tagObj = self.__RefreshContendOwner()
+ if tagObj:
+ ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, tagObj.GetPlayerID()
+
+ if isDead:
+ GameWorld.Log("ownerType=%s, ownerID=%s, tagObjID=%s" % (ownerType, ownerID, 0 if not tagObj else tagObj.GetPlayerID()))
+
+ # 没有攻击目标,则刷新仇恨,支持主动怪
+ if not tagObj:
+ angryObjType, maxAngryObj = None, None
+ self.RefreshAngryList(tick, refreshInterval, isUpdAngry=True)
+ maxAngry = self.GetMaxAngryTag()
+ if maxAngry:
+ angryID = maxAngry.GetObjID()
+ angryObjType = maxAngry.GetObjType()
+ #GameWorld.DebugLog("最大仇恨目标: ID=%s, Type=%s" % (angryID, angryObjType))
+ maxAngryObj = GameWorld.GetObj(angryID, angryObjType)
+
+ tagObj = maxAngryObj
+ if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType:
+ if dropOwnerType == ChConfig.DropOwnerType_Contend:
+ ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()
+ elif maxAngryObj.GetTeamID():
+ ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, maxAngryObj.GetTeamID()
+ else:
+ ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()
+
+ if isDead:
+ GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID))
+
+ self.UpdateDropOwner(tick, ownerType, ownerID, isDead)
+ return tagObj
+
+ def __RefreshContendOwner(self):
+ ## 刷新boss争夺归属者,归属移除时不做刷新新归属,默认由后面的仇恨刷新
+
+ curNPC = self.__Instance
+ ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
+ ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
+ if not ownerID or ownerType != ChConfig.Def_NPCHurtTypePlayer:
+ return
+
+ owner = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
+ if not owner:
+ return
+
+ if not owner.GetVisible():
+ GameWorld.DebugLog("竞争归属玩家不可见,移除归属!playerID=%s" % ownerID)
+ return
+
+ if owner.GetHP() <= 0 or owner.GetPlayerAction() == IPY_GameWorld.paDie:
+ GameWorld.DebugLog("竞争归属玩家死亡,移除归属!playerID=%s" % ownerID)
+ return
+
+ refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+ if not self.GetIsInRefreshPoint(owner.GetPosX(), owner.GetPosY(), refreshPoint):
+ GameWorld.DebugLog("竞争归属玩家不在boss范围里,移除归属!playerID=%s" % ownerID)
+ return
+
+ #GameWorld.DebugLog("竞争归属玩家归属正常!playerID=%s" % ownerID)
+ return owner
+
+ def __GetMaxHurtTeamPlayer(self, teamID, isDead):
+ ## 获取最大伤血队伍中攻击的目标队员
+
+ curNPC = self.__Instance
+ curTeam = GameWorld.GetTeamManager().FindTeam(teamID)
+ if curTeam:
+ refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+ if isDead:
+ GameWorld.Log("队伍成员数: teamID=%s,memberCount=%s" % (teamID, curTeam.GetMemberCount()))
+ for i in xrange(curTeam.GetMemberCount()):
+ curTeamPlayer = curTeam.GetMember(i)
+ if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
+ if isDead:
+ GameWorld.Log(" i=%s, 队员为空!" % i)
+ continue
+ if curTeamPlayer.GetHP() <= 0:
+ if isDead:
+ GameWorld.Log(" i=%s, 队员血量为0!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
+ continue
+ if not curTeamPlayer.GetVisible():
+ if isDead:
+ GameWorld.Log(" i=%s, 队员不可见!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
+ continue
+ if isDead:
+ GameWorld.Log(" i=%s, 队员坐标(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID()))
+ if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
+ return curTeamPlayer
+ else:
+ GameWorld.ErrLog("找不到该队伍: teamID=%s" % teamID)
+ return
+
+ def UpdateDropOwner(self, tick, ownerType=0, ownerID=0, isDead=False):
+
+ curNPC = self.__Instance
+ npcID = curNPC.GetNPCID()
+ dropOwnerType = GetDropOwnerType(curNPC)
+ if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family, ChConfig.DropOwnerType_Contend]:
+ #GameWorld.DebugLog("不需要展示掉落归属的NPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))
+ return
+
+ lastDropOwnerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
+ lastDropOwnerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
+
+ key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)
+ if lastDropOwnerID and (lastDropOwnerType != ownerType or lastDropOwnerID != ownerID):
+ GameWorld.Log("归属变更, 清除旧归属! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s"
+ % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID))
+ self.__DelDropOwnerBuff(dropOwnerType, lastDropOwnerType, lastDropOwnerID, tick)
+
+ killerDict, curTeam, hurtType, hurtID = {}, None, 0, 0
+
+ # 更新归属
+ curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerID, ownerID)
+ curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerType, ownerType)
+
+ if isDead:
+ GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))
+
+ # 刷新归属
+ if ownerType == ChConfig.Def_NPCHurtTypePlayer:
+ curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
+ if curPlayer:
+ playerID = curPlayer.GetPlayerID()
+ hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID
+ killerDict[playerID] = curPlayer
+ self.__AddDropOwnerPlayerBuff(curPlayer, tick)
+ if dropOwnerType == ChConfig.DropOwnerType_Contend:
+ curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, curNPC.GetID())
+
+ elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
+ curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
+ if not curTeam:
+ return
+
+ # 因为有击杀次数限制,所以不是所有的队员都可以获得归属,所以这里设置为特殊指定玩家掉落
+ hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0
+ if isDead:
+ GameWorld.Log("队伍成员数: %s" % (curTeam.GetMemberCount()))
+ refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+ for i in xrange(curTeam.GetMemberCount()):
+ curTeamPlayer = curTeam.GetMember(i)
+ if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
+ if isDead:
+ GameWorld.Log(" i=%s, 成员不存在!" % (i))
+ continue
+
+ if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \
+ and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
+ and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible():
+ self.__AddDropOwnerPlayerBuff(curTeamPlayer, tick)
+ killerDict[curTeamPlayer.GetPlayerID()] = curTeamPlayer
+ if isDead:
+ GameWorld.Log(" i=%s, 成员有归属权! memPlayerID=%s,背包剩余空格=%s"
+ % (i, curTeamPlayer.GetPlayerID(), ItemCommon.GetItemPackSpace(curTeamPlayer, IPY_GameWorld.rptItem)))
+
+ # 不同线、或者距离超出boss范围的队员不加归属buff
+ else:
+ isOk = BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
+ if isOk:
+ GameWorld.DebugLog("删除归属队员buff: teamID=%s,playerID=%s" % (ownerID, curTeamPlayer.GetPlayerID()))
+ if isDead:
+ GameWorld.Log(" i=%s, 成员无归属权! memPlayerID=%s,copyMapID=%s,pos(%s,%s),CheckKillNPCByCnt=%s"
+ % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetCopyMapID(),
+ curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(),
+ AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False)))
+
+ elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
+
+ hurtType, hurtID = ChConfig.Def_NPCHurtTypeFamily, ownerID
+ refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+ copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
+ for index in xrange(copyPlayerMgr.GetPlayerCount()):
+ player = copyPlayerMgr.GetPlayerByIndex(index)
+ if not player:
+ continue
+
+ # 归属仙盟 且 在boss区域内
+ if player.GetFamilyID() == ownerID and self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint) and player.GetVisible():
+ self.__AddDropOwnerPlayerBuff(player, tick)
+
+ else:
+ isOk = BuffSkill.DelBuffBySkillID(player, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
+ if isOk:
+ GameWorld.DebugLog("删除非归属仙盟成员buff: teamID=%s,playerID=%s" % (ownerID, player.GetPlayerID()))
+
+ if isDead:
+ #key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)
+ teamID = curTeam.GetTeamID() if curTeam else 0
+ if killerDict:
+ PyGameData.g_npcKillerInfo[key] = killerDict, curTeam, hurtType, hurtID
+ elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
+ PyGameData.g_npcKillerInfo[key] = {}, None, hurtType, hurtID
+
+ GameWorld.Log("Boss被击杀: npcID=%s,key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s"
+ % (npcID, key, killerDict.keys(), teamID, hurtType, hurtID))
+ return
+
+ def __AddDropOwnerPlayerBuff(self, curPlayer, tick):
+ curNPC = self.__Instance
+ findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]
+ if not findBuff:
+ SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
+ GameWorld.DebugLog("添加归属buff: playerID=%s" % curPlayer.GetPlayerID())
+ return
+
+ def __DelDropOwnerBuff(self, dropOwnerType, ownerType, ownerID, tick):
+
+ curNPC = self.__Instance
+ if ownerType == ChConfig.Def_NPCHurtTypePlayer:
+ curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
+ if not curPlayer:
+ return
+ GameWorld.DebugLog("删除归属玩家buff: playerID=%s" % (ownerID))
+ BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
+ if dropOwnerType == ChConfig.DropOwnerType_Contend:
+ curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, 0)
+
+ elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
+ curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
+ if not curTeam:
+ return
+ GameWorld.DebugLog("删除归属队伍buff: teamID=%s" % (ownerID))
+ for i in xrange(curTeam.GetMemberCount()):
+ curTeamPlayer = curTeam.GetMember(i)
+ if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
+ continue
+ BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
+ return
+
+ def DelayDropOwnerBuffDisappearTime(self):
+ ''' 延迟掉落归属buff消失时间 '''
+
+ curNPC = self.__Instance
+ ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
+ ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
+
+ if ownerType == ChConfig.Def_NPCHurtTypePlayer:
+ curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
+ if not curPlayer:
+ return
+ self.__SetDropOwnerBuffDisappearTime(curPlayer)
+
+ elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
+ curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
+ if not curTeam:
+ return
+ for i in xrange(curTeam.GetMemberCount()):
+ curTeamPlayer = curTeam.GetMember(i)
+ if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
+ continue
+ self.__SetDropOwnerBuffDisappearTime(curTeamPlayer)
+ elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
+ copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
+ for index in xrange(copyPlayerMgr.GetPlayerCount()):
+ player = copyPlayerMgr.GetPlayerByIndex(index)
+ if not player:
+ continue
+ self.__SetDropOwnerBuffDisappearTime(player)
+
+ return
+
+ def __SetDropOwnerBuffDisappearTime(self, curPlayer):
+ ''' 设置掉落归属buff消失时间 '''
+
+ curNPC = self.__Instance
+ findSkill = GameWorld.GetGameData().GetSkillBySkillID(ChConfig.Def_SkillID_DropOwnerBuff)
+ if not findSkill:
+ return
+
+ buffType = SkillCommon.GetBuffType(findSkill)
+ buffTuple = SkillCommon.GetBuffManagerByBuffType(curPlayer, buffType)
+ if buffTuple == ():
+ return
+
+ RemainTime = 10000 # 延迟10秒消失
+ tick = GameWorld.GetGameWorld().GetTick()
+
+ buffStateManager = buffTuple[0]
+ for index in xrange(buffStateManager.GetBuffCount()):
+ curBuff = buffStateManager.GetBuff(index)
+ buffSkill = curBuff.GetSkill()
+
+ if buffSkill.GetSkillTypeID() != ChConfig.Def_SkillID_DropOwnerBuff:
+ continue
+
+ if curNPC.GetID() != curBuff.GetOwnerID():
+ #GameWorld.DebugLog("非buff归属着,不设置消失时间!", curPlayer.GetPlayerID())
+ break
+
+ curBuff.SetCalcStartTick(tick)
+ curBuff.SetRemainTime(RemainTime)
+
+ # 通知buff刷新
+ buffStateManager.Sync_RefreshBuff(index, curBuff.GetRemainTime())
+ #GameWorld.DebugLog("掉落归属buff消失时间: RemainTime=%s" % (RemainTime), curPlayer.GetPlayerID())
+ break
+ return
+ ##--------------------------------------------- -----------------------------------------------
+
+def OnPlayerKillNPCPlayer(curPlayer, defender, tick):
+ ## 玩家击杀了NPC相关的玩家
+ contendNPCObjID = defender.GetDictByKey(ChConfig.Def_PlayerKey_ContendNPCObjID)
+ if contendNPCObjID:
+ curNPC = GameWorld.FindNPCByID(contendNPCObjID)
+ if not curNPC:
+ return
+ dropOwnerType = GetDropOwnerType(curNPC)
+ if dropOwnerType != ChConfig.DropOwnerType_Contend:
+ return
+ playerID = curPlayer.GetPlayerID()
+ GameWorld.DebugLog("玩家击杀竞争归属者! defPlayerID=%s,contendNPCObjID=%s,npcID=%s"
+ % (defender.GetPlayerID(), contendNPCObjID, curNPC.GetNPCID()), playerID)
+ npcControl = NPCControl(curNPC)
+ npcControl.UpdateDropOwner(tick, ChConfig.Def_NPCHurtTypePlayer, playerID, False)
+
+ return
+
#---------------------------------------------------------------------
def SendVirtualItemDrop(player, itemID, posX, posY, userDataStr):
#通知客户端假物品掉落
@@ -5139,21 +5543,6 @@
return max(value / pow(10, nlen), 1)
-Def_CollNPCCfg_Len = 10
-(
-Def_CollNPCCfg_CanTogether, # 是否允许同时采集
-Def_CollNPCCfg_SysMsgMark, # 不可同时采集提示
-Def_CollNPCCfg_CostItemInfo, # 采集消耗物品信息
-Def_CollNPCCfg_PrepareTime, # 采集时间毫秒
-Def_CollNPCCfg_ExpFormat, # 获得经验公式
-Def_CollNPCCfg_MoneyFormat, # 获得金币公式
-Def_CollNPCCfg_ZhenQi, # 获得的真气/魔魂
-Def_CollNPCCfg_GiveItemModeID, # 获得的物品信息模板编号
-Def_CollNPCCfg_NotCostItemNotify, # 消耗品不足提示
-Def_CollNPCCfg_LimitSysMsgMark, #采集上限提示
-) = range(Def_CollNPCCfg_Len)
-
-
def CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):
# 根据NPCID判断是否可以采集
@@ -5191,7 +5580,11 @@
npcID = curNPC.GetNPCID()
collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
if not collectNPCIpyData:
- GameWorld.DebugLog("非特定采集NPC...")
+ #GameWorld.DebugLog("非特定采集NPC...")
+ return False
+
+ if collectNPCIpyData.GetIsMissionCollectNPC():
+ #GameWorld.DebugLog("任务采集物暂不处理")
return False
if not CheckCanCollectByNPCID(curPlayer, npcID, collectNPCIpyData):
@@ -5294,6 +5687,10 @@
GameWorld.DebugLog(" 非特定采集NPC...npcID=%s" % npcID)
return
+ if collectNPCIpyData.GetIsMissionCollectNPC():
+ #GameWorld.DebugLog("任务采集物暂不处理")
+ return
+
PlayerState.DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, True)
if GameWorld.IsCrossServer():
@@ -5319,33 +5716,106 @@
DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)
return
+#// A2 34 自定义场景中获取采集奖励 #tagCMGetCustomSceneCollectAward
+#
+#struct tagCMGetCustomSceneCollectAward
+#{
+# tagHead Head;
+# DWORD NPCID; //采集的NPCID
+#};
+def OnGetCustomSceneCollectAward(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ npcID = clientData.NPCID
+ if not curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene):
+ GameWorld.DebugLog("非自定义场景中,无法获取定义采集奖励!")
+ return
+ collectNPCIpyData = IpyGameDataPY.GetIpyGameData("CollectNPC", npcID)
+ if collectNPCIpyData:
+ DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData)
+ return
+
def DoGiveCollectNPCAward(curPlayer, npcID, collectNPCIpyData, collectCnt=1):
GameWorld.DebugLog("给采集奖励: npcID=%s,collectCnt=%s" % (npcID, collectCnt))
if collectCnt <= 0:
return
+
+ if collectNPCIpyData.GetIsMissionCollectNPC():
+ #GameWorld.DebugLog("任务采集物暂不处理")
+ return
+ isMaxTime = False # 是否达到了采集最大次数
limitMaxTime = collectNPCIpyData.GetMaxCollectCount()
if limitMaxTime > 0:
todayCollTime = GetTodayCollectCount(curPlayer, npcID)
canCollectCnt = max(0, limitMaxTime - todayCollTime)
collectCnt = min(collectCnt, canCollectCnt)
if collectCnt <= 0:
- GameWorld.DebugLog(" 该NPC已达到最大采集次数: todayCollTime=%s,limitMaxTime=%s" % (todayCollTime, limitMaxTime))
+ GameWorld.DebugLog(" 该NPC已达到最大采集次数: npcID=%s,todayCollTime=%s,limitMaxTime=%s" % (npcID, todayCollTime, limitMaxTime))
return
- updCollTime = todayCollTime + collectCnt
+ curCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
+ updCollTime = curCollTime + collectCnt
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
SyncCollNPCTime(curPlayer, [npcID])
- GameWorld.DebugLog(" 增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime))
-
- giveItemList = collectNPCIpyData.GetCollectAward()
- if giveItemList:
- itemID, itemCount, isAuctionItem = giveItemList
- ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])
+ GameWorld.DebugLog(" 增加采集次数: npcID=%s,todayCollTime=%s,curCollTime=%s,updCollTime=%s" % (npcID, todayCollTime, curCollTime, updCollTime))
+ isMaxTime = todayCollTime + collectCnt >= limitMaxTime
+
+ awardItemList = []
+ collectAwardCfg = collectNPCIpyData.GetCollectAward()
+ collectAppointAwardCfg = collectNPCIpyData.GetCollectAppointAward()
+ if collectAppointAwardCfg:
+ collTotalTime = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID) + 1, ChConfig.Def_UpperLimit_DWord)
+ if collTotalTime in collectAppointAwardCfg:
+ awardItemList.append(collectAppointAwardCfg[collTotalTime])
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTimeTotal % npcID, collTotalTime)
+ GameWorld.DebugLog(" 采集次数定制奖励: collTotalTime=%s,awardItemList=%s" % (collTotalTime, awardItemList))
+
+ if not awardItemList:
+ alchemyDiffLV = collectNPCIpyData.GetAlchemyDiffLV()
+ giveItemWeightList = []
+ if alchemyDiffLV:
+ curAlchemyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_AlchemyLV)
+ for itemInfo in collectAwardCfg:
+ itemID = itemInfo[1][0]
+ itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
+ if not itemData:
+ continue
+ if ItemCommon.GetItemClassLV(itemData) > curAlchemyLV + alchemyDiffLV:
+ continue
+ giveItemWeightList.append(itemInfo)
+ else:
+ giveItemWeightList = collectAwardCfg
+
+ GameWorld.DebugLog(" 常规采集物品权重列表: alchemyDiffLV=%s,collectAwardCfg=%s,giveItemWeightList=%s" % (alchemyDiffLV, collectAwardCfg, giveItemWeightList))
+ giveItemInfo = GameWorld.GetResultByWeightList(giveItemWeightList)
+ if giveItemInfo:
+ awardItemList.append(giveItemInfo)
+
+ GameWorld.DebugLog(" 最终采集奖励: awardItemList=%s" % awardItemList)
+ if awardItemList:
+ for itemID, itemCount, isAuctionItem in awardItemList:
+ ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem])
+ if collectNPCIpyData.GetNotifyCollectResult():
+ awardPack = ChPyNetSendPack.tagMCCollectAwardItemInfo()
+ awardPack.CollectNPCID = npcID
+ for itemID, itemCount, isAuctionItem in awardItemList:
+ awardItem = ChPyNetSendPack.tagMCCollectAwardItem()
+ awardItem.ItemID = itemID
+ awardItem.Count = itemCount
+ awardItem.IsAuctionItem = isAuctionItem
+ awardPack.AwardItemList.append(awardItem)
+ awardPack.Count = len(awardPack.AwardItemList)
+ NetPackCommon.SendFakePack(curPlayer, awardPack)
+ else:
+ GameWorld.ErrLog("采集物品没有奖励!npcID=%s" % (npcID))
#采集成就
PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, collectCnt, [npcID])
#SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
+
+ if isMaxTime:
+ GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer)
+
return
## 采集结果同步
@@ -5392,11 +5862,20 @@
def CollNPCTimeOnDay(curPlayer):
## 采集NPCOnDay处理
+ DoResetCollectNPCTimeByType(curPlayer, [1])
+ return
+
+def DoResetCollectNPCTimeByType(curPlayer, resetTypeList=[]):
+ '''重置采集物采集次数
+ 重置类型: 0-不重置,1-每日5点,12-灵草园重置,14-仙草园重置
+ '''
resetNPCIDList = []
ipyDataMgr = IpyGameDataPY.IPY_Data()
for index in xrange(ipyDataMgr.GetCollectNPCCount()):
ipyData = ipyDataMgr.GetCollectNPCByIndex(index)
npcID = ipyData.GetNPCID()
+ if resetTypeList and ipyData.GetCollectResetType() not in resetTypeList:
+ continue
if not ipyData.GetMaxCollectCount():
continue
if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID):
@@ -5405,6 +5884,7 @@
resetNPCIDList.append(npcID)
if resetNPCIDList:
+ #GameWorld.DebugLog("重置采集次数: resetTypeList=%s,resetNPCIDList=%s" % (resetTypeList, resetNPCIDList), curPlayer.GetPlayerID())
SyncCollNPCTime(curPlayer, resetNPCIDList)
return
@@ -5697,3 +6177,45 @@
sendPack.Value = speed
curNPC.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
return
+
+def UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount=0):
+ ## 更新玩家攻击NPC次数
+ GameWorld.DebugLog("更新玩家攻击NPC次数: npcID=%s,attackCount=%s,maxCount=%s" % (npcID, attackCount, maxCount))
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCAttackCount % npcID, attackCount)
+
+ if GameWorld.IsCrossServer():
+ serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
+ msgInfo = {"PlayerID":curPlayer.GetPlayerID(), "NPCID":npcID, "AttackCount":attackCount, "MaxCount":maxCount}
+ GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_NPCAttackCount, msgInfo, [serverGroupID])
+ else:
+ SyncNPCAttackCount(curPlayer, [npcID])
+ if attackCount and attackCount >= maxCount:
+ GameLogic_CrossGrassland.DoCheckUpdateGrasslandEnd(curPlayer)
+ return
+
+def CrossServerMsg_NPCAttackCount(curPlayer, msgData):
+ ## 收到跨服服务器同步的攻击NPC次数
+ npcID = msgData["NPCID"]
+ attackCount = msgData["AttackCount"]
+ maxCount = msgData["MaxCount"]
+ UpdateNPCAttackCount(curPlayer, npcID, attackCount, maxCount)
+ return
+
+def SyncNPCAttackCount(curPlayer, npcIDList):
+ ## 同步NPC攻击次数
+ if not npcIDList:
+ return
+
+ clientPack = ChPyNetSendPack.tagMCNPCAttackCountInfo()
+ for npcID in npcIDList:
+ attackCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCAttackCount % npcID)
+ atkCountObj = ChPyNetSendPack.tagMCNPCAttackCount()
+ atkCountObj.NPCID = npcID
+ atkCountObj.AttackCount = attackCount
+ clientPack.NPCAttackCountList.append(atkCountObj)
+ clientPack.Count = len(clientPack.NPCAttackCountList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
+
+
\ No newline at end of file
--
Gitblit v1.8.0