Ejemplo n.º 1
0
		/// <summary>
		/// LoscheckVincinity can be used when source player isn't available to check Los
		/// </summary>
		/// <param name="source">GameObject from witch LoS check start</param>
		/// <param name="target">GameObject to check LoS to</param>
		/// <param name="notifier">GameObject to Notify when Check is made</param>
		/// <param name="cached">Use a cached result</param>
		/// <param name="timeout">Cache Timeout, 0 = default</param>
		public void LosCheckVincinity(GameObject source, GameObject target, IDOLEventHandler notifier, bool cached = true, int timeout = 0) 
		{			
			// FIXME debug
			if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_WARN)
				log.Warn("LOSMGR_W : Starting Vincinity Los Check Between - Source : "+source.Name+" Target : "+target.Name+".");
			
			if(timeout == 0)
				timeout = GetDefaultTimeouts(source, target);
			
			// check Threshold first
			if(source.IsWithinRadius(target, GetDefaultThreshold(source, target), false))
			{
				//we need an arbitrary player
				foreach(GamePlayer player in source.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE))
				{
					if(player.ObjectState == GameNPC.eObjectState.Active) 
					{
						// FIXME debug
						if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG)
							log.Warn("LOSMGR_D : Vincinity Hitted Treshold ("+GetDefaultThreshold(source, target)+") - Source : "+source.Name+" Target : "+target.Name+".");
						
						notifier.Notify(GameObjectEvent.FinishedLosCheck, player, new LosCheckData(source, target, GameTimer.GetTickCount(), true));
						return;
					}
				}
			}
			
			// check cache then !
			if(cached)
			{			
				try
				{
					bool los = GetLosCheckFromCache(source, target, timeout);
					//we need an arbitrary player
					foreach(GamePlayer player in source.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE))
					{
						if(player.ObjectState == GameNPC.eObjectState.Active) 
						{
							notifier.Notify(GameObjectEvent.FinishedLosCheck, player, new LosCheckData(source, target, GameTimer.GetTickCount(), los));
							return;
						}
						
					}
				}
				catch (LosUnavailableException)
				{
					// we have no cache
				}
			}
			
			// check pending
			lock(((ICollection)PendingChecks).SyncRoot)
			{
				IEnumerable<Tuple<GamePlayer, ushort, ushort>> pendings = (from pending in PendingChecks where (pending.Key.Item2 == source.ObjectID && pending.Key.Item3 == target.ObjectID) || (pending.Key.Item2 == target.ObjectID && pending.Key.Item3 == source.ObjectID) select pending.Key).Take(1);
				foreach(Tuple<GamePlayer, ushort, ushort> pend in pendings)
				{
					// FIXME debug
					if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_INFO)
						log.Warn("LOSMGR_I : Vincinity Registered to an other LoS - Source : "+source.Name+" Target : "+target.Name+".");
					
					AddRegisteredEvent(new Tuple<GameObject, GameObject>(source, target), notifier);
					return;
				}
			}
						
			// check if source is player and available for Los check
			if(IsAvailableForLosCheck(source, source, target))
			{
				LosCheck((GamePlayer)source, source, target, notifier, cached, timeout);
				return;
			}
			
			// check if target is player and available for Los check
			if(IsAvailableForLosCheck(target, source, target))
			{
				LosCheck((GamePlayer)target, source, target, notifier, cached, timeout);
				return;
			}
			
			// check if source has an available owner
			if(source is GameNPC && ((GameNPC)source).Brain != null && ((GameNPC)source).Brain is IControlledBrain)
			{
				GamePlayer owner = ((IControlledBrain)((GameNPC)source).Brain).GetPlayerOwner();
				if(owner != null && IsAvailableForLosCheck(owner, source, target)) {
					LosCheck(owner, source, target, notifier, cached, timeout);
					return;
				}	
			}
			
			// check if target has an available owner
			if(target is GameNPC && ((GameNPC)target).Brain != null && ((GameNPC)target).Brain is IControlledBrain)
			{
				GamePlayer tgtowner = ((IControlledBrain)((GameNPC)target).Brain).GetPlayerOwner();
				if(tgtowner != null && IsAvailableForLosCheck(tgtowner, source, target)) {
					LosCheck(tgtowner, source, target, notifier, cached, timeout);
					return;
				}	
			}
			
			GamePlayer checker = GetBestLosChecker(source, target);
			
			if(checker != null)
			{
				// FIXME debug
				if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_INFO)
					log.Warn("LOSMGR_I : Vincinity found best checker "+checker.Name+" - Source : "+source.Name+" Target : "+target.Name+".");
				
				LosCheck(checker, source, target, notifier, cached, timeout);
				return;
			}
			
			throw new LosUnavailableException();
		}
