Esempio n. 1
0
        private void TestArmorSlots(ISet <Type> equippedAbilityEnablingItemTypes)
        {
            int maxAccSlot = PlayerItemLibraries.GetCurrentVanillaMaxAccessories(this.player)
                             + PlayerItemLibraries.VanillaAccessorySlotFirst;

            string alert;

            // Test each item against equipped ability items
            for (int slot = 0; slot < maxAccSlot; slot++)
            {
                Item item = this.player.armor[slot];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (!this.TestArmorAgainstMissingAbilities(equippedAbilityEnablingItemTypes, slot, out alert))
                {
                    Main.NewText(alert, Color.Yellow);
                    PlayerItemLibraries.DropEquippedArmorItem(this.player, slot, 0);
                    continue;
                }
            }

            this.TestAccessorySlotCapacity();
        }
        /*public override void PostDrawInterface( SpriteBatch sb ) {
         *      if( Main.playerInventory && Main.EquipPage == 0 ) {	//== 2 is misc page
         *              this.DrawAccessoryOverlays( sb );
         *      }
         * }*/


        private void DrawDisabledAccessorySlotOverlays(SpriteBatch sb)
        {
            var myplayer = TmlLibraries.SafelyGetModPlayer <LockedAbilitiesPlayer>(Main.LocalPlayer);

            if (myplayer.TotalAllowedAccessorySlots < 0)
            {
                return;
            }

            int firstAccSlot = PlayerItemLibraries.VanillaAccessorySlotFirst;
            int maxAcc       = PlayerItemLibraries.GetCurrentVanillaMaxAccessories(Main.LocalPlayer) + firstAccSlot;
            int myMaxAcc     = myplayer.TotalAllowedAccessorySlots;

            for (int i = firstAccSlot; i < maxAcc; i++)
            {
                if ((i - firstAccSlot) < myMaxAcc)
                {
                    continue;
                }

                var pos = HUDElementLibraries.GetVanillaAccessorySlotScreenPosition(i - firstAccSlot);
                pos.X += 8;
                pos.Y += 8;

                sb.Draw(this.DisabledItemTex, pos, Color.White);
            }
        }
