Skip to main content
deleted 2 characters in body
Source Link
Philipp
  • 123k
  • 28
  • 264
  • 344
if( tradegoodRequirements.All(   (requirement) => {   warehouse.warehouseContents.Contains(   (content) => {   content.scripableTradegood == requirement.scripableTradegood   && content.amount >= requirement.amount;   }   );   } ) ) { // recipe is craftable } 
if(tradegoodRequirements.All( (requirement) => { warehouse.warehouseContents.Contains( (content) => { content.scripableTradegood == requirement.scripableTradegood && content.amount >= requirement.amount; } ); }) ) { // recipe is craftable } 
if( tradegoodRequirements.All(   (requirement) => {   warehouse.warehouseContents.Contains(   (content) => {   content.scripableTradegood == requirement.scripableTradegood   && content.amount >= requirement.amount;   }   );   } ) ) { // recipe is craftable } 
deleted 2 characters in body
Source Link
Philipp
  • 123k
  • 28
  • 264
  • 344

However, there is a more concise way of writing this if you want to use Linq. If you add the using System.Linq directive to your script, then Lists (and all other collections) gain a whole bunch of useful new methods. Among them is the method .Contains(predicateFunction). Which in plain English tells you "Does this collection contain anything where this function returns true?". So instead of the whole inner loop you can do this:

if (warehouse.warehouseContents.Contains( (content) => { content.scripableTradegood == requirement.scripableTradegood && content.amount >= requirement.amount ; }) ) { // This item is available in sufficient quantity } else { // this item is not available in sufficient quantity } 

And then there is another useful method .All which tells you "Does this function return true for everything in this collection?". So you can substitute that whole code with this:

if(tradegoodRequirements.All( (requirement) => { warehouse.warehouseContents.Contains( (content) => { content.scripableTradegood == requirement.scripableTradegood && content.amount >= requirement.amount; } ); }) ) { // recipe is craftable } 

By the way: I assume you do ensure that the content of a warehouse can not contain multiple stacks of the same item type, right? Because if you allow that, then you can not just return; after you found a stack with an insufficient amount. There might be a second stack which is large enough. Or perhaps all the stacks together are large enough. That would complicate things a lot.

By the way: I assume you do ensure that the content of a warehouse can not contain multiple stacks of the same item type, right? Because if you allow that, then you can not just return; after you found a stack with an insufficient amount. There might be a second stack which is large enough. Or perhaps all the stacks together are large enough.

However, there is a more concise way of writing this if you want to use Linq. If you add the using System.Linq directive to your script, then Lists (and all other collections) gain a whole bunch of useful new methods. Among them is the method .Contains(predicateFunction). Which in plain English tells you "Does this collection contain anything where this function returns true?". So instead of the whole inner loop you can do this:

if (warehouse.warehouseContents.Contains( (content) => { content.scripableTradegood == requirement.scripableTradegood && content.amount >= requirement.amount ; }) ) { // This item is available in sufficient quantity } else { // this item is not available in sufficient quantity } 

And then there is another useful method .All which tells you "Does this function return true for everything in this collection?". So you can substitute that whole code with this:

if(tradegoodRequirements.All( (requirement) => { warehouse.warehouseContents.Contains( (content) => { content.scripableTradegood == requirement.scripableTradegood && content.amount >= requirement.amount; } ); }) ) { // recipe is craftable } 

By the way: I assume you do ensure that the content of a warehouse can not contain multiple stacks of the same item type, right? Because if you allow that, then you can not just return; after you found a stack with an insufficient amount. There might be a second stack which is large enough. Or perhaps all the stacks together are large enough. That would complicate things a lot.

deleted 2 characters in body
Source Link
Philipp
  • 123k
  • 28
  • 264
  • 344

The problem is that you did not distinguish whether the inner loop terminated with or without finding the item type you were looking for. You could fix that by introducing a new variable bool requirementFound which you set to false before that loop, and then set to true when finding the resource.

Then, after that loop, Iyou can check if requirementFound is still false. When it's falseit is, then the loop didn't find any of that item type, which means the itemrecipe can't be crafted. When it is true, that resource is available, so we can proceed with the next.

foreach (Item requirement in tradegoodRequirements) { foreach (Item content in warehouse.warehouseContent) { var requirementFound = false; if (content.scripableTradegood != requirement.scripableTradegood) continue; // When right content was found if (content.scripableTradegood == requirement.scripableTradegood) { // If required content amount isnt present return if (content.amount < requirement.amount) return; } else { requirementFound = true; break; } if(requirementFound == false) { //resource is unvailable return; } } } 

By the way: I assume you do ensure that the content of a warehouse can not contain multiple stacks of the same item type, right? Because if you allow that, then you can not just return; after you found a stack with an insufficient amount. There might be a second stack which is large eno ughenough. Or perhaps all the stacks together are large enough.

The problem is that you did not distinguish whether the inner loop terminated with or without finding the item type you were looking for. You could fix that by introducing a new variable bool requirementFound which you set to false before that loop, and then set to true when finding the resource.

Then, after that loop, I check if requirementFound is still false. When it's false, the loop didn't find any of that item, which means the item can't be crafted. When it is true, that resource is available, so we can proceed with the next.

foreach (Item requirement in tradegoodRequirements) { foreach (Item content in warehouse.warehouseContent) { var requirementFound = false; if (content.scripableTradegood != requirement.scripableTradegood) continue; // When right content was found if (content.scripableTradegood == requirement.scripableTradegood) { // If required content amount isnt present return if (content.amount < requirement.amount) return; } else { requirementFound = true; break; } if(requirementFound == false) { //resource is unvailable return; } } } 

By the way: I assume you do ensure that the content of a warehouse can not contain multiple stacks of the same item type, right? Because if you allow that, then you can not just return; after you found a stack with an insufficient amount. There might be a second stack which is large eno ugh. Or perhaps all the stacks together are large enough.

The problem is that you did not distinguish whether the inner loop terminated with or without finding the item type you were looking for. You could fix that by introducing a new variable bool requirementFound which you set to false before that loop, and then set to true when finding the resource.

Then, after that loop, you can check if requirementFound is still false. When it is, then the loop didn't find any of that item type, which means the recipe can't be crafted. When it is true, that resource is available, so we can proceed with the next.

foreach (Item requirement in tradegoodRequirements) { foreach (Item content in warehouse.warehouseContent) { var requirementFound = false; if (content.scripableTradegood != requirement.scripableTradegood) continue; // When right content was found if (content.scripableTradegood == requirement.scripableTradegood) { // If required content amount isnt present return if (content.amount < requirement.amount) return; } else { requirementFound = true; break; } if(requirementFound == false) { //resource is unvailable return; } } } 

By the way: I assume you do ensure that the content of a warehouse can not contain multiple stacks of the same item type, right? Because if you allow that, then you can not just return; after you found a stack with an insufficient amount. There might be a second stack which is large enough. Or perhaps all the stacks together are large enough.

Source Link
Philipp
  • 123k
  • 28
  • 264
  • 344
Loading