Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Visitor Super Craft #1173

Merged
merged 10 commits into from
Apr 17, 2024
2 changes: 2 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ import at.hannibal2.skyhanni.features.garden.pests.SprayFeatures
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorColorNames
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorDropStatistics
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorFeatures
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorSupercraft
import at.hannibal2.skyhanni.features.garden.visitor.GardenVisitorTimer
import at.hannibal2.skyhanni.features.garden.visitor.HighlightVisitorsOutsideOfGarden
import at.hannibal2.skyhanni.features.garden.visitor.NPCVisitorFix
Expand Down Expand Up @@ -615,6 +616,7 @@ class SkyHanniMod {
loadModule(MiscFeatures())
loadModule(SkyMartCopperPrice())
loadModule(GardenVisitorFeatures())
loadModule(GardenVisitorSupercraft())
loadModule(NPCVisitorFix)
loadModule(GardenInventoryNumbers())
loadModule(GardenVisitorTimer())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public class ShoppingListConfig {
@ConfigEditorBoolean
public boolean showSackCount = true;

@Expose
@ConfigOption(name = "Show Super Craft", desc = "Show super craft button if there are enough materials to make in the sack.")
@ConfigEditorBoolean
@FeatureToggle
public boolean showSuperCraft = true;
Conutik marked this conversation as resolved.
Show resolved Hide resolved

@Expose
@ConfigOption(name = "Item Preview", desc = "Show the base type for the required items next to new visitors. §cNote that some visitors may require any crop.")
@ConfigEditorBoolean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package at.hannibal2.skyhanni.features.garden.visitor

import at.hannibal2.skyhanni.data.SackAPI
import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.garden.visitor.VisitorOpenEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.ItemUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
import at.hannibal2.skyhanni.utils.NEUInternalName
import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import io.github.moulberry.notenoughupdates.events.ReplaceItemEvent
import io.github.moulberry.notenoughupdates.events.SlotClickEvent
import io.github.moulberry.notenoughupdates.util.Utils
import net.minecraft.entity.player.InventoryPlayer
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.seconds

class GardenVisitorSupercraft {

private val isSupercraftEnabled get() = VisitorAPI.config.shoppingList.showSuperCraft

private var hasIngredients = false;
Conutik marked this conversation as resolved.
Show resolved Hide resolved
private var lastClick = SimpleTimeMark.farPast()
private var lastSuperCraftMaterial = ""

private val superCraftItem by lazy {
val neuItem = "GOLD_PICKAXE".asInternalName().getItemStack()
Utils.createItemStack(
neuItem.item,
"§bSuper Craft",
"§7You have the items to craft",
"§7Click me to open the super crafter!"
)
}

@SubscribeEvent
fun onInventoryClose(event: InventoryCloseEvent) {
if (hasIngredients) {
hasIngredients = false
}
}

@SubscribeEvent(priority = EventPriority.HIGH)
fun onVisitorOpen(event: VisitorOpenEvent) {
val visitor = event.visitor
val offerItem = visitor.offer!!.offerItem
Conutik marked this conversation as resolved.
Show resolved Hide resolved

val lore = offerItem.getLore()
for (line in lore) {
if (line == "§7Items Required:") continue
if (line.isEmpty()) break
Conutik marked this conversation as resolved.
Show resolved Hide resolved

val pair = ItemUtils.readItemAmount(line)
if (pair == null) {
ErrorManager.logErrorStateWithData(
"Could not read Shopping List in Visitor Inventory", "ItemUtils.readItemAmount returns null",
"line" to line,
"offerItem" to offerItem,
"lore" to lore,
"visitor" to visitor
)
continue
}
val (itemName, amount) = pair
val internalName = NEUInternalName.fromItemName(itemName)
hannibal002 marked this conversation as resolved.
Show resolved Hide resolved
//
// GET SUPERCRAFT FOR SACKS CODE
Conutik marked this conversation as resolved.
Show resolved Hide resolved
//
if (isSupercraftEnabled) {
val item =
NEUItems.getRecipes(internalName).first { !it.ingredients.first().internalItemId.contains("PEST") }
val ingredients = item.ingredients
Conutik marked this conversation as resolved.
Show resolved Hide resolved
val ingredientReqs = mutableMapOf<String, Int>()
for (ingredient in ingredients) {
val ing = ingredient.serialize().split(":")
Conutik marked this conversation as resolved.
Show resolved Hide resolved
ingredientReqs[ing[0]] = ingredientReqs.getOrDefault(ing[0], 0) + ing[1].toDouble().toInt()
}
hasIngredients = true;
for ((key, value) in ingredientReqs) {
val sackItem = SackAPI.fetchSackItem(key.asInternalName())
Conutik marked this conversation as resolved.
Show resolved Hide resolved
lastSuperCraftMaterial = internalName.itemName
Conutik marked this conversation as resolved.
Show resolved Hide resolved
if (sackItem.amount < value * amount) {
hasIngredients = false;
break;
}
}
}
}
}

@SubscribeEvent
fun replaceItem(event: ReplaceItemEvent) {
if (!hasIngredients) return
if (event.inventory is InventoryPlayer) return

if (event.slotNumber == 31) {
event.replaceWith(superCraftItem)
}
}

@SubscribeEvent(priority = EventPriority.HIGH)
fun onStackClick(event: SlotClickEvent) {
if (!hasIngredients) return

if (event.slotId == 31) {
event.isCanceled = true
if (lastClick.passedSince() > 0.3.seconds) {
ChatUtils.sendCommandToServer("recipe $lastSuperCraftMaterial")
lastClick = SimpleTimeMark.now()
}
}
}
}
Loading