clicking on the player's item on the crafting Ui will show recipes using that item

This commit is contained in:
minjaesong
2024-02-18 03:08:11 +09:00
parent f400416a7c
commit 2bf47a2aed
5 changed files with 111 additions and 53 deletions

View File

@@ -73,8 +73,8 @@ basegame
// Commit counts up to the Release 0.3.3: 3020
// val VERSION_SNAPSHOT = Snapshot(0) // for normal dev
val VERSION_SNAPSHOT = ForcedSnapshot("24w07c") // for snapshot release
// val VERSION_SNAPSHOT = null // for the release
// val VERSION_SNAPSHOT = ForcedSnapshot("24w07d") // for snapshot release
val VERSION_SNAPSHOT = null // for the release
const val VERSION_TAG: String = ""

View File

@@ -1,7 +1,13 @@
package net.torvald.terrarum.itemproperties
import com.badlogic.gdx.utils.JsonValue
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.gameitems.isBlock
import net.torvald.terrarum.gameitems.isWall
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
import net.torvald.terrarum.utils.forEachSiblings
import net.torvald.terrarum.utils.forEachSiblingsIndexed
@@ -10,6 +16,10 @@ import net.torvald.terrarum.utils.forEachSiblingsIndexed
*/
class CraftingCodex {
/**
* Key: final product of the given recipes. Equal to the recipe.product
* Value: the recipes
*/
@Transient internal val props = HashMap<ItemID, ArrayList<CraftingRecipe>>() // the key ItemID and value.product must be equal
fun addRecipe(recipe: CraftingRecipe) {
@@ -89,10 +99,23 @@ class CraftingCodex {
}
/**
* Returns list of items that uses the given `item`.
*
* @return list of itemIDs and corresponding recipes
*/
fun getRecipesUsingTheseItems(items: List<ItemID>): List<CraftingRecipe> {
TODO()
fun getCraftableRecipesUsingTheseItems(item: ItemID): List<CraftingRecipe> {
return props.values.flatten().filter { recipe ->
recipe.ingredients.any { ingredient ->
when (ingredient.keyMode) {
CraftingItemKeyMode.TAG -> if (item.isBlock() || item.isWall())
Terrarum.blockCodex[item].hasTag(ingredient.key)
else
Terrarum.itemCodex[item]!!.hasTag(ingredient.key)
CraftingItemKeyMode.VERBATIM -> (item == ingredient.key)
}
}
}
}
/**

View File

@@ -35,33 +35,60 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
override var width = Toolkit.drawWidth
override var height = App.scr.height
private val playerThings = UITemplateHalfInventory(this, false).also {
it.itemListTouchDownFun = { gameItem, _, _, _, _ -> recipeClicked?.let { recipe -> gameItem?.let { gameItem ->
private val playerThings = UITemplateHalfInventory(this, false).also { pt ->
pt.itemListTouchDownFun = { gameItem, _, _, _, theButton -> if (gameItem != null) {
val recipe = recipeClicked
val itemID = gameItem.dynamicID
// don't rely on highlightedness of the button to determine the item on the button is the selected
// ingredient (because I don't fully trust my code lol)
val targetItemToAlter = recipe.ingredients.filter { (key, mode) -> // altering recipe doesn't make sense if player selected a recipe that requires no tag-ingredients
val tags = key.split(',')
val wantsWall = tags.contains("WALL")
(mode == CraftingCodex.CraftingItemKeyMode.TAG && gameItem.hasAllTags(tags) && (wantsWall == gameItem.originalID.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
}.let {
if (it.size > 1)
println("[UICrafting] Your recipe seems to have two similar ingredients defined\n" +
"affected ingredients: ${it.joinToString()}\n" +
"the recipe: ${recipe}")
it.firstOrNull()
}
targetItemToAlter?.let { (key, mode) ->
val oldItem = _getItemListIngredients().getInventory().first { (itm, qty) ->
val tags = key.split(',')
val wantsWall = tags.contains("WALL")
(mode == CraftingCodex.CraftingItemKeyMode.TAG && ItemCodex[itm]!!.hasAllTags(tags) && (wantsWall == itm.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
// change ingredient used
if (recipe != null) {
// don't rely on highlightedness of the button to determine the item on the button is the selected
// ingredient (because I don't fully trust my code lol)
val targetItemToAlter =
recipe.ingredients.filter { (key, mode) -> // altering recipe doesn't make sense if player selected a recipe that requires no tag-ingredients
val tags = key.split(',')
val wantsWall = tags.contains("WALL")
(mode == CraftingCodex.CraftingItemKeyMode.TAG && gameItem.hasAllTags(tags) && (wantsWall == gameItem.originalID.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
}.let {
if (it.size > 1)
println(
"[UICrafting] Your recipe seems to have two similar ingredients defined\n" +
"affected ingredients: ${it.joinToString()}\n" +
"the recipe: ${recipe}"
)
it.firstOrNull()
}
targetItemToAlter?.let { (key, mode) ->
val oldItem = _getItemListIngredients().getInventory().first { (itm, qty) ->
val tags = key.split(',')
val wantsWall = tags.contains("WALL")
(mode == CraftingCodex.CraftingItemKeyMode.TAG && ItemCodex[itm]!!.hasAllTags(tags) && (wantsWall == itm.isWall())) // true if (wants wall and is wall) or (wants no wall and is not wall)
}
changeIngredient(recipe, oldItem, itemID)
refreshCraftButtonStatus()
}
changeIngredient(recipe, oldItem, itemID)
refreshCraftButtonStatus()
}
} } }
// show all the items that can be made using this ingredient
else {
itemListCraftable.rebuild(arrayOf(itemID))
pt.itemList.clearForceHighlightList()
pt.itemList.addToForceHighlightList(listOf(itemID))
if (itemListCraftable.craftingRecipes.isEmpty()) {
pt.itemList.clearForceHighlightList()
itemListCraftable.rebuild(FILTER_CAT_ALL)
}
}
}
else {
pt.itemList.clearForceHighlightList()
recipeClicked = null
filterPlayerListUsing(recipeClicked)
highlightCraftingCandidateButton(null)
ingredients.clear()
itemListIngredients.rebuild(FILTER_CAT_ALL)
}}
}
private val itemListCraftable: UIItemCraftingCandidateGrid // might be changed to something else
@@ -69,7 +96,6 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
private val buttonCraft: UIItemTextButton
private val spinnerCraftCount: UIItemSpinner
private val craftables = FixtureInventory() // might be changed to something else
private val ingredients = FixtureInventory() // this one is definitely not to be changed
private val negotiator = object : InventoryTransactionNegotiator() {
@@ -83,7 +109,7 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
}
override fun getNegotiator() = negotiator
override fun getFixtureInventory(): FixtureInventory = craftables
override fun getFixtureInventory(): FixtureInventory = TODO()
override fun getPlayerInventory(): FixtureInventory = INGAME.actorNowPlaying!!.inventory
private val halfSlotOffset = (UIItemInventoryElemSimple.height + listGap) / 2
@@ -228,7 +254,7 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
_getItemListPlayer().removeFromForceHighlightList(oldSelectedItems)
_getItemListPlayer().addToForceHighlightList(selectedItems)
_getItemListPlayer().itemPage = 0
if (recipe != null) _getItemListPlayer().itemPage = 0
filterPlayerListUsing(recipeClicked)
_getItemListIngredients().rebuild(FILTER_CAT_ALL)
@@ -237,6 +263,10 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
oldSelectedItems.clear()
oldSelectedItems.addAll(selectedItems)
if (recipe == null) {
playerThings.itemList.clearForceHighlightList()
}
refreshCraftButtonStatus()
}
}
@@ -248,7 +278,7 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
itemListIngredients.numberMultiplier = it.toLong()
itemListIngredients.rebuild(FILTER_CAT_ALL)
itemListCraftable.numberMultiplier = it.toLong()
itemListCraftable.rebuild(FILTER_CAT_ALL)
itemListCraftable.rebuild()
refreshCraftButtonStatus()
}
@@ -362,7 +392,7 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
filterPlayerListUsing(recipeClicked)
highlightCraftingCandidateButton(null)
ingredients.clear()
playerThings.removeFromForceHighlightList(oldSelectedItems)
playerThings.itemList.clearForceHighlightList()
itemListIngredients.rebuild(FILTER_CAT_ALL)
// reset scroll
@@ -399,7 +429,7 @@ class UICrafting(val full: UIInventoryFull?) : UICanvas(
private fun itemListUpdate() {
// let itemlists be sorted
itemListCraftable.rebuild(FILTER_CAT_ALL)
itemListCraftable.rebuild()
playerThings.rebuild(FILTER_CAT_ALL)
encumbrancePerc = getPlayerInventory().let {
it.capacity.toFloat() / it.maxCapacity

View File

@@ -9,6 +9,7 @@ import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.itemproperties.CraftingCodex
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
import net.torvald.terrarum.ui.UIItemCatBar.Companion.CAT_ALL
/**
* Created by minjaesong on 2022-06-28.
@@ -95,34 +96,42 @@ class UIItemCraftingCandidateGrid(
highlightRecipe(highlightedRecipe)
}
private var currentFilter1 = arrayOf("")
private var currentFilter0 = arrayOf(CAT_ALL)
private var currentFilter1 = CAT_ALL
fun rebuild() = rebuild(currentFilter0)
override fun rebuild(filter: Array<String>) {
// printdbg(this, "Rebuilding crafting candidate with following filters: ${filter.joinToString()}")
currentFilter1 = filter
currentFilter1 = filter.first()
currentFilter0 = arrayOf(currentFilter1)
// filtering policy: if the player have all the ingredient item (regardless of the amount!), make the recipe visible
craftingRecipes.clear()
CraftingRecipeCodex.props.forEach { (_, recipes) ->
recipes.forEach {
if (currentFilter1 == CAT_ALL)
CraftingRecipeCodex.props.forEach { (_, recipes) ->
recipes.forEach {
if (isCraftable((parentUI as UICrafting).getPlayerInventory(), it, (parentUI as UICrafting).nearbyCraftingStations)) {
craftingRecipes.add(it)
}
}
}
else
CraftingRecipeCodex.getCraftableRecipesUsingTheseItems(currentFilter1).forEach {
if (isCraftable((parentUI as UICrafting).getPlayerInventory(), it, (parentUI as UICrafting).nearbyCraftingStations)) {
craftingRecipes.add(it)
}
else {
// printdbg(this, " Skipping $recipes: insufficient ingredients")
}
}
}
recipesSortList.clear() // kinda like the output list
craftingRecipes.forEach {
if (
filter.contains((ItemCodex[it.product]?.inventoryCategory ?: throw IllegalArgumentException("Unknown item: ${it.product}"))) ||
filter[0] == UIItemCatBar.CAT_ALL
) {
recipesSortList.add(it)
}
recipesSortList.add(it)
}
// map sortList to item list
@@ -155,11 +164,11 @@ class UIItemCraftingCandidateGrid(
}
override fun rebuild(filterFun: (InventoryPair) -> Boolean) {
rebuild(currentFilter1)
rebuild(currentFilter0)
}
override fun rebuild(filterFun: (InventoryPair) -> Boolean, itemAppendix: ItemID) {
rebuild(currentFilter1)
rebuild(currentFilter0)
}
override fun scrolled(amountX: Float, amountY: Float): Boolean {

View File

@@ -82,10 +82,6 @@ class UITemplateHalfInventory(
itemList.rebuild(predicate, appendix)
}
fun removeFromForceHighlightList(items: List<ItemID>) {
itemList.removeFromForceHighlightList(items)
}
fun setGetInventoryFun(getter: () -> ActorInventory) {
itemList.getInventory = getter
}