Exemple #1
0
        public static bool DoesQuadIntersectCircleSector(Quad quad, Messages.ScanShoot msg)
        {
            Vector2 quadCentre        = new Vector2(quad.CentreX, quad.CentreY);
            double  maximumQuadRadius = 1.41421356237 * quad.Radius;
            Vector2 leftPoint         = new Vector2(msg.Radius * Math.Cos(msg.Direction + msg.Width), msg.Radius * Math.Sin(msg.Direction + msg.Width));
            Vector2 rightPoint        = new Vector2(msg.Radius * Math.Cos(msg.Direction - msg.Width), msg.Radius * Math.Sin(msg.Direction - msg.Width));

            return(CircleTriangleIntersection(quadCentre, maximumQuadRadius, msg.Origin, leftPoint, rightPoint) || CircleSegmentIntersection(quadCentre, maximumQuadRadius, msg.Origin, msg.Radius, msg.Direction, msg.Width));
        }
Exemple #2
0
        /// <summary>
        /// Handle scanning/shooting on this node:
        /// - Broadcasts the Struck response for the local node
        /// - Moves ships to the graveyard as needed
        /// </summary>
        private Messages.Struck HandleLocalScanShoot(Messages.ScanShoot msg)
        {
            Messages.Struck results = QuadTreeNode.ScanShootLocal(msg);
            Bus.BroadcastMessage(results);

            foreach (var ourStruck in results.ShipsInfo)
            {
                if (ourStruck.Damage < 0.0) // ship ded
                {
                    var ourDeadShip = ourStruck.Ship;
                    QuadTreeNode.ShipsByToken.Remove(ourDeadShip.Token);
                    DeadShips.Add(ourDeadShip.Token, ourDeadShip);
                }
            }

            return(results);
        }
Exemple #3
0
        public override Messages.Struck ScanShootLocal(Messages.ScanShoot msg)
        {
            bool affected = MathUtils.DoesQuadIntersectCircleSector(this.Bounds, msg);

            if (affected)
            {
                Bus.SendMessage(msg, NodePeer);

                var             struckTask = new MessageWaiter <Messages.Struck>(Bus, NodePeer, (struck) => struck.Originator == msg.Originator).Wait;
                Messages.Struck results    = new Messages.Struck();
                if (Task.WaitAll(new Task[] { struckTask }, REPLYTIMEOUT))
                {
                    results.OriginatorAreaGain += struckTask.Result.OriginatorAreaGain;
                    results.ShipsInfo.AddRange(struckTask.Result.ShipsInfo);
                }
                return(results);
            }
            else
            {
                return(null);
            }
        }
Exemple #4
0
        public override Messages.Struck ScanShootLocal(Messages.ScanShoot msg)
        {
            Messages.Struck results = new Messages.Struck();

            // 1) Search ships locally (but only if affected by the scan)
            //bool affected = MathUtils.DoesQuadIntersectCircleSector(this.Bounds, msg);
            bool affected = true; // FIXME - This is here to make sure scans always go through; ideally, though, ships would always be in the SGame node that manages them...

            if (affected)
            {
                Vector2 leftPoint  = MathUtils.DirVec(msg.Direction + msg.Width) * msg.Radius;
                Vector2 rightPoint = MathUtils.DirVec(msg.Direction - msg.Width) * msg.Radius;

                Console.WriteLine($"Scanning with radius {msg.Radius}, in triangle <{msg.Origin}, {leftPoint}, {rightPoint}>");

                var iscanned = ShipsByToken.Values
                               .Where((ship) =>
                                      ship.Token != msg.Originator &&
                                      (MathUtils.CircleTriangleIntersection(ship.Pos, ship.Radius(), msg.Origin, leftPoint, rightPoint) ||
                                       MathUtils.CircleSegmentIntersection(ship.Pos, ship.Radius(), msg.Origin, msg.Radius, msg.Direction, msg.Width))
                                      )
                               .Select((ship) => new Messages.Struck.ShipInfo()
                {
                    Ship = ship
                });

                results.ShipsInfo.AddRange(iscanned);

                if (msg.ScaledShotEnergy > 0.0)
                {
                    foreach (var struck in results.ShipsInfo)
                    {
                        var ourShip = (LocalSpaceship)struck.Ship;

                        double shipDistance = (ourShip.Pos - msg.Origin).Length();
                        double damage       = MathUtils.ShotDamage(msg.ScaledShotEnergy, msg.Width, shipDistance);
                        double shielding    = MathUtils.ShieldingAmount(ourShip, msg.Origin, msg.Direction, msg.Width, msg.Radius);
                        if (shielding > 0.0)
                        {
                            Console.WriteLine($"{ourShip.PublicId} shielded itself for {shielding * 100.0}% of {msg.Originator}'s shot (= {damage * shielding} damage)");
                        }
                        damage *= (1.0 - shielding);

                        // We have killed a ship, gain it's kill reward, and move struck ship to the graveyard
                        if (ourShip.Area - damage < MINIMUM_AREA)
                        {
                            results.OriginatorAreaGain += ourShip.KillReward;
                            struck.Damage = -damage;
                        }
                        else // Struck ship survived - note that it's in combat
                        {
                            if (ourShip.LastUpdate - ourShip.LastCombat > LocalSpaceship.COMBAT_COOLDOWN)
                            {
                                // Reset kill reward when hit ship was not in combat
                                ourShip.KillReward = ourShip.Area;
                            }
                            ourShip.LastCombat = ourShip.LastUpdate;
                            ourShip.Area      -= damage;
                            struck.Damage      = damage;
                        }
                    }
                }
            }
            return(results);
        }
Exemple #5
0
 /// <summary>
 /// Returns a (area gain for shooter, list of struck ships) pair.
 /// </summary>
 public abstract Messages.Struck ScanShootLocal(Messages.ScanShoot msg);
Exemple #6
0
 public override Messages.Struck ScanShootLocal(Messages.ScanShoot msg)
 {
     return(new Messages.Struck());
 }
Exemple #7
0
 /// <summary>
 /// Called when a node sends a ScanShoot request; broadcasts the response from this node.
 /// </summary>
 private void OnScanShootReceived(NetPeer arbiterPeer, Messages.ScanShoot msg)
 {
     HandleLocalScanShoot(msg);
 }