aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/KatRecipe.kt
blob: acb379dea0d630695ca0174f63b30f4059501f5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * Copyright (C) 2022 Linnea Gräf
 *
 * This file is part of NotEnoughUpdates.
 *
 * NotEnoughUpdates is free software: you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * NotEnoughUpdates is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
 */
package io.github.moulberry.notenoughupdates.recipes

import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import io.github.moulberry.notenoughupdates.NEUManager
import io.github.moulberry.notenoughupdates.core.util.GuiElementSlider
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay.Pet
import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe
import io.github.moulberry.notenoughupdates.util.ItemUtils
import io.github.moulberry.notenoughupdates.util.PetLeveling
import io.github.moulberry.notenoughupdates.util.Utils
import io.github.moulberry.notenoughupdates.util.toJsonArray
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.util.ResourceLocation
import java.time.Duration
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.roundToInt
import kotlin.math.sin

data class KatRecipe(
    val manager: NEUManager,
    val inputPet: Ingredient,
    val outputPet: Ingredient,
    val items: List<Ingredient>,
    val coins: Long,
    val time: Duration,
) : NeuRecipe {
    var inputLevel = 1
    val radius get() = 50 / 2
    val circleCenter get() = 33 + 110 / 2 to 19 + 110 / 2
    val textPosition get() = circleCenter.first to circleCenter.second + 90 / 2
    val sliderPos get() = 40 to 15
    val levelTextPos
        get() = sliderPos.first - 4 - Minecraft.getMinecraft().fontRendererObj.getStringWidth("100") to
                sliderPos.second + 16 / 2 - Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT / 2

    val levelSlider = GuiElementSlider(0, 0, 100, 1F, 100F, 1F, inputLevel.toFloat()) { inputLevel = it.toInt() }
    val coinsAdjustedForLevel: Int
        get() = (coins.toInt() * (1 - 0.003F * (getOutputPetForCurrentLevel()?.petLevel?.currentLevel ?: 0))).toInt()
    private val basicIngredients = items.toSet() + setOf(inputPet, Ingredient.coinIngredient(manager, coins.toInt()))
    override fun getIngredients(): Set<Ingredient> = basicIngredients

    override fun getOutputs(): Set<Ingredient> {
        return setOf(outputPet)
    }

    fun getInputPetForCurrentLevel(): Pet? {
        return PetInfoOverlay.getPetFromStack(inputPet.itemStack.tagCompound)?.also {
            val petLeveling = PetLeveling.getPetLevelingForPet(it.petType, it.rarity)
            it.petLevel = petLeveling.getPetLevel(petLeveling.getPetExpForLevel(inputLevel).toDouble())
        }
    }

    fun getOutputPetForCurrentLevel(): Pet? {
        return PetInfoOverlay.getPetFromStack(outputPet.itemStack.tagCompound)?.also {
            val petLeveling = PetLeveling.getPetLevelingForPet(it.petType, it.rarity)
            it.petLevel = petLeveling.getPetLevel(getInputPetForCurrentLevel()?.petLevel?.expTotal?.toDouble() ?: 0.0)
        }
    }

    private fun positionOnCircle(i: Int, max: Int): Pair<Int, Int> {
        val radians = PI * 2 * i / max
        val offsetX = cos(radians) * radius
        val offsetY = sin(radians) * radius
        return (circleCenter.first + offsetX).roundToInt() to (circleCenter.second + offsetY).roundToInt()
    }

    override fun drawExtraInfo(gui: GuiItemRecipe, mouseX: Int, mouseY: Int) {
        levelSlider.x = gui.guiLeft + sliderPos.first
        levelSlider.y = gui.guiTop + sliderPos.second
        levelSlider.render()
        Minecraft.getMinecraft().fontRendererObj.drawString(
            "$inputLevel",
            gui.guiLeft + levelTextPos.first,
            gui.guiTop + levelTextPos.second,
            0xFF0000
        )
        Utils.drawStringCentered(
            Utils.prettyTime(time),
            gui.guiLeft + textPosition.first.toFloat(), gui.guiTop + textPosition.second.toFloat(),
            false, 0xff00ff
        )
        GlStateManager.color(1F, 1F, 1F, 1F)
    }

    override fun genericMouseInput(mouseX: Int, mouseY: Int) {
        levelSlider.mouseInput(mouseX, mouseY)
    }

    override fun getSlots(): List<RecipeSlot> {
        val advancedIngredients = items.map { it.itemStack } + listOf(
            ItemUtils.createPetItemstackFromPetInfo(getInputPetForCurrentLevel()),
            Ingredient.coinIngredient(
                manager,
                coinsAdjustedForLevel
            ).itemStack
        )
        return advancedIngredients.mapIndexed { index, itemStack ->
            val (x, y) = positionOnCircle(index, advancedIngredients.size)
            RecipeSlot(x - 18 / 2, y - 18 / 2, itemStack)
        } + listOf(
            RecipeSlot(
                circleCenter.first - 9,
                circleCenter.second - 9,
                ItemUtils.createPetItemstackFromPetInfo(getOutputPetForCurrentLevel())
            )
        )
    }

    override fun getType(): RecipeType = RecipeType.KAT_UPGRADE

    override fun hasVariableCost(): Boolean = false

    override fun serialize(): JsonObject {
        return JsonObject().apply {
            addProperty("type", type.id)
            addProperty("coins", coins)
            addProperty("input", inputPet.serialize())
            addProperty("output", outputPet.serialize())
            addProperty("time", time.seconds)
            add("items", items.map { JsonPrimitive(it.serialize()) }.toJsonArray())
        }
    }

    companion object {
        @JvmStatic
        fun parseRecipe(manager: NEUManager, recipe: JsonObject, output: JsonObject): NeuRecipe {
            return KatRecipe(
                manager,
                Ingredient(manager, recipe["input"].asString),
                Ingredient(manager, recipe["output"].asString),
                recipe["items"]?.asJsonArray?.map { Ingredient(manager, it.asString) } ?: emptyList(),
                recipe["coins"].asLong,
                Duration.ofSeconds(recipe["time"].asLong)
            )
        }
    }

    override fun getBackground(): ResourceLocation {
        return ResourceLocation("notenoughupdates:textures/gui/katting_tall.png")
    }

    override fun shouldUseForCraftCost() = false
}