Esempio n. 3
0
        public override bool?CanUseGrapple(int projType, Player player)
        {
            var mymod   = (NihilismMod)this.mod;
            var myworld = ModContent.GetInstance <NihilismWorld>();

            if (myworld.Logic == null)
            {
                return(null);
            }

            if (!myworld.Logic.AreItemFiltersEnabled())
            {
                return(null);
            }

            Item grappleItem = PlayerItemLibraries.GetGrappleItem(player);

            bool _;

            if (grappleItem != null && myworld.Logic.DataAccess.IsItemEnabled(grappleItem, out _, out _))
            {
                return(null);
            }
            return(false);
        }
        public override void UseGrapple(Player player, ref int type)
        {
            var config   = LockedAbilitiesConfig.Instance;
            int chainAmt = config.Get <int>(nameof(LockedAbilitiesConfig.GrappleRequiresChainAmount));

            if (chainAmt > 0)
            {
                int idx = ItemFinderLibraries.FindIndexOfFirstOfItemInCollection(
                    player.inventory,
                    new HashSet <int> {
                    ItemID.Chain
                }
                    );

                if (idx == -1)
                {
                    Main.NewText("No chains available for grappling.", Color.Yellow);
                    return;
                }

                PlayerItemLibraries.RemoveInventoryItemQuantity(
                    player,
                    ItemID.Chain,
                    chainAmt
                    );
            }
        }
        ////////////////

        public static bool IsAmmoSourceAvailable(Player player, bool skipSpeedloaders, out string result)
        {
            var config = TMRConfig.Instance;

            if (config.Get <bool>(nameof(TMRConfig.InfiniteAmmoCheat)))
            {
                result = "Cheater.";
                return(true);
            }

            if (!skipSpeedloaders)
            {
                int speedloaderType = ModContent.ItemType <SpeedloaderItem>();

                for (int i = 0; i < player.inventory.Length; i++)
                {
                    Item item = player.inventory[i];
                    if (item == null || item.IsAir || item.type != speedloaderType)
                    {
                        continue;
                    }

                    var myitem = item.modItem as SpeedloaderItem;
                    if ((myitem?.LoadedRounds ?? 0) > 0)
                    {
                        result = " Speedloader available.";
                        return(true);
                    }
                }
                result = "Loaded speedloader needed.";
            }
            else
            {
                result = "Cannot reload.";
            }

            if (config.Get <bool>(nameof(TMRConfig.BandolierNeededToReload)))
            {
                int bandolierType = ModContent.ItemType <BandolierItem>();
                int max           = PlayerItemLibraries.VanillaAccessorySlotFirst
                                    + PlayerItemLibraries.GetCurrentVanillaMaxAccessories(player);

                for (int i = PlayerItemLibraries.VanillaAccessorySlotFirst; i < max; i++)
                {
                    Item item = player.armor[i];
                    if (item == null || item.IsAir || item.type != bandolierType)
                    {
                        continue;
                    }

                    result = "Bandolier available.";
                    return(true);
                }
                result = "Bandolier needed.";
            }

            return(false);
        }
        private void BlockEquipsIfDisabled()
        {
            var mymod = (NihilismMod)this.mod;

            if (!NihilismConfig.Instance.EnableItemEquipsFilters)
            {
                return;
            }

            var myworld = ModContent.GetInstance <NihilismWorld>();

            if (myworld.Logic == null)
            {
                return;
            }
            if (!myworld.Logic.DataAccess.IsActive())
            {
                return;
            }

            bool _;

            for (int i = 0; i < this.player.armor.Length; i++)
            {
                Item item = this.player.armor[i];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (!myworld.Logic.DataAccess.IsItemEnabled(item, out _, out _))
                {
                    PlayerItemLibraries.DropEquippedArmorItem(player, i);
                }
            }

            for (int i = 0; i < this.player.miscEquips.Length; i++)
            {
                Item item = this.player.armor[i];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (!myworld.Logic.DataAccess.IsItemEnabled(item, out _, out _))
                {
                    PlayerItemLibraries.DropEquippedMiscItem(player, i);
                }
            }

            if (mymod.WingSlotMod != null)
            {
                this.BlockWingSlotIfDisabled("EquipSlot");
                this.BlockWingSlotIfDisabled("VanitySlot");
            }
        }
		////////////////

		private void UpdateDoubleJumps( bool isOnGround ) {
			if( !LockedAbilitiesConfig.Instance.Get<bool>( nameof(LockedAbilitiesConfig.DoubleJumpsRequireGels) ) ) {
				return;
			}

			if( !isOnGround ) {
				if( this.player.jump == 0 ) {
					if( !this.player.inventory.Any( i => i != null && !i.IsAir && i.type == ItemID.Gel ) ) {
						bool hadDoubleJump = this.player.jumpAgainBlizzard
							|| this.player.jumpAgainCloud
							|| this.player.jumpAgainFart
							|| this.player.jumpAgainSail
							|| this.player.jumpAgainSandstorm;

						if( hadDoubleJump ) {
							Main.NewText( "Need gels to double jump.", Color.Yellow );
						}

						this.player.jumpAgainBlizzard = false;
						this.player.jumpAgainCloud = false;
						this.player.jumpAgainFart = false;
						this.player.jumpAgainSail = false;
						this.player.jumpAgainSandstorm = false;
					}
				}

				if( this.player.doubleJumpBlizzard && !this.player.jumpAgainBlizzard && !this.HasBlizzardJumped ) {
					this.HasBlizzardJumped = true;
					PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.Gel, 1 );
				} else
				if( this.player.doubleJumpCloud && !this.player.jumpAgainCloud && !this.HasCloudJumped ) {
					this.HasCloudJumped = true;
					PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.Gel, 1 );
				} else
				if( this.player.doubleJumpFart && !this.player.jumpAgainFart && !this.HasFartJumped ) {
					this.HasFartJumped = true;
					PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.Gel, 1 );
				} else
				if( this.player.doubleJumpSail && !this.player.jumpAgainSail && !this.HasSailJumped ) {
					this.HasSailJumped = true;
					PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.Gel, 1 );
				}
				if( this.player.doubleJumpSandstorm && !this.player.jumpAgainSandstorm && !this.HasSandstormJumped ) {
					this.HasSandstormJumped = true;
					PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.Gel, 1 );
				}
			} else {
				this.HasBlizzardJumped = false;
				this.HasCloudJumped = false;
				this.HasFartJumped = false;
				this.HasSailJumped = false;
				this.HasSandstormJumped = false;
			}
		}
Esempio n. 8
0
        public override bool ConsumeItem(Player player)
        {
            var  myplayer            = TmlLibraries.SafelyGetModPlayer <LockedAbilitiesPlayer>(player);
            int  vanillaMaxAcc       = PlayerItemLibraries.GetCurrentVanillaMaxAccessories(player);
            bool canIncreaseAccSlots = myplayer.InternalAllowedAccessorySlots >= 0 &&
                                       myplayer.InternalAllowedAccessorySlots < vanillaMaxAcc;

            if (canIncreaseAccSlots)
            {
                myplayer.IncreaseAllowedAccessorySlots();
            }
            return(canIncreaseAccSlots);
        }
        ////////////////

        internal void UpdateRuinedAccessoriesForPlayer(Player player)
        {
            for (int i = PlayerItemLibraries.VanillaAccessorySlotFirst; PlayerItemLibraries.IsAccessorySlot(player, i); i++)
            {
                Item accItem = player.armor[i];
                if (accItem?.active != true || accItem.prefix != ModContent.PrefixType <RuinedPrefix>())
                {
                    continue;
                }

                this.ConveyRuinedAccessoryStatsToPlayer(player);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Gets a formatted collection of a player's body equipment.
        /// </summary>
        /// <param name="player"></param>
        /// <returns></returns>
        public static IDictionary <string, string> GetPlayerEquipment(Player player)
        {
            var dict = new Dictionary <string, string>();
            int acc  = 1;
            int van  = 1;
            int unk  = 1;

            for (int i = 0; i < player.armor.Length; i++)
            {
                string key;
                Item   item = player.armor[i];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (i == 0)
                {
                    key = "Head";
                }
                else if (i == 1)
                {
                    key = "Body";
                }
                else if (i == 2)
                {
                    key = "Legs";
                }
                else if (PlayerItemLibraries.IsAccessorySlot(player, i))
                {
                    key = "Accessory " + acc;
                    acc++;
                }
                else if (PlayerItemLibraries.IsVanitySlot(player, i))
                {
                    key = "Vanity " + van;
                    van++;
                }
                else
                {
                    key = "? " + unk;
                    unk++;
                }

                dict[key] = item.HoverName;
            }

            return(dict);
        }
Esempio n. 11
0
        ////////////////

        public override void UpdateEquips(ref bool wallSpeedBuff, ref bool tileSpeedBuff, ref bool tileRangeBuff)
        {
            int maxAccSlot     = 3 + PlayerItemLibraries.GetCurrentVanillaMaxAccessories(this.player);
            int hookBracerType = ModContent.ItemType <TensionedHookBracerItem>();

            this.IsEquippingTensionedHookBracer = false;

            for (int i = 3; i < maxAccSlot; i++)
            {
                if (!(this.player.armor[i]?.IsAir ?? false) && this.player.armor[i].type == hookBracerType)
                {
                    this.IsEquippingTensionedHookBracer = true;
                    break;
                }
            }
        }
		private void ConsumePixieDust() {
			PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.PixieDust, 1 );

			for( int i=0; i<4; i++ ) {
				int dustIdx = Dust.NewDust(
					Position: this.player.position,
					Height: this.player.width,
					Width: this.player.height,
					Type: 55,
					SpeedX: 0f,
					SpeedY: 0f,
					Alpha: 200,
					newColor: Color.White,
					Scale: 1f
				);
				Main.dust[dustIdx].velocity *= 0.3f;
			}
		}
Esempio n. 13
0
        ////////////////

        private IList <Item> GetEquippedAbilityItems()
        {
            int firstAccSlot = PlayerItemLibraries.VanillaAccessorySlotFirst;
            int maxAccSlot   = PlayerItemLibraries.GetCurrentVanillaMaxAccessories(player) + firstAccSlot;
            var items        = new List <Item>();

            for (int i = firstAccSlot; i < maxAccSlot; i++)
            {
                Item item = player.armor[i];
                if (item == null || item.IsAir || item.modItem == null || !(item.modItem is IAbilityAccessoryItem))
                {
                    continue;
                }

                items.Add(item);
            }

            return(items);
        }
        ////////////////

        public bool PickupIntoJarIf(Player player, out bool isError)
        {
            if (player.HeldItem?.IsAir != false)
            {
                isError = false;
                return(false);
            }

            int emptyJarType = ModContent.ItemType <EmptyCanopicJarItem>();

            if (player.HeldItem?.type != emptyJarType)
            {
                isError = false;
                return(false);
            }

            if (PlayerItemLibraries.RemoveInventoryItemQuantity(player, emptyJarType, 1) == 0)
            {
                Main.NewText("Could not fill jar.", Color.Yellow);
                isError = true;
                return(false);
            }

            int itemWho = Item.NewItem(
                position: player.position,
                Type: ModContent.ItemType <FilledCanopicJarItem>(),
                Stack: 1,
                noBroadcast: false,
                prefixGiven: 0,
                noGrabDelay: true
                );

            if (Main.netMode == NetmodeID.MultiplayerClient)
            {
                NetMessage.SendData(MessageID.SyncItem, -1, -1, null, itemWho, 1f, 0f, 0f, 0, 0, 0);
            }

            Main.PlaySound(SoundID.Drip, this.item.Center, 2);

            isError = false;
            return(true);
        }
        public override bool?CanUseGrapple(int projType, Player player)
        {
            var config = LockedAbilitiesConfig.Instance;

            if (config.Get <int>(nameof(LockedAbilitiesConfig.GrappleRequiresChainAmount)) > 0)
            {
                int idx = ItemFinderLibraries.FindIndexOfFirstOfItemInCollection(
                    player.inventory,
                    new HashSet <int> {
                    ItemID.Chain
                }
                    );

                if (idx == -1)
                {
                    return(false);
                }
            }

            if (!config.Get <bool>(nameof(config.GrappleHarnessEnabled)))
            {
                return(null);
            }

            int grappleHarnessType = ModContent.ItemType <GrappleHarnessItem>();
            int utilBeltType       = ModContent.ItemType <UtilitarianBeltItem>();
            int firstAccSlot       = PlayerItemLibraries.VanillaAccessorySlotFirst;
            int lastAccSlot        = PlayerItemLibraries.GetFirstVanitySlot(player);

            for (int i = firstAccSlot; i < lastAccSlot; i++)
            {
                Item item = player.armor[i];
                if (item?.active != true || (item.type != grappleHarnessType && item.type != utilBeltType))
                {
                    continue;
                }

                return(true);
            }

            return(false);
        }
Esempio n. 16
0
        ////////////////

        public override bool PreItemCheck()
        {
            if (!Main.mouseLeft && !Main.mouseRight)
            {
                return(base.PreItemCheck());
            }

            string timerName = "LockedAbilitiesEquipCheck_" + this.player.whoAmI;

            if (Timers.GetTimerTickDuration(timerName) > 0)
            {
                Timers.SetTimer(timerName, 2, false, () => false);
                return(false);
            }

            int         firstAccSlot             = PlayerItemLibraries.VanillaAccessorySlotFirst;
            int         maxAccSlot               = PlayerItemLibraries.GetCurrentVanillaMaxAccessories(this.player) + firstAccSlot;
            ISet <Type> equippedAbilityItemTypes = new HashSet <Type>();

            // Find equipped ability items
            for (int i = firstAccSlot; i < maxAccSlot; i++)
            {
                Item item = this.player.armor[i];
                if (item == null || item.IsAir || item.modItem == null || !(item.modItem is IAbilityAccessoryItem))
                {
                    continue;
                }

                equippedAbilityItemTypes.Add(item.modItem.GetType());
            }

            if (!this.TestEquipItem(equippedAbilityItemTypes, this.player.HeldItem))
            {
                Timers.SetTimer(timerName, 2, false, () => false);
                return(false);
            }

            return(base.PreItemCheck());
        }
        private void TestMiscSlots(ISet <Type> abilityItemTypes)
        {
            int maxMiscSlot = this.player.miscEquips.Length;

            string alert;

            // Test each item against equipped ability items
            for (int slot = 0; slot < maxMiscSlot; slot++)
            {
                Item item = this.player.miscEquips[slot];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (!this.TestMiscAgainstMissingAbilities(abilityItemTypes, slot, out alert))
                {
                    Main.NewText(alert, Color.Yellow);
                    PlayerItemLibraries.DropEquippedMiscItem(this.player, slot, 0);
                    continue;
                }
            }
        }
        private void BlockEquipsIf()
        {
            var config = RuinedItemsConfig.Instance;

            if (!config.Get <bool>(nameof(config.RuinedItemsLockedFromUse)))
            {
                return;
            }

            for (int i = 0; i < this.player.armor.Length; i++)
            {
                Item item = this.player.armor[i];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (item.prefix == ModContent.PrefixType <RuinedPrefix>())
                {
                    PlayerItemLibraries.DropEquippedArmorItem(player, i);
                }
            }

            for (int i = 0; i < this.player.miscEquips.Length; i++)
            {
                Item item = this.player.armor[i];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                if (item.prefix == ModContent.PrefixType <RuinedPrefix>())
                {
                    PlayerItemLibraries.DropEquippedMiscItem(player, i);
                }
            }
        }
Esempio n. 19
0
        private void CheckTrackKitResume(int heldTrackKitItemType)
        {
            if (!this.player.mount.Active || !this.player.mount.Cart)
            {
                return;
            }

            var trackKitSingleton = ModContent.GetInstance <TrackDeploymentKitItem>();

            (int x, int y, int dir)resume = trackKitSingleton.ResumeDeploymentAt;
            var resumeWldPos = new Vector2((resume.x << 4) + 8, (resume.y << 4) + 8);

            if (Vector2.DistanceSquared(this.player.Center, resumeWldPos) >= 4096)                // 4 tiles
            {
                return;
            }

            PlayerItemLibraries.RemoveInventoryItemQuantity(this.player, heldTrackKitItemType, 1);

            int leftovers = TrackDeploymentKitItem.Redeploy(this.player.whoAmI);

            if (leftovers == 0)
            {
                return;
            }

            int itemWho = Item.NewItem(resumeWldPos, ItemID.MinecartTrack, leftovers);

            if (Main.netMode != NetmodeID.MultiplayerClient)
            {
                NetMessage.SendData(MessageID.SyncItem, -1, -1, null, itemWho, 1f);
            }
            else
            {
                TrackKitDeployProtocol.SendToServer(resume.dir > 0, resume.x, resume.y, true);
            }
        }
        private void TestMountState()
        {
            var config = LockedAbilitiesConfig.Instance;

            if (!config.Get <bool>(nameof(config.MountReinEnabled)))
            {
                return;
            }

            if (!this.player.mount.Active || this.player.mount.Cart)
            {
                return;
            }

            int mountReinType = ModContent.ItemType <MountReinItem>();
            int utilBeltType  = ModContent.ItemType <UtilitarianBeltItem>();
            int firstAccSlot  = PlayerItemLibraries.VanillaAccessorySlotFirst;
            int lastAccSlot   = PlayerItemLibraries.GetFirstVanitySlot(player);

            for (int i = firstAccSlot; i < lastAccSlot; i++)
            {
                Item item = player.armor[i];
                if (item?.active != true || (item.type != mountReinType && item.type != utilBeltType))
                {
                    continue;
                }

                return;
            }

            var mountReinItem = ModContent.GetInstance <MountReinItem>();
            var utilBeltItem  = ModContent.GetInstance <UtilitarianBeltItem>();

            Main.NewText("Need " + mountReinItem.item.Name + " or " + utilBeltItem.item.Name + " to equip.", Color.Yellow);

            this.player.mount.Dismount(this.player);
        }
Esempio n. 21
0
        ////////////////

        private void TestAccessorySlotCapacity()
        {
            if (this.TotalAllowedAccessorySlots < 0)
            {
                return;
            }

            int firstAccSlot = PlayerItemLibraries.VanillaAccessorySlotFirst;
            int maxAccSlot   = PlayerItemLibraries.GetCurrentVanillaMaxAccessories(this.player) + firstAccSlot;

            // Test max accessory slots
            for (int slot = (firstAccSlot + this.TotalAllowedAccessorySlots); slot < maxAccSlot; slot++)
            {
                Item item = this.player.armor[slot];
                if (item == null || item.IsAir)
                {
                    continue;
                }

                Main.NewText("Invalid accessory slot.", Color.Yellow);
                PlayerItemLibraries.DropEquippedArmorItem(this.player, slot, 0);
                break;
            }
        }
		private void UpdateRocketBoots( bool isOnGround ) {
			if( !LockedAbilitiesConfig.Instance.Get<bool>( nameof(LockedAbilitiesConfig.RocketBootsRequireGels) ) ) {
				return;
			}

			if( this.player.rocketBoots == 0 ) {
				return;
			}

			if( !isOnGround ) {
				if( this.player.rocketTime > 1 ) {
					if( !this.player.inventory.Any( i => i != null && !i.IsAir && i.type == ItemID.Gel ) ) {
						this.player.rocketTime = 1;
					} else if( this.player.rocketTime > 0 && this.player.rocketTime < this.player.rocketTimeMax ) {
						if( !this.HasRocketChecked ) {
							this.HasRocketChecked = true;
							PlayerItemLibraries.RemoveInventoryItemQuantity( this.player, ItemID.Gel, 1 );
						}
					}
				}
			} else {
				this.HasRocketChecked = false;
			}
		}
Esempio n. 23
0
        ////////////////

        /// <summary>
        /// Totals up player's money.
        /// </summary>
        /// <param name="player"></param>
        /// <param name="includeBanks"></param>
        /// <returns></returns>
        public static long CountMoney(Player player, bool includeBanks)
        => PlayerItemLibraries.CountMoney(player, includeBanks);
Esempio n. 24
0
        /// <summary>
        /// Reports all the reasons a given recipe for a givne player will fail with a given set of ingredients (defaults to
        /// the player's inventory).
        /// </summary>
        /// <param name="player"></param>
        /// <param name="recipe"></param>
        /// <param name="missingTile">Returns the tile IDs (crafting stations) needed for the recipe.</param>
        /// <param name="missingItemTypesStacks">Returns the missing item ids and amounts for the recipe.</param>
        /// <param name="availableIngredients"></param>
        /// <returns></returns>
        public static RecipeCraftFailReason GetRecipeFailReasons(
            Player player,
            Recipe recipe,
            out int[] missingTile,
            out IDictionary <int, int> missingItemTypesStacks,
            IEnumerable <Item> availableIngredients = null)
        {
            RecipeCraftFailReason reason = 0;
            var missingTileList          = new List <int>();

            missingItemTypesStacks = new Dictionary <int, int>();

            // Get available item ingredients
            if (availableIngredients == null)
            {
                availableIngredients = player.inventory
                                       .Take(58)
                                       .Where(item => !item.IsAir);

                bool?  _;
                Item[] chest = PlayerItemLibraries.GetCurrentlyOpenChest(player, out _);
                if (chest != null)
                {
                    availableIngredients = availableIngredients.Concat(chest);
                }
            }

            // Process ingredients list into id + stack map
            IDictionary <int, int> availIngredientInfo = new Dictionary <int, int>(availableIngredients.Count());

            foreach (Item item in availableIngredients)
            {
                if (availIngredientInfo.ContainsKey(item.netID))
                {
                    availIngredientInfo[item.netID] += item.stack;
                }
                else
                {
                    availIngredientInfo[item.netID] = item.stack;
                }
            }

            // Tiles
            for (int i = 0; i < recipe.requiredTile.Length; i++)
            {
                int reqTileType = recipe.requiredTile[i];
                if (reqTileType == -1)
                {
                    break;
                }

                if (!player.adjTile[reqTileType])
                {
                    missingTileList.Add(reqTileType);
                    reason |= RecipeCraftFailReason.MissingTile;
                }
            }

            // Items
            for (int i = 0; i < recipe.requiredItem.Length; i++)
            {
                Item reqItem = recipe.requiredItem[i];
                if (reqItem == null || reqItem.type == ItemID.None)
                {
                    break;
                }

                int  reqStack         = reqItem.stack;
                bool hasCheckedGroups = false;

                foreach (var kv in availIngredientInfo)
                {
                    int itemType  = kv.Key;
                    int itemStack = kv.Value;

                    if (recipe.useWood(itemType, reqItem.type) ||
                        recipe.useSand(itemType, reqItem.type) ||
                        recipe.useIronBar(itemType, reqItem.type) ||
                        recipe.useFragment(itemType, reqItem.type) ||
                        recipe.usePressurePlate(itemType, reqItem.type) ||
                        recipe.AcceptedByItemGroups(itemType, reqItem.type))
                    {
                        reqStack        -= itemStack;
                        hasCheckedGroups = true;
                    }
                }
                if (!hasCheckedGroups && availIngredientInfo.ContainsKey(reqItem.netID))
                {
                    reqStack -= availIngredientInfo[reqItem.netID];
                }

                // Account for missing ingredients:
                if (reqStack > 0)
                {
                    missingItemTypesStacks[reqItem.netID] = reqStack;
                    reason |= RecipeCraftFailReason.MissingItem;
                }
            }

            if (recipe.needWater && !player.adjWater && !player.adjTile[172])
            {
                reason |= RecipeCraftFailReason.NeedsNearbyWater;
            }
            if (recipe.needHoney && !player.adjHoney)
            {
                reason |= RecipeCraftFailReason.NeedsNearbyHoney;
            }
            if (recipe.needLava && !player.adjLava)
            {
                reason |= RecipeCraftFailReason.NeedsNearbyLava;
            }
            if (recipe.needSnowBiome && !player.ZoneSnow)
            {
                reason |= RecipeCraftFailReason.NeedsNearbySnowBiome;
            }

            missingTile = missingTileList.ToArray();
            return(reason);
        }
        public static bool ApplyRepairIf(Player player, Item item)
        {
            if (item?.active != true || item.stack == 0)
            {
                return(false);
            }

            int  scrapItemType = ModContent.ItemType <MagitechScrapItem>();
            Item scrapItem     = PlayerItemFinderLibraries.FindFirstOfPossessedItemFor(
                player,
                new HashSet <int> {
                scrapItemType
            },
                false
                );

            var myScrapItem = scrapItem?.modItem as MagitechScrapItem;

            if (myScrapItem == null)
            {
                Main.NewText("No repair scrap items in player's possession.", Color.Yellow);
                return(false);
            }

            int ruinedPrefixType = ModContent.PrefixType <RuinedPrefix>();

            if (item.prefix != ruinedPrefixType)
            {
                return(false);
            }

            var  config   = RuinedItemsConfig.Instance;
            var  myitem   = item.GetGlobalItem <RuinedItemsItem>();
            bool onlyOnce = config.Get <bool>(nameof(config.MagitechScrapAttemptsRepairOnlyOncePerItem));

            if (onlyOnce && myitem.IsScrapUsedUpon)
            {
                Main.NewText("Cannot repair this with scrap more than once. Use reforging instead.", Color.Yellow);
                return(false);
            }

            if (PlayerItemLibraries.RemoveInventoryItemQuantity(Main.LocalPlayer, scrapItemType, 1) <= 0)
            {
                Main.NewText("Could not use player's scrap items for repairing.", Color.Yellow);
                return(false);
            }

            if (Main.rand.NextFloat() < config.Get <float>(nameof(config.MagitechScrapRepairChance)))
            {
                float rollChance = config.Get <float>(nameof(config.GeneralRuinRollChance));

                config.SetOverride(nameof(config.GeneralRuinRollChance), 0f);
                item.Prefix(-1);
                config.SetOverride(nameof(config.GeneralRuinRollChance), rollChance);

                CombatText.NewText(Main.LocalPlayer.getRect(), Color.Lime, "Repair success!", true);
                Main.NewText("Repair success!", Color.Lime);
            }
            else
            {
                CombatText.NewText(Main.LocalPlayer.getRect(), Color.DimGray, "Repair failed!", true);
                Main.NewText("Repair failed! Item can now only be repaired via. reforging.", Color.OrangeRed);
            }

            myitem.IsScrapUsedUpon = true;

            Main.PlaySound(SoundID.Item37, Main.LocalPlayer.Center);
            Main.PlaySound(SoundID.Grab, Main.LocalPlayer.Center);

            return(true);
        }