protected virtual bool FilterUpgradeSlotItem(BaseSlotItemInfo baseSlotItem, UpgradeSlotItemInfo upgradeSlotItem)
 {
     return true;
 }
 protected virtual bool FilterAssistant(BaseSlotItemInfo baseSlotItem, UpgradeSlotItemInfo upgradeSlotItem, AssistantInfo assistant)
 {
     return true;
 }
 protected virtual bool FilterBaseSlotItem(BaseSlotItemInfo baseSlotItem)
 {
     return true;
 }
        protected override bool FilterUpgradeSlotItem(BaseSlotItemInfo baseSlotItem, UpgradeSlotItemInfo upgradeSlotItem)
        {
            if (this.IsOnlyShowAvailable)
            {
                var materials = KanColleClient.Current.Homeport.Materials;
                var slotItems = KanColleClient.Current.Homeport.Itemyard.SlotItems;

                // 资材
                if (materials.Fuel < upgradeSlotItem.Fuel ||
                    materials.Ammunition < upgradeSlotItem.Ammo ||
                    materials.Steel < upgradeSlotItem.Steel ||
                    materials.Bauxite < upgradeSlotItem.Bauxite)
                {
                    return false;
                }

                var baseItems = slotItems.Values
                    .Where(s => s.Info == baseSlotItem.Info)
                    .ToArray();
                // All Lv Max & no upgrade
                if (upgradeSlotItem.Info == null && baseItems.All(s => s.Level == 10))
                {
                    return false;
                }

                // 不同等级阶段的开发资材/改修资材/装备消耗
                var lvs = new[] { 0, 6, 10, int.MaxValue };
                var canRemodel = upgradeSlotItem.Consumptions
                    .Where((t, i) => baseItems.Any(s => s.Level >= lvs[i] && s.Level < lvs[i + 1]))
                    .Aggregate(false, (c, v) => c | this.CheckConsumption(v));

                if (!canRemodel)
                {
                    return false;
                }
            }

            return base.FilterUpgradeSlotItem(baseSlotItem, upgradeSlotItem);
        }
        protected override bool FilterBaseSlotItem(BaseSlotItemInfo baseSlotItem)
        {
            if (IsOnlyShowCurrentDay)
            {
                // 今日不可改修
                if (!baseSlotItem.IsAvailable(this.CurrentDay)) return false;
            }

            if (this.IsOnlyShowAvailable)
            {
                // 无此装备
                if (KanColleClient.Current.Homeport.Itemyard.SlotItems.Values.All(s => s.Info != baseSlotItem.Info))
                {
                    return false;
                }
            }

            // filter
            if (this.SlotItemTypes != null)
            {
                var slotType = baseSlotItem.Info.EquipType;
                if (this.SlotItemTypes.Where(type => !type.IsSelected).Any(type => type.Equals(slotType)))
                {
                    return false;
                }
            }

            return base.FilterBaseSlotItem(baseSlotItem);
        }
        protected override bool FilterAssistant(BaseSlotItemInfo baseSlotItem, UpgradeSlotItemInfo upgradeSlotItem,
            AssistantInfo assistant)
        {
            if (this.IsOnlyShowCurrentDay)
            {
                // 今日不可改修
                if (!assistant.IsAvailable(this.CurrentDay)) return false;
            }

            if (this.IsOnlyShowAvailable)
            {
                // 需要二号舰
                if (assistant.ShipInfo != null)
                {
                    // 检查是否拥有舰娘
                    var shipId = assistant.ShipInfo.Id;
                    var client = KanColleClient.Current;
                    var set = new HashSet<int>();
                    while (client.Homeport.Organization.Ships.Values.All(ship => ship.Info.Id != shipId))
                    {
                        // 改造链循环(如霞改二/乙)
                        if (!set.Add(shipId)) return false;

                        int.TryParse(client.Master.Ships[shipId].RawData.api_aftershipid, out shipId);
                        // 没有后续改造舰娘
                        if (shipId == 0) return false;
                    }
                }
            }

            return base.FilterAssistant(baseSlotItem, upgradeSlotItem, assistant);
        }
        protected override bool FilterBaseSlotItem(BaseSlotItemInfo baseSlotItem)
        {
            if (!baseSlotItem.IsAvailable(this.CurrentDay)) return false;

            return base.FilterBaseSlotItem(baseSlotItem);
        }
 protected override bool FilterAssistant(BaseSlotItemInfo baseSlotItem, UpgradeSlotItemInfo upgradeSlotItem, AssistantInfo assistant)
 {
     return base.FilterAssistant(baseSlotItem, upgradeSlotItem, assistant) && assistant.IsAvailable(this.CurrentDay);
 }