Exemplo n.º 1
0
        /// <summary>
        /// Add hitscan position to coordinates
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        public static PointF GetHitscanPoint(HitscanResult result)
        {
            switch (result)
            {
            case HitscanResult.Center:
                return(new PointF(0, 0));

            case HitscanResult.Top:
                return(new PointF(0, 0 - ScanRange));

            case HitscanResult.Bottom:
                return(new PointF(0, 0 + ScanRange));

            case HitscanResult.Left:
                return(new PointF(0 - ScanRange, 0));

            case HitscanResult.Right:
                return(new PointF(0 + ScanRange, 0));

            case HitscanResult.TopLeft:
                return(new PointF(0 - ScanRange, 0 - ScanRange));

            case HitscanResult.TopRight:
                return(new PointF(0 + ScanRange, 0 - ScanRange));

            case HitscanResult.BottomLeft:
                return(new PointF(0 - ScanRange, 0 + ScanRange));

            case HitscanResult.BottomRight:
                return(new PointF(0 + ScanRange, 0 + ScanRange));
            }

            return(new PointF(0, 0));
        }
Exemplo n.º 2
0
        private void DoHitscan(Vector2 dir)
        {
            float   rotation   = item.body.Rotation;
            Vector2 simPositon = item.SimPosition;

            item.Drop(null);

            item.body.Enabled = true;
            //set the velocity of the body because the OnProjectileCollision method
            //uses it to determine the direction from which the projectile hit
            item.body.LinearVelocity = dir;
            IsActive = true;

            Vector2 rayStart = simPositon;
            Vector2 rayEnd   = simPositon + dir * 1000.0f;

            List <HitscanResult> hits = new List <HitscanResult>();

            hits.AddRange(DoRayCast(rayStart, rayEnd));

            if (item.Submarine != null)
            {
                //shooting indoors, do a hitscan outside as well
                hits.AddRange(DoRayCast(rayStart + item.Submarine.SimPosition, rayEnd + item.Submarine.SimPosition));
            }
            else
            {
                //shooting outdoors, see if we can hit anything inside a sub
                foreach (Submarine submarine in Submarine.Loaded)
                {
                    var inSubHits = DoRayCast(rayStart - submarine.SimPosition, rayEnd - submarine.SimPosition);
                    //transform back to world coordinates
                    for (int i = 0; i < inSubHits.Count; i++)
                    {
                        inSubHits[i] = new HitscanResult(
                            inSubHits[i].Fixture,
                            inSubHits[i].Point + submarine.SimPosition,
                            inSubHits[i].Normal,
                            inSubHits[i].Fraction);
                    }

                    hits.AddRange(inSubHits);
                }
            }

            bool hitSomething = false;

            hits = hits.OrderBy(h => h.Fraction).ToList();
            foreach (HitscanResult h in hits)
            {
                item.body.SetTransform(h.Point, rotation);
                if (OnProjectileCollision(h.Fixture, h.Normal))
                {
                    hitSomething = true;
                    break;
                }
            }

            //the raycast didn't hit anything -> the projectile flew somewhere outside the level and is permanently lost
            if (!hitSomething)
            {
                if (Entity.Spawner == null)
                {
                    item.Remove();
                }
                else
                {
                    Entity.Spawner.AddToRemoveQueue(item);
                }
            }
        }
Exemplo n.º 3
0
        private void DoHitscan(Vector2 dir)
        {
            float   rotation   = item.body.Rotation;
            Vector2 simPositon = item.SimPosition;

            item.Drop(null);

            item.body.Enabled = true;
            //set the velocity of the body because the OnProjectileCollision method
            //uses it to determine the direction from which the projectile hit
            item.body.LinearVelocity = dir;
            IsActive = true;

            Vector2 rayStart = simPositon;
            Vector2 rayEnd   = simPositon + dir * 500.0f;

            List <HitscanResult> hits = new List <HitscanResult>();

            hits.AddRange(DoRayCast(rayStart, rayEnd, submarine: item.Submarine));

            if (item.Submarine != null)
            {
                //shooting indoors, do a hitscan outside as well
                hits.AddRange(DoRayCast(rayStart + item.Submarine.SimPosition, rayEnd + item.Submarine.SimPosition, submarine: null));
                //also in the coordinate space of docked subs
                foreach (Submarine dockedSub in item.Submarine.DockedTo)
                {
                    if (dockedSub == item.Submarine)
                    {
                        continue;
                    }
                    hits.AddRange(DoRayCast(rayStart + item.Submarine.SimPosition - dockedSub.SimPosition, rayEnd + item.Submarine.SimPosition - dockedSub.SimPosition, dockedSub));
                }
            }
            else
            {
                //shooting outdoors, see if we can hit anything inside a sub
                foreach (Submarine submarine in Submarine.Loaded)
                {
                    var inSubHits = DoRayCast(rayStart - submarine.SimPosition, rayEnd - submarine.SimPosition, submarine);
                    //transform back to world coordinates
                    for (int i = 0; i < inSubHits.Count; i++)
                    {
                        inSubHits[i] = new HitscanResult(
                            inSubHits[i].Fixture,
                            inSubHits[i].Point + submarine.SimPosition,
                            inSubHits[i].Normal,
                            inSubHits[i].Fraction);
                    }

                    hits.AddRange(inSubHits);
                }
            }

            bool hitSomething = false;

            hits = hits.OrderBy(h => h.Fraction).ToList();
            foreach (HitscanResult h in hits)
            {
                item.SetTransform(h.Point, rotation);
                if (HandleProjectileCollision(h.Fixture, h.Normal, Vector2.Zero))
                {
                    hitSomething = true;
                    break;
                }
            }

            //the raycast didn't hit anything -> the projectile flew somewhere outside the level and is permanently lost
            if (!hitSomething)
            {
                if (Entity.Spawner == null)
                {
                    item.Remove();
                }
                else
                {
                    if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
                    {
                        //clients aren't allowed to remove items by themselves, so lets hide the projectile until the server tells us to remove it
                        item.HiddenInGame = Hitscan;
                    }
                    else
                    {
                        Entity.Spawner.AddToRemoveQueue(item);
                    }
                }
            }
        }
