Пример #1
0
        /// <summary>
        /// Does the action.
        /// </summary>
        public override void DoAction()
        {
            if (!this.SetNextActionDelay(NpcShipBase.DelayBeforeNextAction))
            {
                return;
            }

            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();
            Ship npcShip = this.npcRow.Ship;

            // Check if we are still traveling
            npcShip.CheckIfTraveling();

            // Check if we are currently in combat
            if (npcShip.InProgressCombat != null)
            {
                // In Combat!
                this.DoCombat();
            }
            else if (this.npcRow.NextTravelTime < DateTime.UtcNow)
            {
                // Check if we need to give this pirate some credits
                if (npcShip.Credits < BaseCreditAmount)
                {
                    // Poor pirate has no gold, give him some to start
                    npcShip.Credits = BaseCreditAmount;
                }

                // Attack?
                if (this.rnd.SelectByProbablity(new bool[] { true, false }, new double[] { 0.50, 0.50 }))
                {
                    this.DoAttack();
                }
                else
                {
                    this.DoTravel();
                }

                this.SetNextTravelTime();
            }
            else
            {
                /*
                 * Dictionary<string, object> props = new Dictionary<string, object>
                 * {
                 *  { "NpcId", this.npcRow.NpcId },
                 *  { "NextTravelTime", this.npcRow.NextTravelTime },
                 *  { "UtcNow", DateTime.UtcNow }
                 * };
                 * Logger.Write("Waiting for NextTravelTime", "NPC", 200, 0, TraceEventType.Verbose, "Pirate Wait", props);
                 */
            }

            db.SaveChanges();
        }
Пример #2
0
        /// <summary>
        /// Sets the delay before the next action will be taken for this Npc again.
        /// </summary>
        /// <param name="delay">The delay before the next scheduled action.</param>
        /// <returns>true is time has been set, false if another thread has already ran (Npc should exit)</returns>
        protected bool SetNextActionDelay(TimeSpan delay)
        {
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Mark the next time this NPC will need to do an action
            this.npcRow.NextActionTime = DateTime.UtcNow.Add(delay);

            db.SaveChanges();

            return(true);
        }
Пример #3
0
        /// <summary>
        /// Does the action.
        /// </summary>
        public override void DoAction()
        {
            if (!this.SetNextActionDelay(NpcShipBase.DelayBeforeNextAction))
            {
                return;
            }

            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();
            Ship npcShip = this.npcRow.Ship;

            // Check if we are still traveling
            npcShip.CheckIfTraveling();

            // Check if we are currently in combat
            if (npcShip.InProgressCombat != null)
            {
                // In Combat!
                this.DoCombat();
            }
            else if (this.npcRow.NextTravelTime < DateTime.UtcNow)
            {
                // Search?
                if (this.rnd.SelectByProbablity(new bool[] { true, false }, new double[] { 0.50, 0.50 }))
                {
                    this.DoSearch();
                }
                else
                {
                    this.DoTravel();
                }

                this.SetNextTravelTime();
            }

            db.SaveChanges();
        }
