Exemple #1
0
		private bool MyPeopleNeedMe()
		{
			if (IsFaction || Crystal == null || Crystal.Deleted || !Crystal.Visible || !Crystal.Movable || Utility.RandomBool())
			{
				return false;
			}

			Crystal.PublicOverheadMessage(MessageType.Regular, 1287, false, "I MUST GO, MY PEOPLE NEED ME.");

			Point3D loc = Crystal.GetWorldLocation();

			// (Lee) The reason for using effects is efficiency,
			// since whenever the physical item's location (Z) is changed, 
			// it sends a bunch of update packets, I know it's trivial, 
			// but i thought you might like this example of usage of the VNc effects :)

			// Create a new deferred effect queue.
			// When the queue has finished processing, delete the crystal.
			var q = new EffectQueue(
				() =>
				{
					if (Crystal != null)
					{
						Crystal.Delete();
					}
				});

			// Add 10 effects to the queue,
			// each with a duration of 10 (default value),
			// which translates to 1000 milliseconds (10 * 100).
			// Since they are not moving effects and each effect lasts for 1 second,
			// it should produce the same illusion of the original implementation design.
			for (int i = 0; i < 10; i++)
			{
				q.Add(
					new EffectInfo(
						loc.Clone3D(0, 0, i), Crystal.Map, Crystal.ItemID, Crystal.Hue, 10, 10, EffectRender.Normal, TimeSpan.Zero));
			}

			// Process the effect queue after waiting 5 seconds.
			Timer.DelayCall(
				TimeSpan.FromSeconds(5.0),
				() =>
				{
					// Anything can happen in 5 seconds, so check it all again.
					if (Crystal != null && !Crystal.Deleted && Crystal.Visible && Crystal.Movable && !IsFaction)
					{
						// Hiding the crystal so the effects can handle the visuals
						Crystal.Visible = false;

						// Just in case anyone wants to try to mess with it, even when it's hidden.
						Crystal.Movable = false;

						q.Process();
					}

					// We don't need the queue, so explicitly dispose for efficiency (optional)
					q.Dispose();
				});

			return true;
		}