Exemplo n.º 4
0
        private void DoHitscan(Vector2 dir)
        {
            float   rotation   = item.body.Rotation;
            Vector2 simPositon = item.SimPosition;

            item.Drop(null);

            item.body.Enabled = true;
            //set the velocity of the body because the OnProjectileCollision method
            //uses it to determine the direction from which the projectile hit
            item.body.LinearVelocity = dir;
            IsActive = true;

            Vector2 rayStart = simPositon;
            Vector2 rayEnd   = rayStart + dir * 500.0f;

            Vector2 rayStartWorld = item.WorldPosition;
            float   worldDist     = 1000.0f;

#if CLIENT
            worldDist = Screen.Selected?.Cam?.WorldView.Width ?? GameMain.GraphicsWidth;
#endif
            Vector2 rayEndWorld = rayStartWorld + dir * worldDist;

            List <HitscanResult> hits = new List <HitscanResult>();

            hits.AddRange(DoRayCast(rayStart, rayEnd, submarine: item.Submarine));

            if (item.Submarine != null)
            {
                //shooting indoors, do a hitscan outside as well
                hits.AddRange(DoRayCast(rayStart + item.Submarine.SimPosition, rayEnd + item.Submarine.SimPosition, submarine: null));
                //also in the coordinate space of docked subs
                foreach (Submarine dockedSub in item.Submarine.DockedTo)
                {
                    if (dockedSub == item.Submarine)
                    {
                        continue;
                    }
                    hits.AddRange(DoRayCast(rayStart + item.Submarine.SimPosition - dockedSub.SimPosition, rayEnd + item.Submarine.SimPosition - dockedSub.SimPosition, dockedSub));
                }
            }
            else
            {
                //shooting outdoors, see if we can hit anything inside a sub
                foreach (Submarine submarine in Submarine.Loaded)
                {
                    var inSubHits = DoRayCast(rayStart - submarine.SimPosition, rayEnd - submarine.SimPosition, submarine);
                    //transform back to world coordinates
                    for (int i = 0; i < inSubHits.Count; i++)
                    {
                        inSubHits[i] = new HitscanResult(
                            inSubHits[i].Fixture,
                            inSubHits[i].Point + submarine.SimPosition,
                            inSubHits[i].Normal,
                            inSubHits[i].Fraction);
                    }

                    hits.AddRange(inSubHits);
                }
            }

            int     hitCount   = 0;
            Vector2 lastHitPos = item.WorldPosition;
            hits = hits.OrderBy(h => h.Fraction).ToList();
            for (int i = 0; i < hits.Count; i++)
            {
                var h = hits[i];
                item.SetTransform(h.Point, rotation);
                if (HandleProjectileCollision(h.Fixture, h.Normal, Vector2.Zero))
                {
                    hitCount++;
                    if (hitCount >= MaxTargetsToHit || i == hits.Count - 1)
                    {
                        LaunchProjSpecific(rayStartWorld, item.WorldPosition);
                        break;
                    }
                }
            }
            //the raycast didn't hit anything (or didn't hit enough targets to stop the projectile) -> the projectile flew somewhere outside the level and is permanently lost
            if (hitCount < MaxTargetsToHit)
            {
                item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation);
                LaunchProjSpecific(rayStartWorld, rayEndWorld);
                if (Entity.Spawner == null)
                {
                    item.Remove();
                }
                else
                {
                    if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
                    {
                        //clients aren't allowed to remove items by themselves, so lets hide the projectile until the server tells us to remove it
                        item.HiddenInGame = Hitscan;
                    }
                    else
                    {
                        Entity.Spawner.AddToRemoveQueue(item);
                    }
                }
            }
        }