Пример #4
0
        /// <summary>
        /// Balances the number of NPCs vs Active Players to keep the galaxy alive.
        /// </summary>
        public override void DoAction()
        {
            // Set next run time to 1 hour
            if (!this.SetNextActionDelay(new TimeSpan(1, 0, 0)))
            {
                return;
            }

            // Balance Npcs
            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();

            // Find the number of players active in the last hour on the galaxy
            int activePlayerCount = (from p in db.Players
                                     where p.LastPlayed > DateTime.UtcNow.AddHours(-1)
                                     select p).Count();

            // Calculate how many Npcs we need
            int neededNpcs = NpcBalancer.TargetActivePlayers - activePlayerCount;

            // Make sure we don't go below the min amount
            neededNpcs = Math.Max(neededNpcs, NpcBalancer.MinNpcs);

            // Grab the active NPCs we currently have
            IQueryable <Npc> activeNpcs = (from n in db.Npcs
                                           where n.NType == Npc.NpcType.Pirate ||
                                           n.NType == Npc.NpcType.Police ||
                                           n.NType == Npc.NpcType.Trader
                                           select n);

            // Calculate how many NPCs we need to create/delete
            int npcAdjustment = neededNpcs - activeNpcs.Count();

            if (npcAdjustment > 0)
            {
                while (npcAdjustment-- > 0)
                {
                    // Produce NPCs
                    Npc     newNpc = new Npc();
                    NpcBase npc    = null;

                    // Which type will we produce?
                    Npc.NpcType[] npcTypes      = { Npc.NpcType.Pirate, Npc.NpcType.Trader, Npc.NpcType.Police };
                    double[]      npcProbablity = { NpcBalancer.PercentPirates, NpcBalancer.PercentTraders, NpcBalancer.PercentPolice };
                    newNpc.NType = this.rnd.SelectByProbablity(npcTypes, npcProbablity);

                    switch (newNpc.NType)
                    {
                    case Npc.NpcType.Pirate:
                        // Produce pirate
                        npc = new NpcPirate(newNpc);
                        break;

                    case Npc.NpcType.Trader:
                        // Produce trader
                        npc = new NpcTrader(newNpc);
                        break;

                    case Npc.NpcType.Police:
                        // Produce Police
                        npc = new NpcPolice(newNpc);
                        break;

                    default:
                        throw new InvalidOperationException("Unknown NpcType selected");
                    }

                    // Give the NPC a good name
                    string npcName = (from name in db.NpcNames
                                      where name.NType == newNpc.NType &&
                                      !(from n in db.Npcs
                                        select n.Name)
                                      .Contains(name.Name)
                                      select name.Name).FirstOrDefault();

                    // Break out if we couldn't find a new name
                    if (npcName == null)
                    {
                        Logger.Write(newNpc.NType.ToString(), "NPC", 1000, 0, TraceEventType.Critical, "Out of NPC Names");
                        break;
                    }

                    // Give the NPC the cool name
                    newNpc.Name = npcName;

                    // Add to the database
                    db.Npcs.InsertOnSubmit(newNpc);

                    // Setup the NPC
                    npc.Setup();

                    db.SaveChanges();
                }
            }
            else if (npcAdjustment < 0)
            {
                // TODO: Delete or inactive NPCs

                /*
                 * // Query the NPCs to delete
                 * IQueryable<Npc> npcsToDelete = activeNpcs.Take(Math.Abs(npcAdjustment));
                 * if (npcsToDelete.Any())
                 * {
                 *  // Remove the NPCs
                 *  db.Npcs.DeleteAllOnSubmit(npcsToDelete);
                 *
                 *  IQueryable<Ship> npcShips = (from n in activeNpcs
                 *                               select n.Ship);
                 *  if (npcShips.Any())
                 *  {
                 *      IQueryable<ShipGood> npcShipGoods = (from g in db.ShipGoods
                 *                                           where npcShips.Contains(g.Ship)
                 *                                           select g);
                 *      if (npcShipGoods.Any())
                 *      {
                 *          // Remove the ship goods
                 *          db.ShipGoods.DeleteAllOnSubmit(npcShipGoods);
                 *      }
                 *
                 *      // Remove the ships
                 *      db.Ships.DeleteAllOnSubmit(npcShips);
                 *  }
                 * }
                 */
            }

            db.SaveChanges();
        }