Exemple #2
0
        private bool MyPeopleNeedMe()
        {
            if (IsFaction || Crystal == null || Crystal.Deleted || !Crystal.Visible || !Crystal.Movable || Utility.RandomBool())
            {
                return(false);
            }

            Crystal.PublicOverheadMessage(MessageType.Regular, 1287, false, "I MUST GO, MY PEOPLE NEED ME.");

            Point3D loc = Crystal.GetWorldLocation();

            // (Lee) The reason for using effects is efficiency,
            // since whenever the physical item's location (Z) is changed,
            // it sends a bunch of update packets, I know it's trivial,
            // but i thought you might like this example of usage of the VNc effects :)

            // Create a new deferred effect queue.
            // When the queue has finished processing, delete the crystal.
            var q = new EffectQueue(
                () =>
            {
                if (Crystal != null)
                {
                    Crystal.Delete();
                }
            });

            // Add 10 effects to the queue,
            // each with a duration of 10 (default value),
            // which translates to 1000 milliseconds (10 * 100).
            // Since they are not moving effects and each effect lasts for 1 second,
            // it should produce the same illusion of the original implementation design.
            for (int i = 0; i < 10; i++)
            {
                q.Add(
                    new EffectInfo(
                        loc.Clone3D(0, 0, i), Crystal.Map, Crystal.ItemID, Crystal.Hue, 10, 10, EffectRender.Normal, TimeSpan.Zero));
            }

            // Process the effect queue after waiting 5 seconds.
            Timer.DelayCall(
                TimeSpan.FromSeconds(5.0),
                () =>
            {
                // Anything can happen in 5 seconds, so check it all again.
                if (Crystal != null && !Crystal.Deleted && Crystal.Visible && Crystal.Movable && !IsFaction)
                {
                    // Hiding the crystal so the effects can handle the visuals
                    Crystal.Visible = false;

                    // Just in case anyone wants to try to mess with it, even when it's hidden.
                    Crystal.Movable = false;

                    q.Process();
                }

                // We don't need the queue, so explicitly dispose for efficiency (optional)
                q.Dispose();
            });

            return(true);
        }
        protected override void OnInvoke(BaseAspect aspect)
        {
            if (aspect == null || aspect.Deleted)
            {
                return;
            }

            var list = ListPool <EffectQueue> .AcquireObject();

            var cw = Utility.RandomBool();

            for (int a = (cw ? 0 : 360), h = 0; (cw ? a <= 360 : a >= 0); a += (cw ? 1 : -1))
            {
                var x = (int)Math.Round(aspect.X + (aspect.RangePerception * Math.Sin(Geometry.DegreesToRadians(a))));
                var y = (int)Math.Round(aspect.Y + (aspect.RangePerception * Math.Cos(Geometry.DegreesToRadians(a))));

                if (((x * 397) ^ y) == h)
                {
                    // This location was just handled, ignore it to avoid small increments
                    continue;
                }

                h = ((x * 397) ^ y);

                var start = aspect.Clone3D(0, 0, 10);
                var end   = new Point3D(x, y, aspect.Z);

                end.Z = end.GetTopZ(aspect.Map);

                var l = start.GetLine3D(end, aspect.Map, false);

                var q = new EffectQueue
                {
                    Deferred = false,
                    Handler  = e => HandleDeathRay(aspect, e)
                };

                for (var i = 0; i < l.Length; i++)
                {
                    var p       = new Block3D(l[i], 5);
                    var blocked = i + 1 >= l.Length;

                    if (!blocked)
                    {
                        var land = aspect.Map.GetLandTile(p);

                        if (p.Intersects(land.Z, land.Height))
                        {
                            var o = TileData.LandTable[land.ID];

                            if (o.Flags.AnyFlags(_BlockingFlags))
                            {
                                blocked = true;
                            }
                        }
                    }

                    if (!blocked)
                    {
                        var tiles = aspect.Map.GetStaticTiles(p);

                        var data = tiles.Where(o => p.Intersects(o.Z, o.Height)).Select(t => TileData.ItemTable[t.ID]);

                        if (data.Any(o => o.Flags.AnyFlags(_BlockingFlags)))
                        {
                            blocked = true;
                        }
                    }

                    if (!blocked)
                    {
                        var items = p.FindItemsAt(aspect.Map);

                        var data = items.Where(p.Intersects).Select(o => TileData.ItemTable[o.ItemID]);

                        if (data.Any(o => o.Flags.AnyFlags(_BlockingFlags)))
                        {
                            blocked = true;
                        }
                    }

                    var effect = blocked ? 14120 : Utility.RandomMinMax(12320, 12324);
                    var hue    = blocked ? 0 : 2075;

                    if (blocked)
                    {
                        p = p.Clone3D(0, 0, -8);
                    }

                    q.Add(
                        new EffectInfo(p, aspect.Map, effect, hue, 10, 10, EffectRender.Darken)
                    {
                        QueueIndex = i
                    });

                    if (blocked)
                    {
                        break;
                    }
                }

                if (q.Queue.Count > 0)
                {
                    list.Add(q);
                }
            }

            if (list.Count == 0)
            {
                ObjectPool.Free(list);

                return;
            }

            for (var i = 0; i < list.Count; i++)
            {
                var cur = list[i];

                if (i + 1 < list.Count)
                {
                    var next = list[i + 1];

                    cur.Callback = () =>
                    {
                        if (aspect.Deleted || !aspect.Alive)
                        {
                            list.ForEach(q => q.Dispose());

                            ObjectPool.Free(list);

                            return;
                        }

                        if (next.Queue.Count > 0)
                        {
                            SpellHelper.Turn(aspect, next.Queue.Last().Source);
                        }

                        Timer.DelayCall(TimeSpan.FromSeconds(0.05), next.Process);
                    };
                }
                else
                {
                    cur.Callback = () =>
                    {
                        list.ForEach(q => q.Dispose());

                        ObjectPool.Free(list);

                        aspect.CantWalk      = false;
                        aspect.LockDirection = false;
                    };
                }
            }

            if (list.Count == 0)
            {
                ObjectPool.Free(list);

                return;
            }

            aspect.CantWalk      = true;
            aspect.LockDirection = true;

            if (list[0].Queue.Count > 0)
            {
                SpellHelper.Turn(aspect, list[0].Queue.Last().Source);
            }

            Timer.DelayCall(TimeSpan.FromSeconds(0.1), list[0].Process);
        }
        protected override void OnInvoke(BaseAspect aspect)
        {
            if (aspect == null || aspect.Deleted)
            {
                return;
            }

            var map = aspect.Map;
            var x   = aspect.X;
            var y   = aspect.Y;
            var z   = aspect.Z;

            var count = Utility.RandomMinMax(5, 10);
            var sect  = 360 / count;

            var shift = Utility.RandomMinMax(0, sect);
            var range = Math.Max(3, aspect.RangePerception - 3);

            for (var i = 0; i < count; i++)
            {
                var t = Angle.GetPoint3D(x, y, z, shift + (i * sect), range);
                var l = aspect.PlotLine3D(t).TakeWhile(p => map.HasLand(p) && !map.HasWater(p));

                var q = new EffectQueue(range);

                var c = -1;

                foreach (var p in l)
                {
                    q.Add(
                        new EffectInfo(p, map, 14089, 0, 8, 15, EffectRender.Darken)
                    {
                        QueueIndex = ++c
                    });
                }

                if (q.Count == 0)
                {
                    q.Dispose();
                    continue;
                }

                q.Handler = fx =>
                {
                    var isEnd = fx.QueueIndex >= c;

                    if (!TryBurst(aspect, fx, ref isEnd) || isEnd)
                    {
                        q.Clear();
                    }
                };

                q.Callback = q.Dispose;

                Timer.DelayCall(
                    TimeSpan.FromSeconds(0.2 * i),
                    () =>
                {
                    aspect.Direction = aspect.GetDirection(t);

                    if (aspect.PlayAttackAnimation())
                    {
                        aspect.PlayAttackSound();
                    }

                    q.Process();
                });
            }
        }