Пример #1
0
 private void OnMenuChanged(object sender, MenuChangedEventArgs e)
 {
     if (!DeliveryEnabled())
     {
         return;
     }
     // remove old overlay
     if (this.CurrentOverlay != null)
     {
         this.CurrentOverlay?.Dispose();
         this.CurrentOverlay = null;
     }
     this.Monitor.Log("New menu: " + e.NewMenu?.GetType(), LogLevel.Trace);
     if (e.NewMenu is ItemGrabMenu igm && igm.context is Chest container)
     {
         DeliveryChest chest;
         if (!this.DeliveryChests.TryGetValue(container, out chest))
         {
             chest = new DeliveryChest(container);
             if (chest.Location == null)
             {
                 Monitor.Log($"Failed to find chest location.  Can't deliver to chest {container.Name}", LogLevel.Warn);
                 return;
             }
             DeliveryChests[container] = chest;
             Monitor.Log($"Creating DeliveryChest {chest.Location}", LogLevel.Trace);
         }
         this.Monitor.Log($"Applying DeliveryOverlay to {chest.Location}", LogLevel.Trace);
         this.Monitor.Log($"Send: {string.Join(", ", chest.DeliveryOptions.Send)} Receive: {string.Join(", ", chest.DeliveryOptions.Receive)}", LogLevel.Trace);
         this.CurrentOverlay = new DeliveryOverlay(this.Monitor, igm, chest, this.Helper, this.ModManifest.UniqueID, this.HostID);
     }
 }
