From bd61f5e92fad5dc02f693747fde8fdb86ee01c5c Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期五, 06 十二月 2019 20:46:52 +0800 Subject: [PATCH] 8346 【恺英】【后端】协助系统(初版,可完成协助完整流程,增加新NPC伤血管理,支持协助、支持超过20亿伤害) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 338 +++---------------------------------------------------- 1 files changed, 23 insertions(+), 315 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 39c9ca2..3c88207 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -53,6 +53,7 @@ import PlayerNewFairyCeremony import GameLogic_CrossGrassland import PlayerWeekParty +import NPCHurtManager import PlayerActLogin import FamilyRobBoss import IpyGameDataPY @@ -2271,6 +2272,7 @@ AttackCommon.ClearTeamPlayerHurtValue(curNPC) # 清除自定义伤血列表 #BossHurtMng.ClearHurtValueList(curNPC) + NPCHurtManager.DeletePlayerHurtList(curNPC) if curNPC.GetType() == ChConfig.ntRobot: lineID = GameWorld.GetGameWorld().GetLineID() lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {}) @@ -2393,7 +2395,6 @@ # @remarks 类初始化 def __init__(self, iNPC): self.__Instance = iNPC - self.__MaxHurtPlayer = None # 最大伤血者,队伍取队长 self.__LastHurtPlayer = None # 最后一击的玩家 self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致 self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者 @@ -3198,231 +3199,6 @@ npcHurtList.Clear() return True - def __IsBossHurtOfflineProtect(self, refreshPoint, playerID, tick): - ## boss伤血是否掉线保护中 - # 是否离线超过3分钟,下线坐标是否不在boss区域等 - leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID) - leavePos = PlayerControl.GetPlayerLeaveServerPos(playerID) - if not leaveTick or not leavePos: - GameWorld.DebugLog("玩家不在本地图或已长久离线!清除该伤血!playerID=%s" % playerID) - return False - - if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime: - GameWorld.DebugLog("本地图离线玩家超过保护时长!清除该伤血!playerID=%s,tick=%s,leaveTick=%s" % (playerID, tick, leaveTick)) - return False - - if not self.GetIsInRefreshPoint(leavePos[0], leavePos[1], refreshPoint): - GameWorld.DebugLog("本地图离线玩家不在保护区域内!playerID=%s,leavePos=%s" % (playerID, leavePos)) - return False - - return True - - def __IsClearPlayerHurt(self, hurtPlayer, refreshPoint, hurtID, tick): - if hurtPlayer == None: - if not self.__IsBossHurtOfflineProtect(refreshPoint, hurtID, tick): - return True - - #GameWorld.DebugLog("本地图离线玩家伤血值保护中!playerID=%s" % (hurtID)) - return False - - #if hurtPlayer.GetHP() <= 0: - # GameWorld.DebugLog("伤血玩家血量为0,清除该伤血!playerID=%s" % hurtID) - # return True - - curNPC = self.__Instance - if hurtPlayer.GetInitOK() and (not hurtPlayer.GetVisible() or hurtPlayer.GetSightLevel() != curNPC.GetSightLevel()): - GameWorld.DebugLog("伤血玩家不可见,清除该伤血!playerID=%s" % hurtID) - return True - - if not self.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint): - GameWorld.DebugLog("伤血玩家不在boss范围里,清除该伤血!playerID=%s" % hurtID) - return True - - if hurtPlayer.GetTeamID(): - # 这种情况一般是玩家未加入队伍前对该NPC有伤血,加入到某个队伍后,将该伤害转移到队伍中 - return True - - if hurtPlayer.GetHP() <= 0 or hurtPlayer.GetPlayerAction() == IPY_GameWorld.paDie: - deadTime = hurtPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime) - if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1): - #GameWorld.DebugLog("伤血玩家死亡超过伤血保护时长,清除该伤血!playerID=%s" % hurtID) - return True - - #GameWorld.DebugLog("正常玩家伤血保护中!playerID=%s" % hurtID) - return False - - def __GetTeamHurtNPCPlayerIDList(self, refreshPoint, teamID, tick): - - curNPC = self.__Instance - teamHurtPlayerIDList = [] - # 如果没有在线队员在有效范围内,则进一步判断离线队员是否有伤血保护中的 - playerMgr = GameWorld.GetPlayerManager() - copyMapID = GameWorld.GetGameWorld().GetCopyMapID() - mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID) # 因为需要判断离线队员,所以只能用含离线的队伍缓存 - for playerID in mapTeamPlayerIDList: - - curTeamPlayer = playerMgr.FindPlayerByID(playerID) - if curTeamPlayer: - if curTeamPlayer.GetCopyMapID() != copyMapID: - #GameWorld.DebugLog("队员不在本线路,不计!playerID=%s" % playerID) - continue - - if curTeamPlayer.GetInitOK() and (not curTeamPlayer.GetVisible() or curTeamPlayer.GetSightLevel() != curNPC.GetSightLevel()): - #GameWorld.DebugLog("队员不可见,不计!playerID=%s" % playerID) - continue - - if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie: - deadTime = curTeamPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime) - if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1): - #GameWorld.DebugLog("伤血队员死亡超过伤血保护时长,不计!playerID=%s" % playerID) - continue - - #if curTeamPlayer.GetHP() > 0 and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint): - if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \ - and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False): - #GameWorld.DebugLog("有队员在boss范围内,保留队伍伤血!teamID=%s,playerID=%s" % (teamID, curTeamPlayer.GetPlayerID())) - teamHurtPlayerIDList.append(playerID) - else: - if self.__IsBossHurtOfflineProtect(refreshPoint, playerID, tick): - #GameWorld.DebugLog("有队员对boss离线伤血保护中!teamID=%s,playerID=%s" % (teamID, playerID)) - teamHurtPlayerIDList.append(playerID) - - if not teamHurtPlayerIDList: - GameWorld.DebugLog("伤血队伍没有符合条件的队员在boss区域内,清除该伤血!teamID=%s,mapTeamPlayerIDList=%s" % (teamID, mapTeamPlayerIDList)) - return teamHurtPlayerIDList - - def RefreshHurtList(self, tick, refreshInterval=3000): - ## 刷新伤血列表 - # @return: 可攻击的最大伤血数值对象 IPY_PlayerHurtValue - - curNPC = self.__Instance - if not curNPC.GetIsBoss() or GetDropOwnerType(curNPC) != ChConfig.DropOwnerType_MaxHurt: - return - - npcHurtList = curNPC.GetPlayerHurtList() - if tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < (refreshInterval): - if npcHurtList.GetHurtCount(): - return self.__GetAtkObjByHurtList(npcHurtList) - return - curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick) - - hurtPlayerDict = {} # {playerID:teamID, ...} - refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex()) - hurtCount = npcHurtList.GetHurtCount() - isInHurt = 0 - for index in xrange(hurtCount): - #获得伤血对象 - hurtObj = npcHurtList.GetHurtAt(index) - hurtType = hurtObj.GetValueType() - hurtID = hurtObj.GetValueID() - hurtValue = hurtObj.GetHurtValue() - if not hurtID: - continue - - # Clear()只会把伤血类型及数值重置为0,不会清除该伤血数值对象 - - if hurtType == ChConfig.Def_NPCHurtTypePlayer: - hurtPlayer = GameWorld.GetObj(hurtID, IPY_GameWorld.gotPlayer) - if self.__IsClearPlayerHurt(hurtPlayer, refreshPoint, hurtID, tick): - hurtObj.Clear() - teamID = 0 if not hurtPlayer else hurtPlayer.GetTeamID() - if teamID: - GameWorld.DebugLog("加入队伍,之气的伤血转移到队伍中!playerID=%s,teamID=%s" % (hurtID, teamID)) - AttackCommon.AddHurtValue(curNPC, teamID, ChConfig.Def_NPCHurtTypeTeam, hurtValue) - else: - isInHurt = 1 - hurtPlayerDict[hurtID] = 0 - - elif hurtType == ChConfig.Def_NPCHurtTypeTeam: - teamHurtPlayerIDList = self.__GetTeamHurtNPCPlayerIDList(refreshPoint, hurtID, tick) - if not teamHurtPlayerIDList: - hurtObj.Clear() - else: - isInHurt = 1 - for tPlayerID in teamHurtPlayerIDList: - hurtPlayerDict[tPlayerID] = hurtID - - mapID = GameWorld.GetMap().GetMapID() - if IsMapNeedBossShunt(mapID): - self.__UpdBossShuntInfo(mapID, hurtPlayerDict, tick) - - #GameWorld.DebugLog("RefreshHurtList, hurtCount=%s,isInHurt=%s" % (hurtCount, isInHurt)) - npcHurtList.Sort() - curNPC.SetDict(ChConfig.Def_NPC_Dict_InHurtProtect, isInHurt) - - if hurtCount: - # 排序后的,第一个可攻击的最大伤血对象 - return self.__GetAtkObjByHurtList(npcHurtList) - return - - def __UpdBossShuntInfo(self, mapID, hurtPlayerDict, tick): - ## 更新本地图线路boss分流信息 - curNPC = self.__Instance - npcID = curNPC.GetNPCID() - lineID = GameWorld.GetGameWorld().GetLineID() - key = (mapID, lineID) - shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {}) - - shuntChange = False - for playerID, shuntInfo in shuntPlayerDict.items(): - bossID, teamID, relatedTick = shuntInfo - if bossID != npcID: - # 不是该boss的伤害不处理 - continue - - # 还在伤血中 - if playerID in hurtPlayerDict: - newTeamID = hurtPlayerDict[playerID] - if newTeamID != teamID: - shuntPlayerDict[playerID] = [npcID, newTeamID, 0] - shuntChange = True - GameWorld.DebugLog("boss分流 -> 玩家对该boss的伤害变更队伍!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" - % (playerID, npcID, teamID, newTeamID), lineID) - elif relatedTick: - shuntPlayerDict[playerID] = [npcID, newTeamID, 0] - shuntChange = True - GameWorld.DebugLog("boss分流 -> 玩家对该boss的关联状态转为伤害状态!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" - % (playerID, npcID, teamID, newTeamID), lineID) - - # 不在伤血中,更新关联tick - elif not relatedTick: - shuntPlayerDict[playerID] = [npcID, teamID, tick] - shuntChange = True - GameWorld.DebugLog("boss分流 -> 玩家不在该boss伤血中,设置为关联状态!playerID=%s,npcID=%s,teamID=%s,tick=%s" - % (playerID, npcID, teamID, tick), lineID) - - # 伤先优先级最高,可直接覆盖更新 - for playerID, teamID in hurtPlayerDict.items(): - if playerID not in shuntPlayerDict: - shuntPlayerDict[playerID] = [npcID, teamID, 0] - shuntChange = True - GameWorld.DebugLog("boss分流 -> 新增玩家对boss伤害!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID) - - elif shuntPlayerDict[playerID][0] != npcID: - shuntPlayerDict[playerID] = [npcID, teamID, 0] - shuntChange = True - GameWorld.DebugLog("boss分流 -> 伤害转移到本boss上!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID) - - if shuntChange: - PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict - GameServer_WorldBossShuntInfo(mapID, lineID) - return - - def __GetAtkObjByHurtList(self, npcHurtList): - '''第一个可攻击的最大伤血对象,也是实际的归属者或队伍 - 因为玩家伤血掉线、死亡有一定时间的保留机制,故最大伤血不一定是可攻击目标(归属者) - 注意: 该规则必须与最终算归属的规则一致,不然可能导致归属错乱 - ''' - for index in xrange(npcHurtList.GetHurtCount()): - #获得伤血对象 - hurtObj = npcHurtList.GetHurtAt(index) - - curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, True) - - if curPlayer or curTeam: - return hurtObj - return - def IsInHurtProtect(self): '''NPC是否伤血保护中 因为手游比较会出现网络切换的情况,此时会可能会引起掉线重连 @@ -3457,6 +3233,8 @@ self.ClearNPCHurtList() #清除所有身上buff self.ClearAllBuff(isClearAuraBuff) + curNPC = self.__Instance + NPCHurtManager.ClearPlayerHurtList(curNPC) return True #--------------------------------------------------------------------- @@ -4234,7 +4012,9 @@ curNPC = self.__Instance self.__FeelPlayerList = [] - npcHurtList = curNPC.GetPlayerHurtList() + npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC) + if not npcHurtList: + npcHurtList = curNPC.GetPlayerHurtList() #npcHurtList.Sort() #这里不排序,只要有伤害就算 eventPlayerList = [] @@ -4672,7 +4452,6 @@ #objID = curNPC.GetID() npcID = curNPC.GetNPCID() self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx() - self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家 isGameBoss = ChConfig.IsGameBoss(curNPC) self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo(isGameBoss) @@ -4691,8 +4470,6 @@ for curPlayer in self.__AllKillerDict.values(): if not self.__LastHurtPlayer: self.__LastHurtPlayer = curPlayer - if not self.__MaxHurtPlayer: - self.__MaxHurtPlayer = curPlayer if not self.__Killer: self.__Killer = curPlayer @@ -4736,12 +4513,7 @@ if OnNPCDie: OnNPCDie(curNPC, hurtType, hurtID) - - #执行玩家连轧逻辑 - lastTimeHurtObj = self.__FindLastTimeHurtObj() - if lastTimeHurtObj[0] == None and lastTimeHurtObj[1] == None: - return - + return ## 最后一击处理 @@ -4757,35 +4529,6 @@ return curNPC = self.__Instance - #npcID = curNPC.GetNPCID() - #mapID = GameWorld.GetMap().GetMapID() - #playerName = lastHurtPlayer.GetPlayerName() - - #=========================================================================================== - # # 最后一击奖励 - # lastTimeHurtBossAwardDict = ReadChConfig.GetEvalChConfig("LastTimeHurtBossAward") - # if npcID in lastTimeHurtBossAwardDict: - # giveItemList = lastTimeHurtBossAwardDict[npcID] - # playerID = lastHurtPlayer.GetPlayerID() - # bossAwardMailInfo = ReadChConfig.GetEvalChConfig("LastTimeHurtBossAwardMail") - # title, content, getDays = bossAwardMailInfo - # mailContent = content % (npcID) - # PlayerControl.SendMail(title, mailContent, getDays, [playerID], giveItemList) - # - # # 广播 - # if len(giveItemList) > 0: - # itemID = giveItemList[0][0] # 默认取第一个奖励物品广播 - # PlayerControl.WorldNotify(0, "GeRen_liubo_698214", [playerName, mapID, npcID, itemID, itemID]) - #=========================================================================================== - - #=========================================================================================== - # # 最后一击广播 - # LastHurtNotifyDict = ReadChConfig.GetEvalChConfig("LastHurtNotify") - # for npcIDTuple, notifyMark in LastHurtNotifyDict.items(): - # if npcID in npcIDTuple: - # PlayerControl.WorldNotify(0, notifyMark, [playerName, mapID, npcID]) - # break - #=========================================================================================== # VIP杀怪加攻 PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, curNPC) @@ -4851,14 +4594,6 @@ if isGameBoss: GameWorld.Log(" 归属最大伤血队伍: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID())) return killerDict, curTeam, ChConfig.Def_NPCHurtTypeTeam, curTeam.GetTeamID() - # 最大伤血玩家 - 伤血不会被重置 - elif dropOwnerType == ChConfig.DropOwnerType_MaxHurtPlayer: - if self.__MaxHurtPlayer: - maxHurtPlayerID = self.__MaxHurtPlayer.GetPlayerID() - if maxHurtPlayerID not in killerDict: - killerDict[maxHurtPlayerID] = self.__MaxHurtPlayer - #GameWorld.DebugLog(" 特殊归属最大伤害玩家: playerID=%s" % maxHurtPlayerID) - return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, maxHurtPlayerID # 最大仇恨 elif dropOwnerType == ChConfig.DropOwnerType_MaxAngry: @@ -4946,20 +4681,7 @@ return curTag, GameWorld.GetTeamManager().FindTeam(teamID) #--------------------------------------------------------------------- - ## 获取补刀者,包含队伍 - # @param self 类实例 - # @return 返回值 玩家或者None - # @remarks - def __FindLastTimeHurtObj(self): - curNPC = self.__Instance - npcHurtList = curNPC.GetPlayerHurtList() - if npcHurtList.GetHurtCount() <= 0: - return (None, None) - - maxHurtObj = npcHurtList.GetLastTimeHurtValue() - return self.__GetTagByHurtObj(maxHurtObj) - - + ## 获取补刀者(这个绝对是玩家) # @param self 类实例 # @return 返回值 玩家或者None @@ -4968,17 +4690,6 @@ playerID = curNPC.GetDictByKey(ChConfig.Def_PlayerKey_LastHurt) curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) - if not curPlayer: - return None - - return curPlayer - - def __FindBossMaxHurtObj(self): - # py自定义伤血所得到的Boss最大伤血玩家 - curNPC = self.__Instance - maxHurtID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_BossMaxHurtID % (curNPC.GetID(), curNPC.GetNPCID())) - - curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(maxHurtID) if not curPlayer: return None @@ -5137,8 +4848,6 @@ if not self.__LastHurtPlayer: self.__LastHurtPlayer = playerlist[0] - if not self.__MaxHurtPlayer: - self.__MaxHurtPlayer = playerlist[0] if not self.__Killer: self.__Killer = playerlist[0] maxHurtID = playerlist[0].GetPlayerID() @@ -5217,8 +4926,6 @@ # 赶时间,先简单处理直接取最大等级的,之后可按实际情况来 if not self.__LastHurtPlayer: self.__LastHurtPlayer = dropPlayer - if not self.__MaxHurtPlayer: - self.__MaxHurtPlayer = dropPlayer if not self.__Killer: self.__Killer = dropPlayer maxHurtID = dropPlayer.GetPlayerID() @@ -5441,14 +5148,10 @@ 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) - + maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead) + if maxHurtInfo: + tagObj, ownerType, ownerID = maxHurtInfo + elif dropOwnerType == ChConfig.DropOwnerType_Family: ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval) if ownerInfo: @@ -5576,16 +5279,20 @@ if isDead: GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID)) + hurtList = NPCHurtManager.GetPlayerHurtList(curNPC) # 刷新归属 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()) + if not hurtList or hurtList.HaveHurtValue(playerID): + 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()) + else: + BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC) elif ownerType == ChConfig.Def_NPCHurtTypeTeam: curTeam = GameWorld.GetTeamManager().FindTeam(ownerID) @@ -5605,6 +5312,7 @@ continue if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \ + and (not hurtList or hurtList.HaveHurtValue(curTeamPlayer.GetPlayerID()))\ and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \ and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible(): self.__AddDropOwnerPlayerBuff(curTeamPlayer, tick) -- Gitblit v1.8.0