From 26a116683bd08fe6705f12d6386068a801b702b9 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 03 四月 2020 18:11:33 +0800
Subject: [PATCH] 4475 【主干】免费送的3个仙盟,概率随机重名导致无法创建(手动创建与系统随机仙盟名相同的默认当做创建该系统仙盟,防止重复)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py | 169 ++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 133 insertions(+), 36 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
index 7e39069..73a3458 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
@@ -30,6 +30,7 @@
import ShareDefine
import PlayerTeam
import NPCCommon
+import FBCommon
import ChConfig
import time
@@ -44,6 +45,7 @@
self.__hurtType = ChConfig.Def_NPCHurtTypePlayer # 均默认是玩家
self.__hurtName = ""
self.__hurtValue = 0
+ self.__isFriend = 0
return
def GetValueID(self): return self.__hurtID
@@ -54,6 +56,8 @@
def SetHurtName(self, hurtName): self.__hurtName = hurtName
def GetHurtValue(self): return self.__hurtValue
def SetHurtValue(self, hurtValue): self.__hurtValue = hurtValue
+ def GetIsFriend(self): return self.__isFriend
+ def SetIsFriend(self, isFriend): self.__isFriend = isFriend
class PlayerHurtList():
''' 伤血列表, 类似 IPY_GameObj.IPY_PlayerHurtList
@@ -71,6 +75,9 @@
self.__hurtSortList = []
self.__hurtDict = {} # 伤血列表实例字典,实际的NPC伤血列表实例,可能不是玩家{(hurtID, hurtType):HurtValueObj, ...}
+
+ self.__assistAwardItemID = 0 # 协助奖励礼盒ID
+ self.__assistAwardResult = {} # {playerID:{assistPlayerID:{协助玩家信息数据字典}, ...}}
return
def Clear(self):
@@ -87,11 +94,11 @@
def OnDelete(self):
# 删除伤血列表,NPC死亡调用
- cancelPlayerIDList = self.__noAssitPlayerIDDict.keys()
- if cancelPlayerIDList:
+ noAssistPlayerIDList = self.__noAssitPlayerIDDict.keys()
+ if noAssistPlayerIDList:
mapID = GameWorld.GetMap().GetMapID()
- queryData = [mapID, self.lineID, self.npcID, self.objID, "OnBossDead", cancelPlayerIDList]
- PlayerAssist.QueryGameServer_PlayerAssist(0, "OnCancelBossRequestAssist", queryData)
+ queryData = [mapID, self.lineID, self.npcID, self.objID, noAssistPlayerIDList, self.__assistAwardItemID, self.__assistAwardResult]
+ PlayerAssist.QueryGameServer_PlayerAssist(0, "OnBossAssistOver", queryData)
return
@@ -124,7 +131,7 @@
hurtPlayer.SetHurtName(playerName)
return hurtPlayer
- def AddAssistPlayer(self, assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID):
+ def AddAssistPlayer(self, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID):
## 添加助战玩家
# @param assistPlayerID: 协助玩家ID
# @param tagPlayerID: 目标玩家ID,即发布协助的玩家ID
@@ -138,8 +145,8 @@
% (assistPlayerID, tagPlayerID), self.npcID, self.lineID)
return
- GameWorld.DebugLog("新增协助玩家: assistPlayerID=%s,tagPlayerID=%s,tagTeamID=%s"
- % (assistPlayerID, tagPlayerID, tagTeamID), self.npcID, self.lineID)
+ GameWorld.DebugLog("新增协助玩家: assistPlayerID=%s,tagPlayerID=%s,tagTeamID=%s,isFriend=%s"
+ % (assistPlayerID, tagPlayerID, tagTeamID, isFriend), self.npcID, self.lineID)
if assistPlayerID in self.__noAssitPlayerIDDict:
GameWorld.DebugLog("原来为常规玩家,需要先删除!", self.npcID, self.lineID)
@@ -150,6 +157,8 @@
assistPlayerIDList.append(assistPlayerID)
self.__assistPlayerIDDict[assistPlayerID] = tagPlayerID
+ assistHurtPlayer = self.__GetHurtPlayer(assistPlayerID, assistPlayerName)
+ assistHurtPlayer.SetIsFriend(isFriend)
GameWorld.DebugLog(" self.__noAssitPlayerIDDict=%s" % (self.__noAssitPlayerIDDict), self.npcID, self.lineID)
GameWorld.DebugLog(" self.__assistPlayerIDDict=%s" % (self.__assistPlayerIDDict), self.npcID, self.lineID)
return
@@ -177,9 +186,8 @@
# 地图删除的同步GameServer
if isMapServerDel:
mapID = GameWorld.GetMap().GetMapID()
- cancelPlayerIDList = [playerID]
- queryData = [mapID, self.lineID, self.npcID, self.objID, reason, cancelPlayerIDList]
- PlayerAssist.QueryGameServer_PlayerAssist(0, "OnCancelBossRequestAssist", queryData)
+ queryData = [mapID, self.lineID, self.npcID, self.objID, reason]
+ PlayerAssist.QueryGameServer_PlayerAssist(playerID, "OnCancelBossRequestAssist", queryData)
# 协助玩家
elif playerID in self.__assistPlayerIDDict:
@@ -423,12 +431,10 @@
# @return: atkPlayer, hurtID, hurtType
curNPC = self.curNPC
- if not self.__hurtDict:
- return
if not isDead:
if refreshInterval and tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < refreshInterval:
- return self.__GetAtkObjByHurtList()
+ return self.__GetAtkObjByHurtList(isDead)
curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick)
@@ -464,7 +470,7 @@
isInHurt = self.__hurtSortList != []
curNPC.SetDict(ChConfig.Def_NPC_Dict_InHurtProtect, isInHurt)
- return self.__GetAtkObjByHurtList()
+ return self.__GetAtkObjByHurtList(isDead)
def __UnAssistPlayerHurtValidLogic(self, playerID, refreshPoint, tick):
## 非协助玩家伤血有效性检查逻辑
@@ -580,7 +586,7 @@
return
- def __GetAtkObjByHurtList(self):
+ def __GetAtkObjByHurtList(self, isDead):
'''第一个可攻击的最大伤血对象,也是实际的归属者或队伍
因为玩家伤血掉线、死亡有一定时间的保留机制,故最大伤血不一定是可攻击目标(归属者)
注意: 该规则必须与最终算归属的规则一致,不然可能导致归属错乱
@@ -590,7 +596,7 @@
atkPlayer, atkHurtType, atkHurtID = None, 0, 0
curNPC = self.curNPC
refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
- for hurtObj in self.__hurtSortList:
+ for rank, hurtObj in enumerate(self.__hurtSortList, 1):
hurtID = hurtObj.GetValueID()
hurtType = hurtObj.GetValueType()
@@ -613,6 +619,7 @@
else:
continue
+ playerDisableReason = {}
maxHurtValue = 0
for playerID in playerIDList:
@@ -621,15 +628,19 @@
continue
if player.GetHP() <= 0 or player.GetPlayerAction() == IPY_GameWorld.paDie:
+ playerDisableReason[playerID] = "dead"
continue
if not player.GetVisible() or player.GetSightLevel() != curNPC.GetSightLevel():
+ playerDisableReason[playerID] = "no visible or sightLevel different"
continue
if not self.__GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):
+ playerDisableReason[playerID] = "not in boss area"
continue
if playerID not in self.__hurtPlayerDict:
+ playerDisableReason[playerID] = "no hurt"
continue
hurtPlayer = self.__hurtPlayerDict[playerID]
hurtValue = hurtPlayer.GetHurtValue()
@@ -640,6 +651,9 @@
if maxHurtValue:
return atkPlayer, atkHurtType, atkHurtID
+ if rank == 1 and isDead:
+ GameWorld.Log("boss死亡时,第一名团队没有归属权! playerDisableReason=%s" % playerDisableReason)
+
return atkPlayer, atkHurtType, atkHurtID
def __GetIsInRefreshPoint(self, curPosX, curPosY, refreshPoint):
@@ -710,34 +724,80 @@
''' 执行协助奖励逻辑
'''
- liheItemID = 2244 # 感谢礼盒物品ID,暂山寨,感谢系统再修改
+ self.__assistAwardResult = {}
+ liheItemID, assistMoney = 0, 0
+ mapAssistGiftDict = IpyGameDataPY.GetFuncEvalCfg("AssistAward", 2, {})
+ mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
+ if str(mapID) in mapAssistGiftDict:
+ liheItemID, assistMoney = mapAssistGiftDict[str(mapID)]
+ else:
+ killBossCntLimitDict = IpyGameDataPY.GetFuncEvalCfg('KillBossCntLimit')
+ index = GameWorld.GetDictValueByKey(killBossCntLimitDict, self.npcID)
+ if index == None:
+ return
+ bossAssistGiftDict = IpyGameDataPY.GetFuncEvalCfg("AssistAward", 1, {})
+ if str(index) not in bossAssistGiftDict:
+ GameWorld.DebugLog("该boss没有协助额外奖励!index=%s" % index, self.npcID)
+ return
+ liheItemID, assistMoney = bossAssistGiftDict[str(index)]
+
+ if not liheItemID or not assistMoney:
+ GameWorld.DebugLog("该副本或boss没有协助额外奖励!mapID=%s" % (mapID), self.npcID)
+ return
+ self.__assistAwardItemID = liheItemID
+
+ fbType = GameWorld.GetMap().GetMapFBTypeByMapID(mapID)
GameWorld.DebugLog("执行协助奖励逻辑", self.npcID, self.lineID)
copyPlayerManager = GameWorld.GetMapCopyPlayerManager()
for playerID, assistPlayerIDList in self.__noAssitPlayerIDDict.items():
if not assistPlayerIDList:
- GameWorld.DebugLog("发布方没有发布协助,不给奖励: playerID=%s" % playerID, self.npcID, self.lineID)
+ GameWorld.DebugLog("发布方没有发布协助,不处理: playerID=%s" % playerID, self.npcID, self.lineID)
continue
- player = copyPlayerManager.FindPlayerByID(playerID)
- if player:
- GameWorld.DebugLog("发布方给感谢礼盒奖励: playerID=%s" % playerID, self.npcID, self.lineID)
- ItemControler.GivePlayerItemOrMail(player, [[liheItemID, 1, 0]])
- else:
- GameWorld.DebugLog("发布方离线或不在本地图,不给感谢礼盒奖励: playerID=%s" % playerID, self.npcID, self.lineID)
-
+ noAssistPlayer = copyPlayerManager.FindPlayerByID(playerID)
+
+ assistAwardPlayerDict = {}
+ # 即使发布方不在线,协助方完成后也可获得活跃令奖励,只是不一定获得礼盒感谢奖励(礼盒感谢奖励需双方都在线)
for assistPlayerID in assistPlayerIDList:
assistHurtPlayer = self.__GetHurtPlayer(assistPlayerID)
if not assistHurtPlayer.GetHurtValue():
GameWorld.DebugLog("协助方没有输出,不给奖励: assistPlayerID=%s" % assistPlayerID, self.npcID, self.lineID)
continue
- assPlayer = copyPlayerManager.FindPlayerByID(assistPlayerID)
- if not assPlayer:
+ assistPlayer = copyPlayerManager.FindPlayerByID(assistPlayerID)
+ if not assistPlayer:
GameWorld.DebugLog("协助方离线或不在本地图,不给活跃令奖励: assistPlayerID=%s" % assistPlayerID, self.npcID, self.lineID)
continue
- GameWorld.DebugLog("协助方给活跃令奖励: assistPlayerID=%s" % assistPlayerID, self.npcID, self.lineID)
- PlayerControl.GiveMoney(assPlayer, ShareDefine.TYPE_Price_FamilyActivity, 35)
-
+ isFriend = assistHurtPlayer.GetIsFriend()
+ assistMoneyType = ShareDefine.TYPE_Price_FamilyActivity
+ addAssistMoney = PlayerAssist.AddTodayAssistMoney(assistPlayer, assistMoneyType, assistMoney, isFriend)
+ GameWorld.DebugLog("协助方给活跃令奖励: assistPlayerID=%s,assistMoney=%s,isFriend=%s,addAssistMoney=%s"
+ % (assistPlayerID, assistMoney, isFriend, addAssistMoney), self.npcID, self.lineID)
+ if fbType == IPY_GameWorld.fbtNull:
+ PlayerControl.NotifyCode(assistPlayer, "AssistSuccess")
+ else:
+ overDict = {FBCommon.Over_isAssist:1, FBCommon.Over_money:FBCommon.GetJsonMoneyList({assistMoneyType:addAssistMoney}),
+ FBCommon.Over_itemInfo:[]}
+ FBCommon.NotifyFBOver(assistPlayer, mapID, PlayerControl.GetFBFuncLineID(assistPlayer), 1, overDict)
+ assistPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, 10000, True)
+
+ if noAssistPlayer:
+ todayGiftCount = assistPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GetThanksGiftCount % liheItemID)
+ assistAwardPlayerDict[assistPlayerID] = {"PlayerName":assistPlayer.GetPlayerName(), "Job":assistPlayer.GetJob(),
+ "LV":assistPlayer.GetLV(), "RealmLV":assistPlayer.GetOfficialRank(),
+ "TodayGiftCount":todayGiftCount}
+
+ notifyParam = [assistPlayer.GetPlayerName(), noAssistPlayer.GetPlayerName(), mapID, self.curNPC.GetLV(), self.npcID]
+ PlayerControl.FamilyNotify(assistPlayer.GetFamilyID(), "AssistBossFinish", notifyParam)
+
+ if not noAssistPlayer or not assistAwardPlayerDict:
+ GameWorld.DebugLog("发布方离线或无有效协助玩家在线,不给感谢礼盒奖励: playerID=%s" % playerID, self.npcID, self.lineID)
+ continue
+
+ GameWorld.DebugLog("发布方给感谢礼盒奖励: playerID=%s" % playerID, self.npcID, self.lineID)
+ ItemControler.GivePlayerItemOrMail(noAssistPlayer, [[liheItemID, 1, 0]])
+ self.__assistAwardResult[playerID] = assistAwardPlayerDict
+
return
def __CmpHurtValue(self, hurtObjA, hurtObjB):
@@ -778,13 +838,15 @@
bossHurtInfoPack.HurtValueList = hurtValueList
bossHurtInfoPack.HurtCount = len(hurtValueList)
+ curNPC = self.curNPC
assistHurtValueListDict = {}
copyPlayerManager = GameWorld.GetMapCopyPlayerManager()
for playerID in syncPlayerIDList:
player = copyPlayerManager.FindPlayerByID(playerID)
if not player:
continue
-
+ if not player.CanSeeOther(curNPC):
+ continue
if playerID in self.__noAssitPlayerIDDict:
assTagPlayerID = playerID
elif playerID in self.__assistPlayerIDDict:
@@ -825,9 +887,17 @@
def OnPlayerLeaveMap(curPlayer):
## 玩家离开地图处理
+ mapID = curPlayer.GetMapID()
+ mapType = GameWorld.GetMap().GetMapFBType()
+ changeMapID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ChangeMapID)
+ changeLineID = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ChangeLineID)
+
playerID = curPlayer.GetPlayerID()
for hurtList in PyGameData.g_npcHurtDict.values():
if hurtList.IsNoAssistPlayer(playerID) or hurtList.IsAssistPlayer(playerID):
+ if mapType == IPY_GameWorld.fbtNull and mapID == changeMapID and changeLineID == hurtList.lineID:
+ #GameWorld.DebugLog("玩家同地图切线,当前伤血lineID为目标线路,不清伤血!changeLineID=%s" % changeLineID, playerID)
+ continue
GameWorld.DebugLog("玩家离开地图, 删除boss伤血玩家!npcID=%s" % (hurtList.npcID), playerID)
hurtList.DelHurtPlayer(playerID, "LeaveMap")
break
@@ -863,11 +933,19 @@
defendHurtList.Clear()
return
+def GetBossLineID(npcID):
+ sealDemonIpyData = IpyGameDataPY.GetIpyGameDataNotLog("SealDemon", npcID)
+ if sealDemonIpyData:
+ lineID = sealDemonIpyData.GetLineID()
+ else:
+ lineID = GameWorld.GetGameWorld().GetLineID()
+ return lineID
+
def DeletePlayerHurtList(curNPC):
## 删除伤血列表
- lineID = GameWorld.GetGameWorld().GetLineID()
objID = curNPC.GetID()
npcID = curNPC.GetNPCID()
+ lineID = GetBossLineID(npcID)
key = (lineID, objID, npcID)
if key in PyGameData.g_npcHurtDict:
hurtList =PyGameData.g_npcHurtDict.pop(key)
@@ -877,9 +955,9 @@
def GetPlayerHurtList(curNPC):
## 获取伤血列表,可能为None
- lineID = GameWorld.GetGameWorld().GetLineID()
objID = curNPC.GetID()
npcID = curNPC.GetNPCID()
+ lineID = GetBossLineID(npcID)
return GetPlayerHurtListEx(lineID, objID, npcID)
def GetPlayerHurtListEx(lineID, objID, npcID):
## 获取伤血列表,可能为None
@@ -888,10 +966,12 @@
if key not in PyGameData.g_npcHurtDict:
## 只统计最大伤血归属的boss
npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
- if not npcData:
+ if not npcData or not ChConfig.IsGameBoss(npcData):
return defendHurtList
- if not npcData.GetIsBoss() or NPCCommon.GetDropOwnerType(npcData) != ChConfig.DropOwnerType_MaxHurt:
- return defendHurtList
+ if NPCCommon.GetDropOwnerType(npcData) != ChConfig.DropOwnerType_MaxHurt:
+ mapID = GameWorld.GetMap().GetMapID()
+ if mapID not in [ChConfig.Def_FBMapID_SealDemon]:
+ return defendHurtList
defendHurtList = PlayerHurtList(lineID, objID, npcID)
PyGameData.g_npcHurtDict[key] = defendHurtList
defendHurtList = PyGameData.g_npcHurtDict[key]
@@ -939,6 +1019,8 @@
return True
def RefreshHurtList(curNPC, tick, refreshInterval=3000, isDead=False):
+ ## 刷新伤血列表
+ # @return: atkPlayer, ownerType, ownerID
defendHurtList = GetPlayerHurtList(curNPC)
if not defendHurtList:
return
@@ -951,3 +1033,18 @@
return False
return defendHurtList.IsAssistPlayer(playerID)
+def CheckPlayerCanAttackFBNPC(curPlayer, curNPC, mapID, isNotify=False):
+ ## 检查玩家可否攻击有副本次数的NPC
+ enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)
+ if enterCnt < FBCommon.GetEnterFBMaxCnt(curPlayer, mapID):
+ return True
+
+ # 没有次数的,如果是助战玩家也可攻击
+ if IsAssistPlayer(curPlayer.GetPlayerID(), curNPC):
+ return True
+
+ if isNotify:
+ PlayerControl.NotifyCode(curPlayer, "AttackFBBossLimit")
+
+ return False
+
--
Gitblit v1.8.0