Пример #2
0
 private DeliveryChest GetDeliveryChestFromMessage(SerializableChestLocation message)
 {
     foreach (GameLocation location in LocationHelper.GetAccessibleLocations())
     {
         if (location.NameOrUniqueName == message.Location)
         {
             Item item;
             if (message.isFridge)
             {
                 if (location is FarmHouse house && Game1.player.HouseUpgradeLevel > 0)
                 {
                     item = house.fridge.Value;
                 }
                 else
                 {
                     break;
                 }
             }
             else
             {
                 item = location.getObjectAtTile(message.X, message.Y);
             }
             if (item != null && item is Chest chest)
             {
                 DeliveryChest dchest;
                 if (DeliveryChests.TryGetValue(chest, out dchest))
                 {
                     return(dchest);
                 }
                 dchest = new DeliveryChest(chest);
                 DeliveryChests[chest] = dchest;
                 return(dchest);
             }
         }
     }
Пример #3
0
 private void MoveItems(DeliveryChest from, DeliveryChest to, Tuple <DeliveryCategories, int>[] filter)
 {
     // Store items because removing items aborts foreach()
     Item[] items = from.Chest.items.ToArray();
     foreach (Item item in items)
     {
         string type    = "";
         int    quality = 1;
         if (item is SObject obj)
         {
             type    = obj.Type;
             quality = 1 << obj.Quality;
         }
         DeliveryCategories cat = item.getDeliveryCategory();
         this.Monitor.Log($"Found existing item {item.Name} Type: {type} Category: {item.getCategoryName()} cat: {cat.Name()}", LogLevel.Trace);
         if (!filter.Any(x => x.Item1 == cat && (x.Item2 & quality) > 0))
         {
             continue;
         }
         Item chest_full = to.Chest.addItem(item);
         if (chest_full != null)
         {
             this.Monitor.Log($"Item {item.Name} will not fit in chest at {to.Location}", LogLevel.Info);
             continue;
         }
         //this.Monitor.Log($"Removing item", LogLevel.Trace);
         from.Chest.items.Remove(item);
     }
 }
Пример #4
0
 private void OnModMessageReceived(object sender, ModMessageReceivedEventArgs e)
 {
     //Monitor.Log($"Got message: {e.Type}", LogLevel.Debug);
     if (e.FromModID != this.ModManifest.UniqueID)
     {
         return;
     }
     if (e.Type == "UpdateDeliveryOptions")
     {
         SyncDataModel message = e.ReadAs <SyncDataModel>();
         DeliveryChest dchest  = GetDeliveryChestFromMessage(message);
         if (dchest != null)
         {
             //Monitor.Log($"Send:{string.Join(", ", message.DeliveryOptions.Send)}", LogLevel.Debug);
             dchest.DeliveryOptions.Set(message.DeliveryOptions);
             if (this.CurrentOverlay != null)
             {
                 this.CurrentOverlay.ResetEdit();
             }
         }
     }
     else if (e.Type == "RequestDeliveryOptions")
     {
         SerializableChestLocation message = e.ReadAs <SerializableChestLocation>();
         DeliveryChest             dchest  = GetDeliveryChestFromMessage(message);
         if (dchest != null)
         {
             Helper.Multiplayer.SendMessage(new SyncDataModel(dchest), "UpdateDeliveryOptions", modIDs: new[] { e.FromModID }, playerIDs: new[] { e.FromPlayerID });
         }
     }
 }
Пример #5
0
        private void Load(object sender, SaveLoadedEventArgs e)
        {
            CurrentOverlay = null;
            DeliveryChests = new Dictionary <Chest, DeliveryChest>();
            HostID         = 0;
            if (DeliveryEnabled() && Config.WaitForWizardShop)
            {
                Game1.addMailForTomorrow("DeliveryServiceWizardMail");
            }

            if (!Context.IsMainPlayer)
            {
                // Farmhands don't maintain state
                foreach (IMultiplayerPeer peer in this.Helper.Multiplayer.GetConnectedPlayers())
                {
                    if (peer.HasSmapi && peer.IsHost)
                    {
                        HostID = peer.PlayerID;
                        break;
                    }
                }
                return;
            }
            List <SaveDataModel> save = Helper.Data.ReadSaveData <List <SaveDataModel> >("delivery-service");

            if (save == null)
            {
                return;
            }
            foreach (SaveDataModel data in save)
            {
                DeliveryChest dchest = GetDeliveryChestFromMessage(data);
                if (dchest != null)
                {
                    int[] send    = new int[Enum.GetValues(typeof(DeliveryCategories)).Length];
                    int[] receive = new int[Enum.GetValues(typeof(DeliveryCategories)).Length];
                    foreach (DeliveryCategories cat in Enum.GetValues(typeof(DeliveryCategories)))
                    {
                        send[(int)cat]    = CheckCategoryEnabledInSave(cat, data.Send);
                        receive[(int)cat] = CheckCategoryEnabledInSave(cat, data.Receive);
                    }
                    dchest.DeliveryOptions.Set(send, receive, data.MatchColor);
                }
            }
        }
Пример #6
0
        /*********
        ** Accessors
        *********/

        /// <summary>The menu instance for which the overlay was created.</summary>
        public DeliveryOverlay(IMonitor monitor, ItemGrabMenu menu, DeliveryChest chest, IModHelper helper, string modid, long hostid)
            : base(helper.Events, helper.Input, keepAlive: () => Game1.activeClickableMenu is ItemGrabMenu)
        {
            this.Menu        = menu;
            this.Chest       = chest;
            this.Monitor     = monitor;
            this.Multiplayer = helper.Multiplayer;
            this.ModID       = modid;
            this.HostID      = hostid;
            this.origInventoryHighlighter = this.Menu.inventory.highlightMethod;
            this.origChestHighlighter     = this.Menu.ItemsToGrabMenu.highlightMethod;

            this.EditSaveButtonArea = new ClickableComponent(new Rectangle(0, 0, Game1.tileSize, Game1.tileSize), "save-delivery");
            this.SendCategories     = Category.CategoryList(chest.DeliveryOptions.Send);
            this.ReceiveCategories  = Category.CategoryList(chest.DeliveryOptions.Receive);
            this.MatchColor         = new Checkbox(chest.DeliveryOptions.MatchColor);
            //this.bounds = new Rectangle(this.Menu.xPositionOnScreen, this.Menu.yPositionOnScreen, this.Menu.width, this.Menu.Height);
            this.LabelHeight   = (int)Game1.smallFont.MeasureString("ABC").Y + 2;
            this.maxLabelWidth = 24 + 10 + (int)this.SendCategories.Select(p => Game1.smallFont.MeasureString(p.Name()).X).Max();
            int width =
                100 +                 // border
                this.maxLabelWidth +  // label
                40 + 10 * 26 +        // checkbox
                11 * Game1.pixelZoom; //scrollbar

            this.bounds = new Rectangle((Game1.viewport.Width - width) / 2, 10, width, Game1.viewport.Height - 20);

            this.scrollbar = new ScrollBar(helper.Events, helper.Input,
                                           new Rectangle(
                                               this.bounds.X + 10 * Game1.pixelZoom,
                                               this.bounds.Y + 10 * Game1.pixelZoom + 3 * LabelHeight,
                                               this.bounds.Width - 20 * Game1.pixelZoom,
                                               this.bounds.Height - 20 * Game1.pixelZoom - 5 * LabelHeight),
                                           this.SendCategories.Count,
                                           LabelHeight);
            if (!Context.IsMainPlayer)
            {
                this.Multiplayer.SendMessage(new SerializableChestLocation(chest), "RequestDeliveryOptions", modIDs: new[] { this.ModID }, playerIDs: new[] { this.HostID });
            }
        }
Пример #7
0
        private void DoDelivery()
        {
            List <DeliveryChest> toChests   = new List <DeliveryChest>();
            List <DeliveryChest> fromChests = new List <DeliveryChest>();

            // ignore if player hasn't loaded a save yet
            if (!Context.IsWorldReady)
            {
                return;
            }
            Chest[] containers = DeliveryChests.Keys.ToArray();
            foreach (Chest container in containers)
            {
                DeliveryChest chest = DeliveryChests[container];
                Monitor.Log($"chest:{chest} container:{container}, Chest:{chest.Chest} location:{chest.Location}", LogLevel.Trace);
                if (chest == null || !chest.Exists())
                {
                    this.Monitor.Log($"Chest {chest.Location} no longer exists", LogLevel.Trace);
                    DeliveryChests.Remove(container);
                    continue;
                }
                if (chest.DeliveryOptions.Send.Any(x => x > 0))
                {
                    fromChests.Add(chest);
                }
                if (chest.DeliveryOptions.Receive.Any(x => x > 0))
                {
                    toChests.Add(chest);
                }
            }
            foreach (DeliveryChest fromChest in fromChests)
            {
                bool match_color = fromChest.DeliveryOptions.MatchColor;
                foreach (DeliveryChest toChest in toChests)
                {
                    List <Tuple <DeliveryCategories, int> > categories = new List <Tuple <DeliveryCategories, int> >();
                    if (fromChest == toChest || (match_color && fromChest.Chest.playerChoiceColor != toChest.Chest.playerChoiceColor))
                    {
                        continue;
                    }
                    foreach (DeliveryCategories category in Enum.GetValues(typeof(DeliveryCategories)))
                    {
                        int mask = (fromChest.DeliveryOptions.Send[(int)category] & toChest.DeliveryOptions.Receive[(int)category]);
                        if (mask > 0)
                        {
                            // There is overlap between these chests
                            categories.Add(new Tuple <DeliveryCategories, int>(category, mask));
                        }
                    }
                    if (categories.Count == 0 || (fromChest.DeliveryOptions.MatchColor && fromChest.Chest.playerChoiceColor != toChest.Chest.playerChoiceColor))
                    {
                        continue;
                    }
                    this.Monitor.Log($"Moving {string.Join(", ", categories)} items from {fromChest.Location} -> {toChest.Location}", LogLevel.Trace);
                    MoveItems(
                        from: fromChest,
                        to: toChest,
                        filter: categories.ToArray());
                }
            }
        }