Пример #5
0
        /// <summary>
        /// Does the action.
        /// </summary>
        public override void DoAction()
        {
            if (!this.SetNextActionDelay(NpcTrader.DelayBeforeNextAction))
            {
                return;
            }

            CosmoMongerDbDataContext db = CosmoManager.GetDbContext();
            Ship npcShip = this.npcRow.Ship;

            // Check if we are still traveling
            npcShip.CheckIfTraveling();

            // Check if we are currently in combat
            if (npcShip.InProgressCombat != null)
            {
                // In Combat!
                this.DoCombat();
            }
            else if (this.npcRow.NextTravelTime < DateTime.UtcNow)
            {
                // Create an array of goods that the Trader has onboard
                ShipGood[] goods = npcShip.GetGoods().Where(g => g.Quantity > 0).ToArray();

                // goodCount != 0, sell all the trader's goods
                foreach (ShipGood good in goods)
                {
                    // Get the number of this good type onboard the Trader's ship
                    int shipGoodQuantity = good.Quantity;

                    // Find the price of the good
                    int shipGoodPrice = 0;

                    try
                    {
                        good.Sell(npcShip, shipGoodQuantity, shipGoodPrice);
                    }
                    catch (InvalidOperationException ex)
                    {
                        // Log this exception
                        ExceptionPolicy.HandleException(ex, "NPC Policy");
                    }
                }

                // This is the minimum amount of money a trader should have before buying goods
                int baseCreditsSizeAdjusted = BaseCreditMultiplier * npcShip.CargoSpaceTotal;

                // Check if we need to give this trader some credits
                if (npcShip.Credits < baseCreditsSizeAdjusted)
                {
                    // Poor trader has no credits, give him some to start
                    npcShip.Credits = baseCreditsSizeAdjusted;
                }

                // Trader buys first good
                SystemGood good1 = (from g in npcShip.CosmoSystem.SystemGoods
                                    orderby(g.PriceMultiplier) ascending
                                    select g).FirstOrDefault();

                // This is the maximum number a Trader can purchase
                double numberCanBuy = Math.Floor((double)npcShip.Credits / good1.Price);

                // This is the maximum number we want the Trader to purchase
                double numberToBuy = Math.Ceiling((double)npcShip.CargoSpaceFree / 2);

                // Make sure that the Trader buys as many of good1 as credits allow
                int numberBuying = (int)Math.Min(numberCanBuy, numberToBuy);

                // Insures that Traders attempt to buy the proper number of good1
                int properNumber = (int)Math.Min(numberBuying, good1.Quantity);

                try
                {
                    good1.Buy(npcShip, properNumber, good1.Price);
                }
                catch (InvalidOperationException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "NPC Policy");
                }

                // Find all the systems within range
                CosmoSystem[] inRangeSystems = npcShip.GetInRangeSystems();

                // Finds the system with the highest PriceMultiplier
                CosmoSystem targetSystem = (from g in db.SystemGoods
                                            where inRangeSystems.Contains(g.CosmoSystem) &&
                                            g.Good == good1.Good
                                            orderby(g.PriceMultiplier) descending
                                            select g.CosmoSystem).FirstOrDefault();

                // Get references to the Good entities for all the SystemGoods sold in the target system
                IEnumerable <Good> goodsInTargetSystem = targetSystem.SystemGoods.Select(g => g.Good);

                // Get references to the Good entites for the all the SystemGoods sold in the current system
                IEnumerable <Good> goodsInCurrentSystem = npcShip.CosmoSystem.SystemGoods.Select(g => g.Good);

                // Do an intersetion of both, getting a list of goods sold in both systems
                IEnumerable <Good> goodsInBoth = goodsInTargetSystem.Intersect(goodsInCurrentSystem);

                // Look in the current system for goods sold in both, sorting by PriceMultiplier (lowest at top)
                // and taking the top good in the results
                SystemGood good2 = (from g in npcShip.CosmoSystem.SystemGoods
                                    where goodsInBoth.Contains(g.Good) &&
                                    g != good1
                                    orderby g.PriceMultiplier ascending
                                    select g).FirstOrDefault();

                // This is the maximum number a Trader can purchase
                numberCanBuy = Math.Floor((double)npcShip.Credits / good2.Price);

                // This is the maximum number we want the Trader to purchase
                numberToBuy = Math.Ceiling((double)npcShip.CargoSpaceFree);

                // Make sure that the Trader buys as many of good1 as credits allow
                numberBuying = (int)Math.Min(numberCanBuy, numberToBuy);

                // Insures that Traders attempt to buy the proper number of good1
                properNumber = (int)Math.Min(numberBuying, good2.Quantity);

                try
                {
                    good2.Buy(npcShip, properNumber, good2.Price);
                }
                catch (InvalidOperationException ex)
                {
                    // Log this exception
                    ExceptionPolicy.HandleException(ex, "NPC Policy");
                }

                this.DoTravel(targetSystem);

                // Set next travel time
                this.npcRow.NextTravelTime = DateTime.UtcNow.AddSeconds(this.rnd.Next(60, 120));
            }
            else
            {
                Dictionary <string, object> props = new Dictionary <string, object>
                {
                    { "NpcId", this.npcRow.NpcId },
                    { "NextTravelTime", this.npcRow.NextTravelTime },
                    { "UtcNow", DateTime.UtcNow }
                };
                Logger.Write("Waiting for NextTravelTime", "NPC", 200, 0, TraceEventType.Verbose, "Trader Wait", props);
            }

            db.SaveChanges();
        }