Ejemplo n.º 2
0
		/// <summary>
		/// Register an event handler for the given key
		/// </summary>
		/// <param name="key">Key to Register to</param>
		/// <param name="notifier">Event handler Object</param>
		private void AddRegisteredEvent(Tuple<GameObject, GameObject> key, IDOLEventHandler notifier)
		{
			lock(((ICollection)RegisteredLosEvents).SyncRoot)
			{
				if(!RegisteredLosEvents.ContainsKey(key) || RegisteredLosEvents[key] == null) 
				{
					RegisteredLosEvents[key] = new List<IDOLEventHandler>();
				}

				RegisteredLosEvents[key].Add(notifier);
				return;
			}
		}
Ejemplo n.º 3
0
		/// <summary>
		/// Check LoS and wait for a reply before returning
		/// </summary>
		/// <param name="player">Client used to make the LoS check</param>
		/// <param name="source">GameObject from witch LoS check start</param>
		/// <param name="target">GameObject to check LoS to</param>
		/// <param name="notifier">GameObject to Notify when Check is made</param>
		/// <param name="cached">Use a cached result</param>
		/// <param name="timeout">Cache Timeout, 0 = default</param>
		public void LosCheck(GamePlayer player, GameObject source, GameObject target, IDOLEventHandler notifier, bool cached = true, int timeout = 0)
		{			
			if(player == null || source == null || target == null)
				throw new LosUnavailableException();
			
			// FIXME debug
			if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_WARN)
				log.Warn("LOSMGR_W : Starting Los Check with - Player : "+player.Name+" Source : "+source.Name+" Target : "+target.Name+".");

			if(timeout <= 0)
				timeout = GetDefaultTimeouts(source, target);
			
			// check Threshold first
			if(source.IsWithinRadius(target, GetDefaultThreshold(source, target), false))
			{
				// FIXME debug
				if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG)
					log.Warn("LOSMGR_D : Threshold hitted ("+GetDefaultThreshold(source, target)+") with - Player : "+player.Name+" Source : "+source.Name+" Target : "+target.Name+".");

				notifier.Notify(GameObjectEvent.FinishedLosCheck, player, new LosCheckData(source, target, GameTimer.GetTickCount(), true));
				return;
			}
			
			// check in cache then !
			if(cached)
			{	
				try
				{
					bool los = GetLosCheckFromCache(source, target, timeout);
					notifier.Notify(GameObjectEvent.FinishedLosCheck, player, new LosCheckData(source, target, GameTimer.GetTickCount(), los));
					return;
					
				}
				catch (LosUnavailableException)
				{
					// we have no cache
				}
			}

			// Check if a LoS is pending, or this player is already LoS Checking...
			Tuple<GameObject, GameObject> cacheKey = new Tuple<GameObject, GameObject>(source, target);
						
			// We need to lock the Pending list during the checks
			lock(((ICollection)PendingChecks).SyncRoot)
			{
				IEnumerable<Tuple<GamePlayer, ushort, ushort>> pendings = (from pending in PendingChecks where (pending.Key.Item2 == source.ObjectID && pending.Key.Item3 == target.ObjectID) || (pending.Key.Item2 == target.ObjectID && pending.Key.Item3 == source.ObjectID) select pending.Key).Take(1);

				// We have pending data not too old, Register this event handler
				foreach(Tuple<GamePlayer, ushort, ushort> pend in pendings)
				{
					// FIXME debug
					if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_INFO)
						log.Warn("LOSMGR_D : Registered to an other LoS with - Player : "+player.Name+" Source : "+source.Name+" Target : "+target.Name+".");

					AddRegisteredEvent(cacheKey, notifier);
					return;
				}
			}
			
			// Throttle
			if(IsPvpLosCheck(source, target) || IsAvailableForLosCheck(player, source, target)) {
				// Not pending, Not in Cache, let's work
				AddRegisteredEvent(cacheKey, notifier);
				EventNotifierLosCheck(player, source, target);
			}
			else
			{
				// Get best checker !
				GamePlayer checker = GetBestLosChecker(source, target);
				
				if(checker != null) 
				{
					// FIXME Debug
					if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_WARN)
						log.Warn("LOSMGR_D : Deferred LoSCheck to "+checker.Name+" From - Player : "+player.Name+" Source : "+source.Name+" Target : "+target.Name+".");

					AddRegisteredEvent(cacheKey, notifier);
					EventNotifierLosCheck(checker, source, target);
				}
				else
				{
					// the Player checker is unavailable to make this LosCheck
					throw new LosUnavailableException();
				}
			}
		}