begone, helper objects. kotlin has no need of thou
This commit is contained in:
parent
5945d6ea70
commit
0da0b40256
14 changed files with 347 additions and 362 deletions
|
@ -86,14 +86,14 @@ object PatternRegistry {
|
|||
// when we try to look
|
||||
for (handler in specialHandlers) {
|
||||
val op = handler.handler.handlePattern(pat)
|
||||
if (op != null) return Pair(op, handler.id)
|
||||
if (op != null) return op to handler.id
|
||||
}
|
||||
|
||||
// Is it global?
|
||||
val sig = pat.anglesSignature()
|
||||
this.regularPatternLookup[sig]?.let {
|
||||
val op = this.operatorLookup[it.opId] ?: throw MishapInvalidPattern()
|
||||
return Pair(op, it.opId)
|
||||
return op to it.opId
|
||||
}
|
||||
|
||||
// Look it up in the world?
|
||||
|
@ -102,7 +102,7 @@ object PatternRegistry {
|
|||
ds.computeIfAbsent(Save.Companion::load, { Save.create(overworld.seed) }, TAG_SAVED_DATA)
|
||||
perWorldPatterns.lookup[sig]?.let {
|
||||
val op = this.operatorLookup[it.first]!!
|
||||
return Pair(op, it.first)
|
||||
return op to it.first
|
||||
}
|
||||
|
||||
throw MishapInvalidPattern()
|
||||
|
@ -188,7 +188,7 @@ object PatternRegistry {
|
|||
val entry = tag.getCompound(sig)
|
||||
val opId = ResourceLocation.tryParse(entry.getString(TAG_OP_ID))!!
|
||||
val startDir = HexDir.values()[entry.getInt(TAG_START_DIR)]
|
||||
map[sig] = Pair(opId, startDir)
|
||||
map[sig] = opId to startDir
|
||||
}
|
||||
return Save(map)
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ object PatternRegistry {
|
|||
for ((opId, entry) in PatternRegistry.perWorldPatternLookup) {
|
||||
// waugh why doesn't kotlin recursively destructure things
|
||||
val scrungled = EulerPathFinder.findAltDrawing(entry.prototype, seed)
|
||||
map[scrungled.anglesSignature()] = Pair(opId, scrungled.startDir)
|
||||
map[scrungled.anglesSignature()] = opId to scrungled.startDir
|
||||
}
|
||||
val save = Save(map)
|
||||
save.setDirty()
|
||||
|
|
|
@ -385,10 +385,10 @@ class CastingHarness private constructor(
|
|||
}
|
||||
if (casterStack.`is`(HexItemTags.WANDS) || ipsCanDrawFromInv) {
|
||||
val manableItems = this.ctx.caster.inventory.items
|
||||
.filter(ManaHelper::isManaItem)
|
||||
.sortedWith(Comparator(ManaHelper::compare).reversed())
|
||||
.filter(::isManaItem)
|
||||
.sortedWith(Comparator(::compareManaItem).reversed())
|
||||
for (stack in manableItems) {
|
||||
costLeft -= ManaHelper.extractMana(stack, costLeft)
|
||||
costLeft -= extractMana(stack, costLeft)
|
||||
if (costLeft <= 0)
|
||||
break
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ sealed interface ContinuationFrame {
|
|||
*/
|
||||
data class Evaluate(val list: SpellList) : ContinuationFrame {
|
||||
// Discard this frame and keep discarding frames.
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>) = Pair(false, stack)
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>) = false to stack
|
||||
|
||||
// Step the list of patterns, evaluating a single one.
|
||||
override fun evaluate(
|
||||
|
@ -83,7 +83,7 @@ sealed interface ContinuationFrame {
|
|||
*/
|
||||
object FinishEval : ContinuationFrame {
|
||||
// Don't do anything else to the stack, just finish the halt statement.
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>) = Pair(true, stack)
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>) = true to stack
|
||||
|
||||
// Evaluating it does nothing; it's only a boundary condition.
|
||||
override fun evaluate(
|
||||
|
@ -122,10 +122,10 @@ sealed interface ContinuationFrame {
|
|||
|
||||
/** When halting, we add the stack state at halt to the stack accumulator, then return the original pre-Thoth stack, plus the accumulator. */
|
||||
override fun breakDownwards(stack: List<SpellDatum<*>>): Pair<Boolean, List<SpellDatum<*>>> {
|
||||
val newStack = baseStack!!.toMutableList()
|
||||
val newStack = baseStack?.toMutableList() ?: mutableListOf()
|
||||
acc.addAll(stack)
|
||||
newStack.add(SpellDatum.make(acc))
|
||||
return Pair(true, newStack)
|
||||
return true to newStack
|
||||
}
|
||||
|
||||
/** Step the Thoth computation, enqueueing one code evaluation. */
|
||||
|
@ -146,17 +146,15 @@ sealed interface ContinuationFrame {
|
|||
|
||||
// If we still have data to process...
|
||||
val (stackTop, newCont) = if (data.nonEmpty) {
|
||||
Pair(
|
||||
data.car, // Push the next datum to the top of the stack,
|
||||
continuation
|
||||
// put the next Thoth object back on the stack for the next Thoth cycle,
|
||||
.pushFrame(ForEach(data.cdr, code, stack, acc))
|
||||
// and prep the Thoth'd code block for evaluation.
|
||||
.pushFrame(Evaluate(code))
|
||||
)
|
||||
// Push the next datum to the top of the stack,
|
||||
data.car to continuation
|
||||
// put the next Thoth object back on the stack for the next Thoth cycle,
|
||||
.pushFrame(ForEach(data.cdr, code, stack, acc))
|
||||
// and prep the Thoth'd code block for evaluation.
|
||||
.pushFrame(Evaluate(code))
|
||||
} else {
|
||||
// Else, dump our final list onto the stack.
|
||||
Pair(SpellDatum.make(acc), continuation)
|
||||
SpellDatum.make(acc) to continuation
|
||||
}
|
||||
val tStack = stack.toMutableList()
|
||||
tStack.add(stackTop)
|
||||
|
|
|
@ -4,8 +4,6 @@ import at.petrak.hexcasting.api.spell.SpellDatum
|
|||
|
||||
/**
|
||||
* A change to the data in a CastHarness after a pattern is drawn.
|
||||
*
|
||||
* [wasThisPatternInvalid] is for the benefit of the controller.
|
||||
*/
|
||||
data class FunctionalData(
|
||||
val stack: List<SpellDatum<*>>,
|
||||
|
|
|
@ -23,15 +23,15 @@ data class HexPattern(public val startDir: HexDir, public val angles: MutableLis
|
|||
var compass = this.startDir
|
||||
var cursor = HexCoord.Origin
|
||||
for (a in this.angles) {
|
||||
linesSeen.add(Pair(cursor, compass))
|
||||
linesSeen.add(cursor to compass)
|
||||
// Line from here to there also blocks there to here
|
||||
linesSeen.add(Pair(cursor + compass, compass.rotatedBy(HexAngle.BACK)))
|
||||
linesSeen.add(cursor + compass to compass.rotatedBy(HexAngle.BACK))
|
||||
cursor += compass
|
||||
compass *= a
|
||||
}
|
||||
cursor += compass
|
||||
|
||||
val potentialNewLine = Pair(cursor, newDir)
|
||||
val potentialNewLine = cursor to newDir
|
||||
if (potentialNewLine in linesSeen) return false
|
||||
val nextAngle = newDir - compass
|
||||
if (nextAngle == HexAngle.BACK) return false
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@file:JvmName("ManaHelper")
|
||||
package at.petrak.hexcasting.api.utils
|
||||
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
|
@ -5,76 +6,70 @@ import net.minecraft.util.Mth
|
|||
import net.minecraft.world.item.ItemStack
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object ManaHelper {
|
||||
@JvmStatic
|
||||
fun isManaItem(stack: ItemStack): Boolean {
|
||||
val manaHolder = IXplatAbstractions.INSTANCE.findManaHolder(stack) ?: return false
|
||||
if (!manaHolder.canProvide())
|
||||
return false
|
||||
return manaHolder.withdrawMana(-1, true) > 0
|
||||
}
|
||||
fun isManaItem(stack: ItemStack): Boolean {
|
||||
val manaHolder = IXplatAbstractions.INSTANCE.findManaHolder(stack) ?: return false
|
||||
if (!manaHolder.canProvide())
|
||||
return false
|
||||
return manaHolder.withdrawMana(-1, true) > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract [cost] mana from [stack]. If [cost] is less than zero, extract all mana instead.
|
||||
* This may mutate [stack] (and may consume it) unless [simulate] is set.
|
||||
*
|
||||
* If [drainForBatteries] is false, this will only consider forms of mana that can be used to make new batteries.
|
||||
*
|
||||
* Return the amount of mana extracted. This may be over [cost] if mana is wasted.
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun extractMana(
|
||||
stack: ItemStack,
|
||||
cost: Int = -1,
|
||||
drainForBatteries: Boolean = false,
|
||||
simulate: Boolean = false
|
||||
): Int {
|
||||
val manaHolder = IXplatAbstractions.INSTANCE.findManaHolder(stack) ?: return 0
|
||||
/**
|
||||
* Extract [cost] mana from [stack]. If [cost] is less than zero, extract all mana instead.
|
||||
* This may mutate [stack] (and may consume it) unless [simulate] is set.
|
||||
*
|
||||
* If [drainForBatteries] is false, this will only consider forms of mana that can be used to make new batteries.
|
||||
*
|
||||
* Return the amount of mana extracted. This may be over [cost] if mana is wasted.
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun extractMana(
|
||||
stack: ItemStack,
|
||||
cost: Int = -1,
|
||||
drainForBatteries: Boolean = false,
|
||||
simulate: Boolean = false
|
||||
): Int {
|
||||
val manaHolder = IXplatAbstractions.INSTANCE.findManaHolder(stack) ?: return 0
|
||||
|
||||
if (drainForBatteries && !manaHolder.canConstructBattery())
|
||||
return 0
|
||||
if (drainForBatteries && !manaHolder.canConstructBattery())
|
||||
return 0
|
||||
|
||||
return manaHolder.withdrawMana(cost, simulate)
|
||||
}
|
||||
return manaHolder.withdrawMana(cost, simulate)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorted from least important to most important
|
||||
*/
|
||||
fun compare(astack: ItemStack, bstack: ItemStack): Int {
|
||||
val aMana = IXplatAbstractions.INSTANCE.findManaHolder(astack)
|
||||
val bMana = IXplatAbstractions.INSTANCE.findManaHolder(bstack)
|
||||
/**
|
||||
* Sorted from least important to most important
|
||||
*/
|
||||
fun compareManaItem(astack: ItemStack, bstack: ItemStack): Int {
|
||||
val aMana = IXplatAbstractions.INSTANCE.findManaHolder(astack)
|
||||
val bMana = IXplatAbstractions.INSTANCE.findManaHolder(bstack)
|
||||
|
||||
return if (astack.item != bstack.item) {
|
||||
(aMana?.consumptionPriority ?: 0) - (bMana?.consumptionPriority ?: 0)
|
||||
} else if (aMana != null && bMana != null) {
|
||||
aMana.mana - bMana.mana
|
||||
} else {
|
||||
astack.count - bstack.count
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun barColor(mana: Int, maxMana: Int): Int {
|
||||
val amt = if (maxMana == 0) {
|
||||
0f
|
||||
} else {
|
||||
mana.toFloat() / maxMana.toFloat()
|
||||
}
|
||||
|
||||
val r = Mth.lerp(amt, 84f, 254f)
|
||||
val g = Mth.lerp(amt, 57f, 203f)
|
||||
val b = Mth.lerp(amt, 138f, 230f)
|
||||
return Mth.color(r / 255f, g / 255f, b / 255f)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun barWidth(mana: Int, maxMana: Int): Int {
|
||||
val amt = if (maxMana == 0) {
|
||||
0f
|
||||
} else {
|
||||
mana.toFloat() / maxMana.toFloat()
|
||||
}
|
||||
return (13f * amt).roundToInt()
|
||||
return if (astack.item != bstack.item) {
|
||||
(aMana?.consumptionPriority ?: 0) - (bMana?.consumptionPriority ?: 0)
|
||||
} else if (aMana != null && bMana != null) {
|
||||
aMana.mana - bMana.mana
|
||||
} else {
|
||||
astack.count - bstack.count
|
||||
}
|
||||
}
|
||||
|
||||
fun manaBarColor(mana: Int, maxMana: Int): Int {
|
||||
val amt = if (maxMana == 0) {
|
||||
0f
|
||||
} else {
|
||||
mana.toFloat() / maxMana.toFloat()
|
||||
}
|
||||
|
||||
val r = Mth.lerp(amt, 84f, 254f)
|
||||
val g = Mth.lerp(amt, 57f, 203f)
|
||||
val b = Mth.lerp(amt, 138f, 230f)
|
||||
return Mth.color(r / 255f, g / 255f, b / 255f)
|
||||
}
|
||||
|
||||
fun manaBarWidth(mana: Int, maxMana: Int): Int {
|
||||
val amt = if (maxMana == 0) {
|
||||
0f
|
||||
} else {
|
||||
mana.toFloat() / maxMana.toFloat()
|
||||
}
|
||||
return (13f * amt).roundToInt()
|
||||
}
|
||||
|
|
|
@ -134,15 +134,15 @@ value class NbtListBuilder(val tag: ListTag) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add the given Tag<* tags to this list
|
||||
* Add the given tags to this list
|
||||
*/
|
||||
inline operator fun Collection<Tag>.unaryPlus() {
|
||||
tag.addAll(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given Tag<* tag to this list. This is explicitly defined for [ListTag] because otherwise there is overload
|
||||
* ambiguity between the [Tag<*] and [Collection]<[Tag<*]> methods.
|
||||
* Add the given tag to this list. This is explicitly defined for [ListTag] because otherwise there is overload
|
||||
* ambiguity between the [Tag] and [Collection]<Tag> methods.
|
||||
*/
|
||||
inline operator fun ListTag.unaryPlus() {
|
||||
tag.add(this)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
@file:JvmName("RenderLib")
|
||||
package at.petrak.hexcasting.client
|
||||
|
||||
import at.petrak.hexcasting.api.mod.HexConfig
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.utils.TAU
|
||||
import at.petrak.hexcasting.client.gui.GuiSpellcasting
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
|
@ -12,6 +14,7 @@ import com.mojang.math.Matrix4f
|
|||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.util.FastColor
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.levelgen.XoroshiroRandomSource
|
||||
|
@ -19,272 +22,259 @@ import net.minecraft.world.level.levelgen.synth.PerlinNoise
|
|||
import net.minecraft.world.phys.Vec2
|
||||
import kotlin.math.floor
|
||||
import kotlin.math.min
|
||||
import net.minecraft.util.FastColor.ARGB32 as FC
|
||||
|
||||
/**
|
||||
* Common draw code
|
||||
* Source of perlin noise
|
||||
*/
|
||||
object RenderLib {
|
||||
/**
|
||||
* Source of perlin noise
|
||||
*/
|
||||
val NOISE = PerlinNoise.create(XoroshiroRandomSource(9001L), listOf(0, 1, 2, 3, 4))
|
||||
val NOISE: PerlinNoise = PerlinNoise.create(XoroshiroRandomSource(9001L), listOf(0, 1, 2, 3, 4))
|
||||
|
||||
/**
|
||||
* Draw a sequence of linePoints spanning the given points.
|
||||
*
|
||||
* Please make sure to enable the right asinine shaders; see [GuiSpellcasting][at.petrak.hexcasting.client.gui.GuiSpellcasting]
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun drawLineSeq(
|
||||
mat: Matrix4f,
|
||||
points: List<Vec2>,
|
||||
width: Float,
|
||||
z: Float,
|
||||
tail: Int,
|
||||
head: Int,
|
||||
animTime: Float? = null,
|
||||
) {
|
||||
if (points.size <= 1) return
|
||||
/**
|
||||
* Draw a sequence of linePoints spanning the given points.
|
||||
*
|
||||
* Please make sure to enable the right asinine shaders; see [GuiSpellcasting]
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun drawLineSeq(
|
||||
mat: Matrix4f,
|
||||
points: List<Vec2>,
|
||||
width: Float,
|
||||
z: Float,
|
||||
tail: Int,
|
||||
head: Int,
|
||||
animTime: Float? = null,
|
||||
) {
|
||||
if (points.size <= 1) return
|
||||
|
||||
val r1 = FC.red(tail).toFloat()
|
||||
val g1 = FC.green(tail).toFloat()
|
||||
val b1 = FC.blue(tail).toFloat()
|
||||
val a = FC.alpha(tail)
|
||||
val headSource = if (Screen.hasControlDown() != HexConfig.client().ctrlTogglesOffStrokeOrder())
|
||||
head
|
||||
else
|
||||
tail
|
||||
val r2 = FC.red(headSource).toFloat()
|
||||
val g2 = FC.green(headSource).toFloat()
|
||||
val b2 = FC.blue(headSource).toFloat()
|
||||
val r1 = FastColor.ARGB32.red(tail).toFloat()
|
||||
val g1 = FastColor.ARGB32.green(tail).toFloat()
|
||||
val b1 = FastColor.ARGB32.blue(tail).toFloat()
|
||||
val a = FastColor.ARGB32.alpha(tail)
|
||||
val headSource = if (Screen.hasControlDown() != HexConfig.client().ctrlTogglesOffStrokeOrder())
|
||||
head
|
||||
else
|
||||
tail
|
||||
val r2 = FastColor.ARGB32.red(headSource).toFloat()
|
||||
val g2 = FastColor.ARGB32.green(headSource).toFloat()
|
||||
val b2 = FastColor.ARGB32.blue(headSource).toFloat()
|
||||
|
||||
// they spell it wrong at mojang lmao
|
||||
val tess = Tesselator.getInstance()
|
||||
val buf = tess.builder
|
||||
// they spell it wrong at mojang lmao
|
||||
val tess = Tesselator.getInstance()
|
||||
val buf = tess.builder
|
||||
|
||||
// We use one single TRIANGLE_STRIP
|
||||
// in order to connect adjacent segments together and not get the weird hinge effect.
|
||||
// There's still some artifacting but this is passable, at least.
|
||||
buf.begin(VertexFormat.Mode.TRIANGLE_STRIP, DefaultVertexFormat.POSITION_COLOR)
|
||||
// We use one single TRIANGLE_STRIP
|
||||
// in order to connect adjacent segments together and not get the weird hinge effect.
|
||||
// There's still some artifacting but this is passable, at least.
|
||||
buf.begin(VertexFormat.Mode.TRIANGLE_STRIP, DefaultVertexFormat.POSITION_COLOR)
|
||||
|
||||
val n = points.size
|
||||
for ((i, pair) in points.zipWithNext().withIndex()) {
|
||||
val (p1, p2) = pair
|
||||
// https://github.com/not-fl3/macroquad/blob/master/src/shapes.rs#L163
|
||||
// GuiComponent::innerFill line 52
|
||||
// fedor have useful variable names challenge (99% can't beat)
|
||||
val dx = p2.x - p1.x
|
||||
val dy = p2.y - p1.y
|
||||
// normal x and y, presumably?
|
||||
val nx = -dy
|
||||
val ny = dx
|
||||
// thickness?
|
||||
val tlen = Mth.sqrt(nx * nx + ny * ny) / (width * 0.5f)
|
||||
val tx = nx / tlen
|
||||
val ty = ny / tlen
|
||||
val n = points.size
|
||||
for ((i, pair) in points.zipWithNext().withIndex()) {
|
||||
val (p1, p2) = pair
|
||||
// https://github.com/not-fl3/macroquad/blob/master/src/shapes.rs#L163
|
||||
// GuiComponent::innerFill line 52
|
||||
// fedor have useful variable names challenge (99% can't beat)
|
||||
val dx = p2.x - p1.x
|
||||
val dy = p2.y - p1.y
|
||||
// normal x and y, presumably?
|
||||
val nx = -dy
|
||||
val ny = dx
|
||||
// thickness?
|
||||
val tlen = Mth.sqrt(nx * nx + ny * ny) / (width * 0.5f)
|
||||
val tx = nx / tlen
|
||||
val ty = ny / tlen
|
||||
|
||||
fun color(time: Float): BlockPos =
|
||||
BlockPos(Mth.lerp(time, r1, r2).toInt(), Mth.lerp(time, g1, g2).toInt(), Mth.lerp(time, b1, b2).toInt())
|
||||
fun color(time: Float): BlockPos =
|
||||
BlockPos(Mth.lerp(time, r1, r2).toInt(), Mth.lerp(time, g1, g2).toInt(), Mth.lerp(time, b1, b2).toInt())
|
||||
|
||||
val color1 = color(i.toFloat() / n)
|
||||
val color2 = color((i + 1f) / n)
|
||||
buf.vertex(mat, p1.x + tx, p1.y + ty, z).color(color1.x, color1.y, color1.z, a).endVertex()
|
||||
buf.vertex(mat, p1.x - tx, p1.y - ty, z).color(color1.x, color1.y, color1.z, a).endVertex()
|
||||
buf.vertex(mat, p2.x + tx, p2.y + ty, z).color(color2.x, color2.y, color2.z, a).endVertex()
|
||||
buf.vertex(mat, p2.x - tx, p2.y - ty, z).color(color2.x, color2.y, color2.z, a).endVertex()
|
||||
}
|
||||
tess.end()
|
||||
|
||||
if (animTime != null) {
|
||||
val pointCircuit =
|
||||
(animTime * 30f * HexConfig.client().patternPointSpeedMultiplier().toFloat()) % (points.size + 10)
|
||||
// subtract 1 to avoid the point appearing between the end and start for 1 frame
|
||||
if (pointCircuit < points.size - 1) {
|
||||
val pointMacro = floor(pointCircuit).toInt()
|
||||
val pointMicro = pointCircuit - pointMacro
|
||||
|
||||
val p1 = points[pointMacro]
|
||||
val p2 = points[(pointMacro + 1) % points.size]
|
||||
val drawPos = Vec2(
|
||||
p1.x + (p2.x - p1.x) * pointMicro,
|
||||
p1.y + (p2.y - p1.y) * pointMicro,
|
||||
)
|
||||
drawSpot(
|
||||
mat,
|
||||
drawPos,
|
||||
2f,
|
||||
(r1 + 255) / 2f / 255f,
|
||||
(g1 + 255) / 2f / 255f,
|
||||
(b1 + 255) / 2f / 255f,
|
||||
a / 1.2f / 255f
|
||||
)
|
||||
}
|
||||
}
|
||||
val color1 = color(i.toFloat() / n)
|
||||
val color2 = color((i + 1f) / n)
|
||||
buf.vertex(mat, p1.x + tx, p1.y + ty, z).color(color1.x, color1.y, color1.z, a).endVertex()
|
||||
buf.vertex(mat, p1.x - tx, p1.y - ty, z).color(color1.x, color1.y, color1.z, a).endVertex()
|
||||
buf.vertex(mat, p2.x + tx, p2.y + ty, z).color(color2.x, color2.y, color2.z, a).endVertex()
|
||||
buf.vertex(mat, p2.x - tx, p2.y - ty, z).color(color2.x, color2.y, color2.z, a).endVertex()
|
||||
}
|
||||
tess.end()
|
||||
|
||||
/**
|
||||
* Draw a hex pattern from the given list of non-zappy points (as in, do the *style* of drawing it,
|
||||
* you have to do the conversion yourself.)
|
||||
*/
|
||||
@JvmStatic
|
||||
fun drawPatternFromPoints(
|
||||
mat: Matrix4f,
|
||||
points: List<Vec2>,
|
||||
drawLast: Boolean,
|
||||
tail: Int,
|
||||
head: Int,
|
||||
animTime: Float? = null
|
||||
) {
|
||||
val zappyPts = makeZappy(points, 10f, 2.5f, 0.1f)
|
||||
val nodes = if (drawLast) {
|
||||
points
|
||||
} else {
|
||||
points.dropLast(1)
|
||||
}
|
||||
drawLineSeq(mat, zappyPts, 5f, 0f, tail, head, null)
|
||||
drawLineSeq(mat, zappyPts, 2f, 1f, screenCol(tail), screenCol(head), animTime)
|
||||
for (node in nodes) {
|
||||
if (animTime != null) {
|
||||
val pointCircuit =
|
||||
(animTime * 30f * HexConfig.client().patternPointSpeedMultiplier().toFloat()) % (points.size + 10)
|
||||
// subtract 1 to avoid the point appearing between the end and start for 1 frame
|
||||
if (pointCircuit < points.size - 1) {
|
||||
val pointMacro = floor(pointCircuit).toInt()
|
||||
val pointMicro = pointCircuit - pointMacro
|
||||
|
||||
val p1 = points[pointMacro]
|
||||
val p2 = points[(pointMacro + 1) % points.size]
|
||||
val drawPos = Vec2(
|
||||
p1.x + (p2.x - p1.x) * pointMicro,
|
||||
p1.y + (p2.y - p1.y) * pointMicro,
|
||||
)
|
||||
drawSpot(
|
||||
mat,
|
||||
node,
|
||||
drawPos,
|
||||
2f,
|
||||
dodge(FC.red(head)) / 255f,
|
||||
dodge(FC.green(head)) / 255f,
|
||||
dodge(FC.blue(head)) / 255f,
|
||||
FC.alpha(head) / 255f
|
||||
);
|
||||
(r1 + 255) / 2f / 255f,
|
||||
(g1 + 255) / 2f / 255f,
|
||||
(b1 + 255) / 2f / 255f,
|
||||
a / 1.2f / 255f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split up a sequence of linePoints with a lightning effect
|
||||
* @param hops: rough number of points to subdivide each segment into
|
||||
* @param speed: rate at which the lightning effect should move/shake/etc
|
||||
*/
|
||||
@JvmStatic
|
||||
fun makeZappy(points: List<Vec2>, hops: Float, variance: Float, speed: Float): List<Vec2> {
|
||||
// Nothing in, nothing out
|
||||
if (points.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
val zSeed = (ClientTickCounter.total.toDouble()) * speed
|
||||
// Create our output list of zap points
|
||||
val zappyPts = mutableListOf(points[0])
|
||||
// For each segment in the original...
|
||||
for ((i, pair) in points.zipWithNext().withIndex()) {
|
||||
val (src, target) = pair
|
||||
// Compute distance-squared to the destination, then scale it down by # of hops
|
||||
// to know how long each individual hop should be (squared)
|
||||
val hopDistSqr = src.distanceToSqr(target) / (hops * hops)
|
||||
// Then take the square root to find the actual hop distance
|
||||
val hopDist = Mth.sqrt(hopDistSqr)
|
||||
// Compute how big the radius of variance should be
|
||||
val maxVariance = hopDist * variance
|
||||
|
||||
var position = src
|
||||
var j = 0
|
||||
while (position.distanceToSqr(target) > hopDistSqr) {
|
||||
// Add the next hop...
|
||||
val hop = target.add(position.negated()).normalized().scale(hopDist)
|
||||
// as well as some random variance...
|
||||
// (We use i, j (segment #, subsegment #) as seeds for the Perlin noise,
|
||||
// and zSeed (i.e. time elapsed) to perturb the shape gradually over time)
|
||||
val theta = (3 * NOISE.getValue(i.toDouble(), j.toDouble(), zSeed) * TAU).toFloat()
|
||||
val r = NOISE.getValue(i.inv().toDouble(), j.toDouble(), zSeed).toFloat() * maxVariance
|
||||
val randomHop = Vec2(r * Mth.cos(theta), r * Mth.sin(theta))
|
||||
position = position.add(hop).add(randomHop)
|
||||
// Then record the new location.
|
||||
zappyPts.add(position)
|
||||
j += 1
|
||||
}
|
||||
// Finally, we hit the destination, add that too
|
||||
zappyPts.add(target)
|
||||
}
|
||||
return zappyPts
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a little circle, because Minecraft rendering code is a nightmare and doesn't
|
||||
* include primitive drawing code...
|
||||
*/
|
||||
@JvmStatic
|
||||
fun drawSpot(mat: Matrix4f, point: Vec2, radius: Float, r: Float, g: Float, b: Float, a: Float) {
|
||||
val tess = Tesselator.getInstance()
|
||||
val buf = tess.builder
|
||||
// https://stackoverflow.com/questions/20394727/gl-triangle-strip-vs-gl-triangle-fan
|
||||
// Starting point is the center
|
||||
buf.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR)
|
||||
buf.vertex(mat, point.x, point.y, 1f).color(r, g, b, a).endVertex()
|
||||
|
||||
// https://github.com/not-fl3/macroquad/blob/master/src/shapes.rs#L98
|
||||
// yes they are gonna be little hexagons fite me
|
||||
val fracOfCircle = 6
|
||||
// run 0 AND last; this way the circle closes
|
||||
for (i in 0..fracOfCircle) {
|
||||
val theta = i.toFloat() / fracOfCircle * TAU.toFloat()
|
||||
val rx = Mth.cos(theta) * radius + point.x
|
||||
val ry = Mth.sin(theta) * radius + point.y
|
||||
buf.vertex(mat, rx, ry, 1f).color(r, g, b, a).endVertex()
|
||||
}
|
||||
|
||||
tess.end()
|
||||
}
|
||||
|
||||
fun dodge(n: Int): Float = n * 0.9f
|
||||
fun screen(n: Int): Int = (n + 255) / 2
|
||||
|
||||
@JvmStatic
|
||||
fun screenCol(n: Int): Int {
|
||||
return FC.color(
|
||||
FC.alpha(n),
|
||||
screen(FC.red(n)),
|
||||
screen(FC.green(n)),
|
||||
screen(FC.blue(n)),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scale and dots formed by the pattern when centered.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getCenteredPattern(pattern: HexPattern, width: Float, height: Float, minSize: Float): Pair<Float, List<Vec2>> {
|
||||
// Do two passes: one with a random size to find a good COM and one with the real calculation
|
||||
val com1: Vec2 = pattern.getCenter(1f)
|
||||
val lines1: List<Vec2> = pattern.toLines(1f, Vec2.ZERO)
|
||||
var maxDx = -1f
|
||||
var maxDy = -1f
|
||||
for (dot in lines1) {
|
||||
val dx = Mth.abs(dot.x - com1.x)
|
||||
if (dx > maxDx) {
|
||||
maxDx = dx
|
||||
}
|
||||
val dy = Mth.abs(dot.y - com1.y)
|
||||
if (dy > maxDy) {
|
||||
maxDy = dy
|
||||
}
|
||||
}
|
||||
val scale =
|
||||
min(minSize, min(width / 3f / maxDx, height / 3f / maxDy))
|
||||
val com2: Vec2 = pattern.getCenter(scale)
|
||||
val lines2: List<Vec2> = pattern.toLines(scale, com2.negated())
|
||||
return Pair(scale, lines2)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun renderItemStackInGui(ms: PoseStack, stack: ItemStack, x: Int, y: Int) {
|
||||
transferMsToGl(ms) { Minecraft.getInstance().itemRenderer.renderAndDecorateItem(stack, x, y) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun transferMsToGl(ms: PoseStack, toRun: Runnable) {
|
||||
val mvs = RenderSystem.getModelViewStack()
|
||||
mvs.pushPose()
|
||||
mvs.mulPoseMatrix(ms.last().pose())
|
||||
RenderSystem.applyModelViewMatrix()
|
||||
toRun.run()
|
||||
mvs.popPose()
|
||||
RenderSystem.applyModelViewMatrix()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a hex pattern from the given list of non-zappy points (as in, do the *style* of drawing it,
|
||||
* you have to do the conversion yourself.)
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun drawPatternFromPoints(
|
||||
mat: Matrix4f,
|
||||
points: List<Vec2>,
|
||||
drawLast: Boolean,
|
||||
tail: Int,
|
||||
head: Int,
|
||||
animTime: Float? = null
|
||||
) {
|
||||
val zappyPts = makeZappy(points, 10f, 2.5f, 0.1f)
|
||||
val nodes = if (drawLast) {
|
||||
points
|
||||
} else {
|
||||
points.dropLast(1)
|
||||
}
|
||||
drawLineSeq(mat, zappyPts, 5f, 0f, tail, head, null)
|
||||
drawLineSeq(mat, zappyPts, 2f, 1f, screenCol(tail), screenCol(head), animTime)
|
||||
for (node in nodes) {
|
||||
drawSpot(
|
||||
mat,
|
||||
node,
|
||||
2f,
|
||||
dodge(FastColor.ARGB32.red(head)) / 255f,
|
||||
dodge(FastColor.ARGB32.green(head)) / 255f,
|
||||
dodge(FastColor.ARGB32.blue(head)) / 255f,
|
||||
FastColor.ARGB32.alpha(head) / 255f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split up a sequence of linePoints with a lightning effect
|
||||
* @param hops: rough number of points to subdivide each segment into
|
||||
* @param speed: rate at which the lightning effect should move/shake/etc
|
||||
*/
|
||||
fun makeZappy(points: List<Vec2>, hops: Float, variance: Float, speed: Float): List<Vec2> {
|
||||
// Nothing in, nothing out
|
||||
if (points.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
val zSeed = (ClientTickCounter.total.toDouble()) * speed
|
||||
// Create our output list of zap points
|
||||
val zappyPts = mutableListOf(points[0])
|
||||
// For each segment in the original...
|
||||
for ((i, pair) in points.zipWithNext().withIndex()) {
|
||||
val (src, target) = pair
|
||||
// Compute distance-squared to the destination, then scale it down by # of hops
|
||||
// to know how long each individual hop should be (squared)
|
||||
val hopDistSqr = src.distanceToSqr(target) / (hops * hops)
|
||||
// Then take the square root to find the actual hop distance
|
||||
val hopDist = Mth.sqrt(hopDistSqr)
|
||||
// Compute how big the radius of variance should be
|
||||
val maxVariance = hopDist * variance
|
||||
|
||||
var position = src
|
||||
var j = 0
|
||||
while (position.distanceToSqr(target) > hopDistSqr) {
|
||||
// Add the next hop...
|
||||
val hop = target.add(position.negated()).normalized().scale(hopDist)
|
||||
// as well as some random variance...
|
||||
// (We use i, j (segment #, subsegment #) as seeds for the Perlin noise,
|
||||
// and zSeed (i.e. time elapsed) to perturb the shape gradually over time)
|
||||
val theta = (3 * NOISE.getValue(i.toDouble(), j.toDouble(), zSeed) * TAU).toFloat()
|
||||
val r = NOISE.getValue(i.inv().toDouble(), j.toDouble(), zSeed).toFloat() * maxVariance
|
||||
val randomHop = Vec2(r * Mth.cos(theta), r * Mth.sin(theta))
|
||||
position = position.add(hop).add(randomHop)
|
||||
// Then record the new location.
|
||||
zappyPts.add(position)
|
||||
j += 1
|
||||
}
|
||||
// Finally, we hit the destination, add that too
|
||||
zappyPts.add(target)
|
||||
}
|
||||
return zappyPts
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a little circle, because Minecraft rendering code is a nightmare and doesn't
|
||||
* include primitive drawing code...
|
||||
*/
|
||||
fun drawSpot(mat: Matrix4f, point: Vec2, radius: Float, r: Float, g: Float, b: Float, a: Float) {
|
||||
val tess = Tesselator.getInstance()
|
||||
val buf = tess.builder
|
||||
// https://stackoverflow.com/questions/20394727/gl-triangle-strip-vs-gl-triangle-fan
|
||||
// Starting point is the center
|
||||
buf.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR)
|
||||
buf.vertex(mat, point.x, point.y, 1f).color(r, g, b, a).endVertex()
|
||||
|
||||
// https://github.com/not-fl3/macroquad/blob/master/src/shapes.rs#L98
|
||||
// yes they are gonna be little hexagons fite me
|
||||
val fracOfCircle = 6
|
||||
// run 0 AND last; this way the circle closes
|
||||
for (i in 0..fracOfCircle) {
|
||||
val theta = i.toFloat() / fracOfCircle * TAU.toFloat()
|
||||
val rx = Mth.cos(theta) * radius + point.x
|
||||
val ry = Mth.sin(theta) * radius + point.y
|
||||
buf.vertex(mat, rx, ry, 1f).color(r, g, b, a).endVertex()
|
||||
}
|
||||
|
||||
tess.end()
|
||||
}
|
||||
|
||||
fun screenCol(n: Int): Int {
|
||||
return FastColor.ARGB32.color(
|
||||
FastColor.ARGB32.alpha(n),
|
||||
screen(FastColor.ARGB32.red(n)),
|
||||
screen(FastColor.ARGB32.green(n)),
|
||||
screen(FastColor.ARGB32.blue(n)),
|
||||
)
|
||||
}
|
||||
|
||||
fun screen(n: Int) = (n + 255) / 2
|
||||
fun dodge(n: Int) = n * 0.9f
|
||||
|
||||
/**
|
||||
* Return the scale and dots formed by the pattern when centered.
|
||||
*/
|
||||
fun getCenteredPattern(pattern: HexPattern, width: Float, height: Float, minSize: Float): Pair<Float, List<Vec2>> {
|
||||
// Do two passes: one with a random size to find a good COM and one with the real calculation
|
||||
val com1: Vec2 = pattern.getCenter(1f)
|
||||
val lines1: List<Vec2> = pattern.toLines(1f, Vec2.ZERO)
|
||||
var maxDx = -1f
|
||||
var maxDy = -1f
|
||||
for (dot in lines1) {
|
||||
val dx = Mth.abs(dot.x - com1.x)
|
||||
if (dx > maxDx) {
|
||||
maxDx = dx
|
||||
}
|
||||
val dy = Mth.abs(dot.y - com1.y)
|
||||
if (dy > maxDy) {
|
||||
maxDy = dy
|
||||
}
|
||||
}
|
||||
val scale =
|
||||
min(minSize, min(width / 3f / maxDx, height / 3f / maxDy))
|
||||
val com2: Vec2 = pattern.getCenter(scale)
|
||||
val lines2: List<Vec2> = pattern.toLines(scale, com2.negated())
|
||||
return scale to lines2
|
||||
}
|
||||
|
||||
fun renderItemStackInGui(ms: PoseStack, stack: ItemStack, x: Int, y: Int) {
|
||||
transferMsToGl(ms) { Minecraft.getInstance().itemRenderer.renderAndDecorateItem(stack, x, y) }
|
||||
}
|
||||
|
||||
fun transferMsToGl(ms: PoseStack, toRun: Runnable) {
|
||||
val mvs = RenderSystem.getModelViewStack()
|
||||
mvs.pushPose()
|
||||
mvs.mulPoseMatrix(ms.last().pose())
|
||||
RenderSystem.applyModelViewMatrix()
|
||||
toRun.run()
|
||||
mvs.popPose()
|
||||
RenderSystem.applyModelViewMatrix()
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import at.petrak.hexcasting.api.spell.math.HexCoord
|
|||
import at.petrak.hexcasting.api.spell.math.HexDir
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.utils.otherHand
|
||||
import at.petrak.hexcasting.client.RenderLib
|
||||
import at.petrak.hexcasting.client.drawPatternFromPoints
|
||||
import at.petrak.hexcasting.client.drawSpot
|
||||
import at.petrak.hexcasting.client.sound.GridSoundInstance
|
||||
import at.petrak.hexcasting.common.items.ItemSpellbook
|
||||
import at.petrak.hexcasting.common.lib.HexItems
|
||||
|
@ -279,7 +280,7 @@ class GuiSpellcasting(
|
|||
0f,
|
||||
1f
|
||||
)
|
||||
RenderLib.drawSpot(
|
||||
drawSpot(
|
||||
mat,
|
||||
dotPx,
|
||||
scaledDist * 2f,
|
||||
|
@ -293,7 +294,7 @@ class GuiSpellcasting(
|
|||
RenderSystem.defaultBlendFunc()
|
||||
|
||||
for ((pat, origin, valid) in this.patterns) {
|
||||
RenderLib.drawPatternFromPoints(mat, pat.toLines(
|
||||
drawPatternFromPoints(mat, pat.toLines(
|
||||
this.hexSize(),
|
||||
this.coordToPx(origin)
|
||||
), true, valid.color or (0xC8 shl 24), valid.fadeColor or (0xC8 shl 24))
|
||||
|
@ -315,7 +316,7 @@ class GuiSpellcasting(
|
|||
}
|
||||
|
||||
points.add(mousePos)
|
||||
RenderLib.drawPatternFromPoints(mat, points, false, 0xff_64c8ff_u.toInt(), 0xff_fecbe6_u.toInt())
|
||||
drawPatternFromPoints(mat, points, false, 0xff_64c8ff_u.toInt(), 0xff_fecbe6_u.toInt())
|
||||
}
|
||||
|
||||
RenderSystem.setShader { prevShader }
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package at.petrak.hexcasting.client.gui;
|
||||
|
||||
import at.petrak.hexcasting.client.ClientTickCounter;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
|
|
|
@ -10,7 +10,8 @@ import at.petrak.hexcasting.api.spell.SpellOperator
|
|||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.api.utils.extractMana
|
||||
import at.petrak.hexcasting.api.utils.isManaItem
|
||||
import at.petrak.hexcasting.common.items.magic.ItemManaHolder
|
||||
import at.petrak.hexcasting.common.lib.HexItems
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
@ -46,7 +47,7 @@ object OpMakeBattery : SpellOperator {
|
|||
|
||||
ctx.assertEntityInRange(entity)
|
||||
|
||||
if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(
|
||||
if (!isManaItem(entity.item) || extractMana(
|
||||
entity.item,
|
||||
drainForBatteries = true,
|
||||
simulate = true
|
||||
|
@ -67,7 +68,7 @@ object OpMakeBattery : SpellOperator {
|
|||
val (handStack, hand) = ctx.getHeldItemToOperateOn { it.`is`(HexItemTags.PHIAL_BASE) }
|
||||
if (handStack.`is`(HexItemTags.PHIAL_BASE) && itemEntity.isAlive) {
|
||||
val entityStack = itemEntity.item.copy()
|
||||
val manaAmt = ManaHelper.extractMana(entityStack, drainForBatteries = true)
|
||||
val manaAmt = extractMana(entityStack, drainForBatteries = true)
|
||||
if (manaAmt > 0) {
|
||||
ctx.caster.setItemInHand(
|
||||
hand,
|
||||
|
|
|
@ -10,7 +10,8 @@ import at.petrak.hexcasting.api.spell.casting.CastingContext
|
|||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapOthersName
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.api.utils.extractMana
|
||||
import at.petrak.hexcasting.api.utils.isManaItem
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedHex
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
@ -36,7 +37,7 @@ class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) :
|
|||
}
|
||||
|
||||
ctx.assertEntityInRange(entity)
|
||||
if (!ManaHelper.isManaItem(entity.item) || ManaHelper.extractMana(
|
||||
if (!isManaItem(entity.item) || extractMana(
|
||||
entity.item,
|
||||
drainForBatteries = true,
|
||||
simulate = true
|
||||
|
@ -64,7 +65,7 @@ class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) :
|
|||
&& itemEntity.isAlive
|
||||
) {
|
||||
val entityStack = itemEntity.item.copy()
|
||||
val manaAmt = ManaHelper.extractMana(entityStack, drainForBatteries = true)
|
||||
val manaAmt = extractMana(entityStack, drainForBatteries = true)
|
||||
if (manaAmt > 0) {
|
||||
hexHolder.writeHex(patterns, manaAmt)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ import at.petrak.hexcasting.api.spell.SpellOperator
|
|||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadItem
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapBadOffhandItem
|
||||
import at.petrak.hexcasting.api.utils.ManaHelper
|
||||
import at.petrak.hexcasting.api.utils.extractMana
|
||||
import at.petrak.hexcasting.api.utils.isManaItem
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
||||
|
@ -37,7 +38,7 @@ object OpRecharge : SpellOperator {
|
|||
val entity = args.getChecked<ItemEntity>(0, argc)
|
||||
ctx.assertEntityInRange(entity)
|
||||
|
||||
if (!ManaHelper.isManaItem(entity.item)) {
|
||||
if (!isManaItem(entity.item)) {
|
||||
throw MishapBadItem.of(
|
||||
entity,
|
||||
"mana"
|
||||
|
@ -65,7 +66,7 @@ object OpRecharge : SpellOperator {
|
|||
val maxMana = mana.maxMana
|
||||
val existingMana = mana.mana
|
||||
|
||||
val manaAmt = ManaHelper.extractMana(entityStack, maxMana - existingMana)
|
||||
val manaAmt = extractMana(entityStack, maxMana - existingMana)
|
||||
|
||||
mana.mana = manaAmt + existingMana
|
||||
|
||||
|
|
|
@ -57,14 +57,14 @@ public abstract class ItemManaHolder extends Item implements ManaHolderItem {
|
|||
public int getBarColor(ItemStack pStack) {
|
||||
var mana = getMana(pStack);
|
||||
var maxMana = getMaxMana(pStack);
|
||||
return ManaHelper.barColor(mana, maxMana);
|
||||
return ManaHelper.manaBarColor(mana, maxMana);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBarWidth(ItemStack pStack) {
|
||||
var mana = getMana(pStack);
|
||||
var maxMana = getMaxMana(pStack);
|
||||
return ManaHelper.barWidth(mana, maxMana);
|
||||
return ManaHelper.manaBarWidth(mana, maxMana);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue