ok i think it works this time
This commit is contained in:
parent
d634824ae7
commit
cb8b4be953
44 changed files with 354 additions and 1261 deletions
|
@ -1,7 +0,0 @@
|
|||
package at.petrak.hexcasting.api.misc;
|
||||
|
||||
public final class ManaConstants {
|
||||
public static final int DUST_UNIT = 10000;
|
||||
public static final int SHARD_UNIT = 5 * DUST_UNIT;
|
||||
public static final int CRYSTAL_UNIT = 10 * DUST_UNIT;
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package at.petrak.hexcasting.api.spell
|
||||
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapInvalidSpellDatumType
|
||||
import at.petrak.hexcasting.api.utils.HexUtils
|
||||
import at.petrak.hexcasting.api.utils.HexUtils.serializeToNBT
|
||||
import at.petrak.hexcasting.api.utils.getList
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.nbt.*
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TextComponent
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Restricted interface for functional lists.
|
||||
*
|
||||
* ...Surely this won't have any performance implications.
|
||||
*/
|
||||
sealed class SpellList: Iterable<SpellDatum<*>> {
|
||||
|
||||
abstract val nonEmpty: Boolean
|
||||
abstract val car: SpellDatum<*>
|
||||
abstract val cdr: SpellList
|
||||
|
||||
class LPair(override val car: SpellDatum<*>, override val cdr: SpellList): SpellList() {
|
||||
override val nonEmpty = true
|
||||
}
|
||||
|
||||
class LList(val idx: Int, val list: List<SpellDatum<*>>): SpellList() {
|
||||
override val nonEmpty: Boolean
|
||||
get() = idx < list.size
|
||||
override val car: SpellDatum<*>
|
||||
get() = list[idx]
|
||||
override val cdr: SpellList
|
||||
get() = LList(idx + 1, list)
|
||||
}
|
||||
|
||||
fun modifyAt(startIdx: Int, modify: (SpellList) -> SpellList): SpellList {
|
||||
val stack = mutableListOf<SpellDatum<*>>()
|
||||
val ptr = iterator()
|
||||
var idx = startIdx
|
||||
if (idx < 0) {
|
||||
return this
|
||||
}
|
||||
while (idx > 0) {
|
||||
if (!ptr.hasNext()) {
|
||||
return this
|
||||
}
|
||||
idx--
|
||||
stack.add(ptr.next())
|
||||
}
|
||||
var value = modify(ptr.list)
|
||||
for (datum in stack.asReversed()) {
|
||||
value = LPair(datum, value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
fun getAt(startIdx: Int): SpellDatum<*> {
|
||||
var ptr = this
|
||||
var idx = startIdx
|
||||
if (idx < 0) {
|
||||
throw ArrayIndexOutOfBoundsException()
|
||||
}
|
||||
while (idx > 0) {
|
||||
when (ptr) {
|
||||
is LPair -> ptr = ptr.cdr
|
||||
is LList -> return ptr.list[ptr.idx + idx]
|
||||
}
|
||||
idx--
|
||||
}
|
||||
return ptr.car
|
||||
}
|
||||
|
||||
override fun toString() = toList().toString()
|
||||
|
||||
override fun iterator() = Iterator(this)
|
||||
|
||||
class Iterator(var list: SpellList): kotlin.collections.Iterator<SpellDatum<*>> {
|
||||
override fun hasNext() = list.nonEmpty
|
||||
override operator fun next(): SpellDatum<*> {
|
||||
val car = list.car
|
||||
list = list.cdr
|
||||
return car
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapError(val exception: Exception) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.BLACK)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
|
||||
error("unknown", actionName(errorCtx.action), exception)
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package at.petrak.hexcasting.api.spell.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.spell.DatumType
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
/**
|
||||
* The value was a naked iota without being Considered or Retrospected.
|
||||
*/
|
||||
class MishapUnescapedValue(
|
||||
val perpetrator: SpellDatum<*>
|
||||
) : Mishap() {
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.GRAY)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
val idx = stack.indexOfLast { it.getType() == DatumType.LIST }
|
||||
if (idx != -1)
|
||||
stack[idx] = SpellDatum.make(Widget.GARBAGE)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
|
||||
error(
|
||||
"unescaped",
|
||||
perpetrator.display()
|
||||
)
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package at.petrak.hexcasting.client;
|
||||
|
||||
import at.petrak.hexcasting.api.client.ScryingLensOverlayRegistry;
|
||||
import at.petrak.hexcasting.api.player.HexPlayerDataHelper;
|
||||
import at.petrak.hexcasting.api.player.Sentinel;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.xplat.IXplatAbstractions;
|
||||
|
@ -152,8 +151,9 @@ public class HexAdditionalRenderers {
|
|||
|
||||
LocalPlayer player = mc.player;
|
||||
ClientLevel level = mc.level;
|
||||
if (player == null || level == null)
|
||||
if (player == null || level == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean foundLens = false;
|
||||
InteractionHand lensHand = null;
|
||||
|
@ -220,8 +220,9 @@ public class HexAdditionalRenderers {
|
|||
mc.font.drawShadow(ps, actualLine, tx, ty, 0xffffffff);
|
||||
ps.translate(0, mc.font.lineHeight, 0);
|
||||
}
|
||||
if (text.isEmpty())
|
||||
if (text.isEmpty()) {
|
||||
ps.translate(0, mc.font.lineHeight, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ps.popPose();
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
package at.petrak.hexcasting.common.blocks.akashic;
|
||||
|
||||
import at.petrak.hexcasting.annotations.SoftImplement;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.SlabBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BlockAkashicSlab extends SlabBlock {
|
||||
public BlockAkashicSlab(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
@SoftImplement("forge")
|
||||
public boolean isFlammable(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SoftImplement("forge")
|
||||
public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return 20;
|
||||
}
|
||||
|
||||
@SoftImplement("forge")
|
||||
public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return 5;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.blocks.akashic;
|
||||
package at.petrak.hexcasting.common.blocks.decoration;
|
||||
|
||||
import at.petrak.hexcasting.annotations.SoftImplement;
|
||||
import net.minecraft.core.BlockPos;
|
|
@ -1,7 +1,6 @@
|
|||
package at.petrak.hexcasting.common.blocks.akashic;
|
||||
package at.petrak.hexcasting.common.blocks.decoration;
|
||||
|
||||
import at.petrak.hexcasting.annotations.SoftImplement;
|
||||
import at.petrak.hexcasting.common.blocks.decoration.BlockAxis;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
|
@ -1,30 +0,0 @@
|
|||
package at.petrak.hexcasting.common.blocks.akashic;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.StairBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BlockAkashicStairs extends StairBlock {
|
||||
public BlockAkashicStairs(Supplier<BlockState> state, Properties properties) {
|
||||
super(state, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlammable(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {
|
||||
return 5;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ package at.petrak.hexcasting.interop.patchouli;
|
|||
|
||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.interop.utils.utils.PatternDrawingUtil;
|
||||
import at.petrak.hexcasting.interop.utils.utils.PatternEntry;
|
||||
import at.petrak.hexcasting.interop.utils.PatternDrawingUtil;
|
||||
import at.petrak.hexcasting.interop.utils.PatternEntry;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
@ -39,7 +39,8 @@ abstract public class AbstractPatternComponent implements ICustomComponent {
|
|||
|
||||
@Override
|
||||
public void render(PoseStack poseStack, IComponentRenderContext ctx, float partialTicks, int mouseX, int mouseY) {
|
||||
PatternDrawingUtil.drawPattern(poseStack, this.x, this.y, this.patterns, this.pathfinderDots, this.showStrokeOrder(), ctx.getTicksInBook(),
|
||||
PatternDrawingUtil.drawPattern(poseStack, this.x, this.y, this.patterns, this.pathfinderDots,
|
||||
this.showStrokeOrder(), ctx.getTicksInBook(),
|
||||
0xff_d2c8c8, 0xc8_aba2a2, 0xc8_322b33, 0x80_d1cccc);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
package at.petrak.hexcasting.interop.utils;
|
||||
|
||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public final class PatternDrawingUtil {
|
||||
public static void drawPattern(PoseStack poseStack, int x, int y, List<PatternEntry> patterns, List<Vec2> dots,
|
||||
boolean strokeOrder, long animTicks, int outer, int innerLight, int innerDark, int dotColor) {
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(x, y, 1);
|
||||
var mat = poseStack.last().pose();
|
||||
var prevShader = RenderSystem.getShader();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
// RenderSystem.disableDepthTest();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// mark center
|
||||
// RenderLib.drawSpot(mat, Vec2.ZERO, 0f, 0f, 0f, 1f);
|
||||
|
||||
for (var pat : patterns) {
|
||||
RenderLib.drawLineSeq(mat, pat.zappyPoints(), 5f, 0, outer, outer, null);
|
||||
RenderLib.drawLineSeq(mat, pat.zappyPoints(), 2f, 0,
|
||||
strokeOrder ? innerDark : innerLight,
|
||||
innerLight,
|
||||
strokeOrder ? animTicks / 20f : null);
|
||||
|
||||
if (strokeOrder) {
|
||||
RenderLib.drawSpot(mat, pat.zappyPoints().get(0), 2.5f, 1f, 0.1f, 0.15f, 0.6f);
|
||||
}
|
||||
}
|
||||
|
||||
float dotR = FastColor.ARGB32.red(dotColor) / 255f;
|
||||
float dotG = FastColor.ARGB32.green(dotColor) / 255f;
|
||||
float dotB = FastColor.ARGB32.blue(dotColor) / 255f;
|
||||
float dotA = FastColor.ARGB32.alpha(dotColor) / 255f;
|
||||
|
||||
for (var dot : dots) {
|
||||
RenderLib.drawSpot(mat, dot, 1.5f, dotR, dotG, dotB, dotA);
|
||||
}
|
||||
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShader(() -> prevShader);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
public static PatternRenderingData loadPatterns(List<Pair<HexPattern, HexCoord>> patterns) {
|
||||
var patternEntries = new ArrayList<PatternEntry>(patterns.size());
|
||||
|
||||
var fakeScale = 1;
|
||||
var seenFakePoints = new ArrayList<Vec2>();
|
||||
var seenCoords = new HashSet<HexCoord>();
|
||||
for (var pair : patterns) {
|
||||
var pattern = pair.getFirst();
|
||||
var origin = pair.getSecond();
|
||||
for (var pos : pattern.positions(origin)) {
|
||||
var px = HexUtils.coordToPx(pos, fakeScale, Vec2.ZERO);
|
||||
seenFakePoints.add(px);
|
||||
}
|
||||
|
||||
// And while we're looping add the (COORD ONLY) things internally
|
||||
patternEntries.add(new PatternEntry(pattern, origin, new ArrayList<>()));
|
||||
seenCoords.addAll(pattern.positions(origin));
|
||||
}
|
||||
var fakeCom = HexUtils.FindCenter(seenFakePoints);
|
||||
|
||||
var maxDx = -1f;
|
||||
var maxDy = -1f;
|
||||
for (var dot : seenFakePoints) {
|
||||
var dx = Mth.abs(dot.x - fakeCom.x);
|
||||
if (dx > maxDx) {
|
||||
maxDx = dx;
|
||||
}
|
||||
var dy = Mth.abs(dot.y - fakeCom.y);
|
||||
if (dy > maxDy) {
|
||||
maxDy = dy;
|
||||
}
|
||||
}
|
||||
var hexSize = Math.min(12, Math.min(120 / 2.5f / maxDx, 70 / 2.5f / maxDy));
|
||||
|
||||
var seenRealPoints = new ArrayList<Vec2>();
|
||||
for (var pat : patternEntries) {
|
||||
for (var pos : pat.pattern().positions(pat.origin())) {
|
||||
var px = HexUtils.coordToPx(pos, hexSize, Vec2.ZERO);
|
||||
seenRealPoints.add(px);
|
||||
}
|
||||
}
|
||||
var realCom = HexUtils.FindCenter(seenRealPoints);
|
||||
|
||||
// and NOW for real!
|
||||
for (var pat : patternEntries) {
|
||||
var localOrigin = HexUtils.coordToPx(pat.origin(), hexSize, realCom.negated());
|
||||
var points = pat.pattern().toLines(hexSize, localOrigin);
|
||||
pat.zappyPoints().addAll(RenderLib.makeZappy(points, 10f, 0.8f, 0f));
|
||||
}
|
||||
|
||||
var pathfinderDots = seenCoords.stream()
|
||||
.map(coord -> HexUtils.coordToPx(coord, hexSize, realCom.negated())).toList();
|
||||
|
||||
return new PatternRenderingData(patternEntries, pathfinderDots, hexSize);
|
||||
}
|
||||
|
||||
public record PatternRenderingData(List<PatternEntry> patterns, List<Vec2> pathfinderDots, float hexSize) {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
|
@ -7,5 +7,5 @@ import net.minecraft.world.phys.Vec2;
|
|||
import java.util.List;
|
||||
|
||||
public record PatternEntry(HexPattern pattern, HexCoord origin, List<Vec2> zappyPoints) {
|
||||
// NO-OP
|
||||
// NO-OP
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
package at.petrak.hexcasting.interop.utils.utils;
|
||||
|
||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public final class PatternDrawingUtil {
|
||||
public static void drawPattern(PoseStack poseStack, int x, int y, List<PatternEntry> patterns, List<Vec2> dots, boolean strokeOrder, long animTicks, int outer, int innerLight, int innerDark, int dotColor) {
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(x, y, 1);
|
||||
var mat = poseStack.last().pose();
|
||||
var prevShader = RenderSystem.getShader();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
// RenderSystem.disableDepthTest();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// mark center
|
||||
// RenderLib.drawSpot(mat, Vec2.ZERO, 0f, 0f, 0f, 1f);
|
||||
|
||||
for (var pat : patterns) {
|
||||
RenderLib.drawLineSeq(mat, pat.zappyPoints(), 5f, 0, outer, outer, null);
|
||||
RenderLib.drawLineSeq(mat, pat.zappyPoints(), 2f, 0,
|
||||
strokeOrder ? innerDark : innerLight,
|
||||
innerLight,
|
||||
strokeOrder ? animTicks / 20f : null);
|
||||
|
||||
if (strokeOrder) {
|
||||
RenderLib.drawSpot(mat, pat.zappyPoints().get(0), 2.5f, 1f, 0.1f, 0.15f, 0.6f);
|
||||
}
|
||||
}
|
||||
|
||||
float dotR = FastColor.ARGB32.red(dotColor) / 255f;
|
||||
float dotG = FastColor.ARGB32.green(dotColor) / 255f;
|
||||
float dotB = FastColor.ARGB32.blue(dotColor) / 255f;
|
||||
float dotA = FastColor.ARGB32.alpha(dotColor) / 255f;
|
||||
|
||||
for (var dot : dots) {
|
||||
RenderLib.drawSpot(mat, dot, 1.5f, dotR, dotG, dotB, dotA);
|
||||
}
|
||||
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShader(() -> prevShader);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
public static PatternRenderingData loadPatterns(List<Pair<HexPattern, HexCoord>> patterns) {
|
||||
var patternEntries = new ArrayList<PatternEntry>(patterns.size());
|
||||
|
||||
var fakeScale = 1;
|
||||
var seenFakePoints = new ArrayList<Vec2>();
|
||||
var seenCoords = new HashSet<HexCoord>();
|
||||
for (var pair : patterns) {
|
||||
var pattern = pair.getFirst();
|
||||
var origin = pair.getSecond();
|
||||
for (var pos : pattern.positions(origin)) {
|
||||
var px = HexUtils.coordToPx(pos, fakeScale, Vec2.ZERO);
|
||||
seenFakePoints.add(px);
|
||||
}
|
||||
|
||||
// And while we're looping add the (COORD ONLY) things internally
|
||||
patternEntries.add(new PatternEntry(pattern, origin, new ArrayList<>()));
|
||||
seenCoords.addAll(pattern.positions(origin));
|
||||
}
|
||||
var fakeCom = HexUtils.FindCenter(seenFakePoints);
|
||||
|
||||
var maxDx = -1f;
|
||||
var maxDy = -1f;
|
||||
for (var dot : seenFakePoints) {
|
||||
var dx = Mth.abs(dot.x - fakeCom.x);
|
||||
if (dx > maxDx) {
|
||||
maxDx = dx;
|
||||
}
|
||||
var dy = Mth.abs(dot.y - fakeCom.y);
|
||||
if (dy > maxDy) {
|
||||
maxDy = dy;
|
||||
}
|
||||
}
|
||||
var hexSize = Math.min(12, Math.min(120 / 2.5f / maxDx, 70 / 2.5f / maxDy));
|
||||
|
||||
var seenRealPoints = new ArrayList<Vec2>();
|
||||
for (var pat : patternEntries) {
|
||||
for (var pos : pat.pattern().positions(pat.origin())) {
|
||||
var px = HexUtils.coordToPx(pos, hexSize, Vec2.ZERO);
|
||||
seenRealPoints.add(px);
|
||||
}
|
||||
}
|
||||
var realCom = HexUtils.FindCenter(seenRealPoints);
|
||||
|
||||
// and NOW for real!
|
||||
for (var pat : patternEntries) {
|
||||
var localOrigin = HexUtils.coordToPx(pat.origin(), hexSize, realCom.negated());
|
||||
var points = pat.pattern().toLines(hexSize, localOrigin);
|
||||
pat.zappyPoints().addAll(RenderLib.makeZappy(points, 10f, 0.8f, 0f));
|
||||
}
|
||||
|
||||
var pathfinderDots = seenCoords.stream()
|
||||
.map(coord -> HexUtils.coordToPx(coord, hexSize, realCom.negated())).toList();
|
||||
|
||||
return new PatternRenderingData(patternEntries, pathfinderDots, hexSize);
|
||||
}
|
||||
|
||||
public record PatternRenderingData(List<PatternEntry> patterns, List<Vec2> pathfinderDots, float hexSize) {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package at.petrak.hexcasting.interop.utils.utils;
|
||||
|
||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record PatternEntry(HexPattern pattern, HexCoord origin, List<Vec2> zappyPoints) {
|
||||
// NO-OP
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package at.petrak.hexcasting.mixin;
|
||||
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping;
|
||||
import net.minecraft.world.entity.raid.Raider;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
// Prevents the witch from joining a raid
|
||||
@Mixin(Raider.class)
|
||||
public class MixinRaider {
|
||||
@Redirect(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/raid/Raider;isAlive()Z"))
|
||||
private boolean isAliveForAiPurposes(Raider instance) {
|
||||
var self = (Raider) (Object) this;
|
||||
return self.isAlive() && !Brainsweeping.isBrainswept(self);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package at.petrak.hexcasting.mixin;
|
||||
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping;
|
||||
import net.minecraft.world.entity.monster.Witch;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
// Prevents the witch from drinking potions
|
||||
@Mixin(Witch.class)
|
||||
public class MixinWitch {
|
||||
@Redirect(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/Witch;isAlive()Z"))
|
||||
private boolean isAliveForAiPurposes(Witch instance) {
|
||||
var self = (Witch) (Object) this;
|
||||
return self.isAlive() && !Brainsweeping.isBrainswept(self);
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import at.petrak.hexcasting.common.blocks.behavior.HexStrippables
|
|||
import at.petrak.hexcasting.common.casting.RegisterPatterns
|
||||
import at.petrak.hexcasting.common.command.PatternResLocArgument
|
||||
import at.petrak.hexcasting.common.entities.HexEntities
|
||||
import at.petrak.hexcasting.common.items.ItemJewelerHammer
|
||||
import at.petrak.hexcasting.common.lib.*
|
||||
import at.petrak.hexcasting.common.misc.Brainsweeping
|
||||
import at.petrak.hexcasting.common.misc.PlayerPositionRecorder
|
||||
|
@ -16,12 +17,14 @@ import at.petrak.hexcasting.fabric.network.FabricPacketHandler
|
|||
import net.fabricmc.api.ModInitializer
|
||||
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback
|
||||
import net.fabricmc.fabric.api.event.player.UseEntityCallback
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry
|
||||
import net.minecraft.commands.synchronization.ArgumentTypes
|
||||
import net.minecraft.commands.synchronization.EmptyArgumentSerializer
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.InteractionResult
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
object FabricHexInitializer : ModInitializer {
|
||||
|
@ -47,6 +50,16 @@ object FabricHexInitializer : ModInitializer {
|
|||
fun initListeners() {
|
||||
UseEntityCallback.EVENT.register(Brainsweeping::tradeWithVillager)
|
||||
VillagerConversionCallback.EVENT.register(Brainsweeping::copyBrainsweepFromVillager)
|
||||
AttackBlockCallback.EVENT.register { player, world, _, pos, _ ->
|
||||
// SUCCESS cancels further processing and, on the client, sends a packet to the server.
|
||||
// PASS falls back to further processing.
|
||||
// FAIL cancels further processing and does not send a packet to the server.
|
||||
if (ItemJewelerHammer.shouldFailToBreak(player, world.getBlockState(pos), pos)) {
|
||||
InteractionResult.SUCCESS // "success"
|
||||
} else {
|
||||
InteractionResult.PASS
|
||||
}
|
||||
}
|
||||
|
||||
ServerTickEvents.END_WORLD_TICK.register(PlayerPositionRecorder::updateAllPlayers)
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators
|
||||
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpReadable : ConstManaOperator {
|
||||
override val argc = 0
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val (handStack) = ctx.getHeldItemToOperateOn {
|
||||
HexCapabilities.getCapability(it, HexCapabilities.DATUM).isPresent
|
||||
}
|
||||
|
||||
val datumHolder = HexCapabilities.getCapability(handStack, HexCapabilities.DATUM)
|
||||
if (!datumHolder.isPresent)
|
||||
return spellListOf(0.0)
|
||||
|
||||
if (datumHolder.get().readDatum(ctx.world) == null && datumHolder.get().emptyDatum() == null)
|
||||
return spellListOf(0.0)
|
||||
|
||||
return spellListOf(1.0)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators
|
||||
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
|
||||
object OpTheCoolerReadable : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(
|
||||
args: List<SpellDatum<*>>,
|
||||
ctx: CastingContext
|
||||
): List<SpellDatum<*>> {
|
||||
val target = args.getChecked<ItemEntity>(0)
|
||||
ctx.assertEntityInRange(target)
|
||||
|
||||
val stack = target.item
|
||||
val datumHolder = HexCapabilities.getCapability(stack, HexCapabilities.DATUM)
|
||||
|
||||
if (!datumHolder.isPresent)
|
||||
return spellListOf(0.0)
|
||||
|
||||
if (datumHolder.get().readDatum(ctx.world) == null && datumHolder.get().emptyDatum() == null)
|
||||
return spellListOf(0.0)
|
||||
|
||||
return spellListOf(1.0)
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators
|
||||
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapOthersName
|
||||
|
||||
object OpWritable : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val datum = args[0]
|
||||
|
||||
val (handStack) = ctx.getHeldItemToOperateOn {
|
||||
val datumHolder = HexCapabilities.getCapability(it, HexCapabilities.DATUM)
|
||||
|
||||
datumHolder.isPresent && datumHolder.get().writeDatum(datum, true)
|
||||
}
|
||||
|
||||
val datumHolder = HexCapabilities.getCapability(handStack, HexCapabilities.DATUM)
|
||||
if (!datumHolder.isPresent)
|
||||
return spellListOf(0.0)
|
||||
|
||||
if (!datumHolder.get().writeDatum(datum, true))
|
||||
return spellListOf(0.0)
|
||||
|
||||
val trueName = MishapOthersName.getTrueNameFromDatum(datum, ctx.caster)
|
||||
if (trueName != null)
|
||||
return spellListOf(0.0)
|
||||
|
||||
return spellListOf(1.0)
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.lists
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpCons : ConstManaOperator {
|
||||
override val argc = 2
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val bottom = args.getChecked<SpellList>(0)
|
||||
val top = args[1]
|
||||
return spellListOf(SpellList.LPair(top, bottom))
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.lists
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpModifyInPlace : ConstManaOperator {
|
||||
override val argc = 3
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val list = args.getChecked<SpellList>(0)
|
||||
val index = args.getChecked<Double>(1).roundToInt()
|
||||
val iota = args[2]
|
||||
return spellListOf(list.modifyAt(index) { SpellList.LPair(iota, it.cdr) })
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.lists
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import net.minecraft.util.Mth
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpSlice : ConstManaOperator {
|
||||
override val argc = 3
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val list = args.getChecked<SpellList>(0).toList()
|
||||
val index1 = Mth.clamp(args.getChecked<Double>(1).roundToInt(), 0, list.size)
|
||||
val index2 = Mth.clamp(args.getChecked<Double>(2).roundToInt(), 0, list.size)
|
||||
|
||||
if (index1 == index2)
|
||||
return spellListOf(listOf<SpellDatum<*>>())
|
||||
|
||||
return spellListOf(list.subList(min(index1, index2), max(index1, index2)))
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.lists
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpUnCons : ConstManaOperator {
|
||||
override val argc = 1
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val list = args.getChecked<SpellList>(0)
|
||||
if (list.nonEmpty) {
|
||||
return spellListOf(list.cdr, list.car)
|
||||
}
|
||||
throw ArrayIndexOutOfBoundsException()
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.local
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpPeekLocal : Operator {
|
||||
override fun operate(
|
||||
stack: MutableList<SpellDatum<*>>,
|
||||
local: SpellDatum<*>,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
stack.add(local)
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.local
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.mishaps.MishapNotEnoughArgs
|
||||
|
||||
object OpPushLocal : Operator {
|
||||
override fun operate(
|
||||
stack: MutableList<SpellDatum<*>>,
|
||||
local: SpellDatum<*>,
|
||||
ctx: CastingContext
|
||||
): OperationResult {
|
||||
if (stack.isEmpty())
|
||||
throw MishapNotEnoughArgs(1, 0)
|
||||
val newLocal = stack.removeLast()
|
||||
return OperationResult(stack, newLocal, listOf())
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.bit
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.operators.math.MathOpUtils
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpAnd : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val firstParam = MathOpUtils.GetNumOrList(args[0], 0)
|
||||
|
||||
if (firstParam.right().isPresent) {
|
||||
val list1 = firstParam.right().get()
|
||||
val list2 = args.getChecked<SpellList>(1)
|
||||
return spellListOf(list1.filter { it in list2 })
|
||||
}
|
||||
|
||||
val num1 = firstParam.left().get().roundToInt()
|
||||
val num2 = args.getChecked<Double>(1).roundToInt()
|
||||
return spellListOf((num1 and num2).toDouble())
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.bit
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpNot : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val num = args.getChecked<Double>(0).roundToInt()
|
||||
return spellListOf((num.inv()).toDouble())
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.bit
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.operators.math.MathOpUtils
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpOr : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val firstParam = MathOpUtils.GetNumOrList(args[0], 0)
|
||||
|
||||
if (firstParam.right().isPresent) {
|
||||
val list1 = firstParam.right().get()
|
||||
val list2 = args.getChecked<SpellList>(1)
|
||||
return spellListOf(list1 + list2.filter { it !in list1 })
|
||||
}
|
||||
|
||||
val num1 = firstParam.left().get().roundToInt()
|
||||
val num2 = args.getChecked<Double>(1).roundToInt()
|
||||
return spellListOf((num1 or num2).toDouble())
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.bit
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpToSet : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val payload = args.getChecked<SpellList>(0)
|
||||
return spellListOf(payload.toSet().toList())
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.bit
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.operators.math.MathOpUtils
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object OpXor : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val firstParam = MathOpUtils.GetNumOrList(args[0], 0)
|
||||
|
||||
if (firstParam.right().isPresent) {
|
||||
val list1 = firstParam.right().get()
|
||||
val list2 = args.getChecked<SpellList>(1)
|
||||
return spellListOf(list1.filter { it !in list2 } + list2.filter { it !in list1 })
|
||||
}
|
||||
|
||||
val num1 = firstParam.left().get().roundToInt()
|
||||
val num2 = args.getChecked<Double>(1).roundToInt()
|
||||
return spellListOf((num1 xor num2).toDouble())
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.logic
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpBoolAnd : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
return listOf(
|
||||
if (args[0].payload == Widget.NULL)
|
||||
SpellDatum.make(Widget.NULL)
|
||||
else
|
||||
args[1]
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.logic
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpBoolIdentityKindOf : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
return spellListOf(
|
||||
when (val payload = args[0].payload) {
|
||||
Widget.NULL -> 0.0
|
||||
0.0, Vec3.ZERO -> Widget.NULL
|
||||
is SpellList -> if (payload.nonEmpty) payload else Widget.NULL
|
||||
else -> payload
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.logic
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellList
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpBoolNot : ConstManaOperator {
|
||||
override val argc = 1
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
val payload = args[0].payload
|
||||
val falsy = payload == Widget.NULL || payload == 0.0 || payload == Vec3.ZERO || (payload is SpellList && !payload.nonEmpty)
|
||||
return spellListOf(if (falsy) 1.0 else 0.0)
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.logic
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
|
||||
object OpBoolOr : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
return listOf(
|
||||
if (args[0].payload == Widget.NULL)
|
||||
args[1]
|
||||
else
|
||||
args[0]
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.math.logic
|
||||
|
||||
import at.petrak.hexcasting.api.spell.ConstManaOperator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
import at.petrak.hexcasting.api.spell.Widget
|
||||
|
||||
object OpBoolXor : ConstManaOperator {
|
||||
override val argc = 2
|
||||
|
||||
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
|
||||
return listOf(
|
||||
if (args[0].payload != Widget.NULL && args[1].payload == Widget.NULL)
|
||||
args[0]
|
||||
else if (args[0].payload == Widget.NULL && args[1].payload != Widget.NULL)
|
||||
args[1]
|
||||
else
|
||||
SpellDatum.make(Widget.NULL)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package at.petrak.hexcasting.common.casting.operators.stack
|
||||
|
||||
import at.petrak.hexcasting.api.spell.OperationResult
|
||||
import at.petrak.hexcasting.api.spell.Operator
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.casting.CastingContext
|
||||
|
||||
object OpStackSize : Operator {
|
||||
override fun operate(stack: MutableList<SpellDatum<*>>, local: SpellDatum<*>, ctx: CastingContext): OperationResult {
|
||||
stack.add(SpellDatum.make(stack.size.toDouble()))
|
||||
return OperationResult(stack, local, listOf())
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.interop.jei;
|
||||
package at.petrak.hexcasting.forge.interop.jei;
|
||||
|
||||
import at.petrak.hexcasting.client.ClientTickCounter;
|
||||
import at.petrak.hexcasting.common.recipe.BrainsweepRecipe;
|
||||
|
@ -39,132 +39,138 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static at.petrak.hexcasting.common.lib.RegisterHelper.prefix;
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
public class BrainsweepRecipeCategory implements IRecipeCategory<BrainsweepRecipe> {
|
||||
public static final ResourceLocation UID = prefix("brainsweep");
|
||||
public static final ResourceLocation UID = modLoc("brainsweep");
|
||||
|
||||
private final IDrawableStatic background;
|
||||
private final IDrawable icon;
|
||||
private final Component localizedName;
|
||||
private final IDrawableStatic background;
|
||||
private final IDrawable icon;
|
||||
private final Component localizedName;
|
||||
|
||||
public BrainsweepRecipeCategory(IGuiHelper guiHelper) {
|
||||
ResourceLocation location = prefix("textures/gui/brainsweep_jei.png");
|
||||
background = guiHelper.drawableBuilder(location, 0, 0, 118, 86).setTextureSize(128, 128).build();
|
||||
var brainsweep = prefix("brainsweep");
|
||||
localizedName = new TranslatableComponent("hexcasting.spell." + brainsweep);
|
||||
icon = new PatternDrawable(brainsweep, 16, 16);
|
||||
}
|
||||
public BrainsweepRecipeCategory(IGuiHelper guiHelper) {
|
||||
ResourceLocation location = modLoc("textures/gui/brainsweep_jei.png");
|
||||
background = guiHelper.drawableBuilder(location, 0, 0, 118, 86).setTextureSize(128, 128).build();
|
||||
var brainsweep = modLoc("brainsweep");
|
||||
localizedName = new TranslatableComponent("hexcasting.spell." + brainsweep);
|
||||
icon = new PatternDrawable(brainsweep, 16, 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public @NotNull Component getTitle() {
|
||||
return localizedName;
|
||||
}
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public @NotNull Component getTitle() {
|
||||
return localizedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IDrawable getBackground() {
|
||||
return background;
|
||||
}
|
||||
@Override
|
||||
public @NotNull IDrawable getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IDrawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
@Override
|
||||
public @NotNull IDrawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Component> getTooltipStrings(@NotNull BrainsweepRecipe recipe, @NotNull IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
|
||||
if (37 <= mouseX && mouseX <= 37 + 26 && 19 <= mouseY && mouseY <= 19 + 48) {
|
||||
List<Component> tooltip = new ArrayList<>(3);
|
||||
var profession = recipe.villagerIn().profession();
|
||||
if (profession == null) {
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.profession.any"));
|
||||
} else {
|
||||
var professionKey = "entity.minecraft.villager." + profession.getPath();
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.profession",
|
||||
new TranslatableComponent(professionKey)));
|
||||
}
|
||||
var biome = recipe.villagerIn().biome();
|
||||
if (biome == null) {
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.biome.any"));
|
||||
} else {
|
||||
var biomeKey = "biome.minecraft." + biome.getPath();
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.biome",
|
||||
new TranslatableComponent(biomeKey)));
|
||||
}
|
||||
@Override
|
||||
public @NotNull List<Component> getTooltipStrings(@NotNull BrainsweepRecipe recipe,
|
||||
@NotNull IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
|
||||
if (37 <= mouseX && mouseX <= 37 + 26 && 19 <= mouseY && mouseY <= 19 + 48) {
|
||||
List<Component> tooltip = new ArrayList<>(3);
|
||||
var profession = recipe.villagerIn().profession();
|
||||
if (profession == null) {
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.profession.any"));
|
||||
} else {
|
||||
var professionKey = "entity.minecraft.villager." + profession.getPath();
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.profession",
|
||||
new TranslatableComponent(professionKey)));
|
||||
}
|
||||
var biome = recipe.villagerIn().biome();
|
||||
if (biome == null) {
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.biome.any"));
|
||||
} else {
|
||||
var biomeKey = "biome.minecraft." + biome.getPath();
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.biome",
|
||||
new TranslatableComponent(biomeKey)));
|
||||
}
|
||||
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.min_level",
|
||||
recipe.villagerIn().minLevel()));
|
||||
return tooltip;
|
||||
}
|
||||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.brainsweep.min_level",
|
||||
recipe.villagerIn().minLevel()));
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private Villager villager;
|
||||
private Villager villager;
|
||||
|
||||
@Override
|
||||
public void draw(@NotNull BrainsweepRecipe recipe, @NotNull IRecipeSlotsView recipeSlotsView, @NotNull PoseStack stack, double mouseX, double mouseY) {
|
||||
ClientLevel level = Minecraft.getInstance().level;
|
||||
if (level != null) {
|
||||
VillagerProfession profession = Objects.requireNonNullElse(ForgeRegistries.PROFESSIONS.getValue(recipe.villagerIn().profession()),
|
||||
VillagerProfession.TOOLSMITH);
|
||||
VillagerType biome = Objects.requireNonNullElse(Registry.VILLAGER_TYPE.get(recipe.villagerIn().biome()),
|
||||
VillagerType.PLAINS);
|
||||
int minLevel = recipe.villagerIn().minLevel();
|
||||
if (villager == null)
|
||||
villager = new Villager(EntityType.VILLAGER, level);
|
||||
@Override
|
||||
public void draw(@NotNull BrainsweepRecipe recipe, @NotNull IRecipeSlotsView recipeSlotsView,
|
||||
@NotNull PoseStack stack, double mouseX, double mouseY) {
|
||||
ClientLevel level = Minecraft.getInstance().level;
|
||||
if (level != null) {
|
||||
VillagerProfession profession = Objects.requireNonNullElse(
|
||||
ForgeRegistries.PROFESSIONS.getValue(recipe.villagerIn().profession()),
|
||||
VillagerProfession.TOOLSMITH);
|
||||
VillagerType biome = Objects.requireNonNullElse(Registry.VILLAGER_TYPE.get(recipe.villagerIn().biome()),
|
||||
VillagerType.PLAINS);
|
||||
int minLevel = recipe.villagerIn().minLevel();
|
||||
if (villager == null) {
|
||||
villager = new Villager(EntityType.VILLAGER, level);
|
||||
}
|
||||
|
||||
villager.setVillagerData(villager.getVillagerData()
|
||||
.setProfession(profession)
|
||||
.setType(biome)
|
||||
.setLevel(minLevel));
|
||||
villager.setVillagerData(villager.getVillagerData()
|
||||
.setProfession(profession)
|
||||
.setType(biome)
|
||||
.setLevel(minLevel));
|
||||
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
renderEntity(stack, villager, level, 50, 62.5f, ClientTickCounter.total, 20, 0);
|
||||
}
|
||||
}
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
renderEntity(stack, villager, level, 50, 62.5f, ClientTickCounter.total, 20, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderEntity(PoseStack ms, Entity entity, Level world, float x, float y, float rotation, float renderScale, float offset) {
|
||||
entity.level = world;
|
||||
ms.pushPose();
|
||||
ms.translate(x, y, 50.0D);
|
||||
ms.scale(renderScale, renderScale, renderScale);
|
||||
ms.translate(0.0D, offset, 0.0D);
|
||||
ms.mulPose(Vector3f.ZP.rotationDegrees(180.0F));
|
||||
ms.mulPose(Vector3f.YP.rotationDegrees(rotation));
|
||||
EntityRenderDispatcher erd = Minecraft.getInstance().getEntityRenderDispatcher();
|
||||
MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource();
|
||||
erd.setRenderShadow(false);
|
||||
erd.render(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F, ms, immediate, 15728880);
|
||||
erd.setRenderShadow(true);
|
||||
immediate.endBatch();
|
||||
ms.popPose();
|
||||
}
|
||||
private static void renderEntity(PoseStack ms, Entity entity, Level world, float x, float y, float rotation,
|
||||
float renderScale, float offset) {
|
||||
entity.level = world;
|
||||
ms.pushPose();
|
||||
ms.translate(x, y, 50.0D);
|
||||
ms.scale(renderScale, renderScale, renderScale);
|
||||
ms.translate(0.0D, offset, 0.0D);
|
||||
ms.mulPose(Vector3f.ZP.rotationDegrees(180.0F));
|
||||
ms.mulPose(Vector3f.YP.rotationDegrees(rotation));
|
||||
EntityRenderDispatcher erd = Minecraft.getInstance().getEntityRenderDispatcher();
|
||||
MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource();
|
||||
erd.setRenderShadow(false);
|
||||
erd.render(entity, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F, ms, immediate, 15728880);
|
||||
erd.setRenderShadow(true);
|
||||
immediate.endBatch();
|
||||
ms.popPose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecipe(@NotNull IRecipeLayoutBuilder builder, @NotNull BrainsweepRecipe recipe, @NotNull IFocusGroup focuses) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 12, 35)
|
||||
.addItemStacks(recipe.blockIn().getDisplayedStacks());
|
||||
builder.addSlot(RecipeIngredientRole.OUTPUT, 87, 35)
|
||||
.addItemStack(new ItemStack(recipe.result().getBlock()));
|
||||
}
|
||||
@Override
|
||||
public void setRecipe(@NotNull IRecipeLayoutBuilder builder, @NotNull BrainsweepRecipe recipe,
|
||||
@NotNull IFocusGroup focuses) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 12, 35)
|
||||
.addItemStacks(recipe.blockIn().getDisplayedStacks());
|
||||
builder.addSlot(RecipeIngredientRole.OUTPUT, 87, 35)
|
||||
.addItemStack(new ItemStack(recipe.result().getBlock()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull RecipeType<BrainsweepRecipe> getRecipeType() {
|
||||
return HexJEIPlugin.BRAINSWEEPING;
|
||||
}
|
||||
@Override
|
||||
public @NotNull RecipeType<BrainsweepRecipe> getRecipeType() {
|
||||
return HexJEIPlugin.BRAINSWEEPING;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
public @NotNull ResourceLocation getUid() {
|
||||
return UID;
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
public @NotNull ResourceLocation getUid() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
public @NotNull Class<? extends BrainsweepRecipe> getRecipeClass() {
|
||||
return BrainsweepRecipe.class;
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
public @NotNull Class<? extends BrainsweepRecipe> getRecipeClass() {
|
||||
return BrainsweepRecipe.class;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package at.petrak.hexcasting.interop.jei;
|
||||
package at.petrak.hexcasting.forge.interop.jei;
|
||||
|
||||
import at.petrak.hexcasting.HexMod;
|
||||
import at.petrak.hexcasting.common.items.HexItems;
|
||||
import at.petrak.hexcasting.api.HexAPI;
|
||||
import at.petrak.hexcasting.common.lib.HexItems;
|
||||
import at.petrak.hexcasting.common.recipe.BrainsweepRecipe;
|
||||
import at.petrak.hexcasting.common.recipe.HexRecipeSerializers;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
|
@ -16,45 +16,46 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.level.Level;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static at.petrak.hexcasting.common.lib.RegisterHelper.prefix;
|
||||
import static at.petrak.hexcasting.api.HexAPI.modLoc;
|
||||
|
||||
@JeiPlugin
|
||||
public class HexJEIPlugin implements IModPlugin {
|
||||
private static final ResourceLocation UID = prefix(HexMod.MOD_ID);
|
||||
private static final ResourceLocation UID = modLoc(HexAPI.MOD_ID);
|
||||
|
||||
public static final RecipeType<BrainsweepRecipe> BRAINSWEEPING =
|
||||
RecipeType.create(HexMod.MOD_ID, "brainsweeping", BrainsweepRecipe.class);
|
||||
public static final RecipeType<BrainsweepRecipe> BRAINSWEEPING =
|
||||
RecipeType.create(HexAPI.MOD_ID, "brainsweeping", BrainsweepRecipe.class);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ResourceLocation getPluginUid() {
|
||||
return UID;
|
||||
}
|
||||
@NotNull
|
||||
@Override
|
||||
public ResourceLocation getPluginUid() {
|
||||
return UID;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
registration.addRecipeCategories(new BrainsweepRecipeCategory(registration.getJeiHelpers().getGuiHelper()));
|
||||
}
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
registration.addRecipeCategories(new BrainsweepRecipeCategory(registration.getJeiHelpers().getGuiHelper()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(@NotNull IRecipeRegistration registration) {
|
||||
Level level = Minecraft.getInstance().level;
|
||||
if (level != null) {
|
||||
registration.addRecipes(BRAINSWEEPING, level.getRecipeManager().getAllRecipesFor(HexRecipeSerializers.BRAINSWEEP_TYPE));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void registerRecipes(@NotNull IRecipeRegistration registration) {
|
||||
Level level = Minecraft.getInstance().level;
|
||||
if (level != null) {
|
||||
registration.addRecipes(BRAINSWEEPING,
|
||||
level.getRecipeManager().getAllRecipesFor(HexRecipeSerializers.BRAINSWEEP_TYPE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_OAK::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_SPRUCE::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_BIRCH::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_JUNGLE::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_ACACIA::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_DARK_OAK::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_CRIMSON::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_WARPED::get), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_AKASHIC::get), BRAINSWEEPING);
|
||||
}
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_OAK), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_SPRUCE), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_BIRCH), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_JUNGLE), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_ACACIA), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_DARK_OAK), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_CRIMSON), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_WARPED), BRAINSWEEPING);
|
||||
registration.addRecipeCatalyst(new ItemStack(HexItems.WAND_AKASHIC), BRAINSWEEPING);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.interop.jei;
|
||||
package at.petrak.hexcasting.forge.interop.jei;
|
||||
|
||||
import at.petrak.hexcasting.api.PatternRegistry;
|
||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||
|
@ -14,44 +14,44 @@ import java.util.List;
|
|||
|
||||
public class PatternDrawable implements IDrawable {
|
||||
|
||||
private final long startTime = System.currentTimeMillis();
|
||||
private final long startTime = System.currentTimeMillis();
|
||||
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
private final boolean strokeOrder;
|
||||
private final boolean strokeOrder;
|
||||
|
||||
private final List<PatternEntry> patterns;
|
||||
private final List<Vec2> pathfinderDots;
|
||||
private final List<PatternEntry> patterns;
|
||||
private final List<Vec2> pathfinderDots;
|
||||
|
||||
public PatternDrawable(ResourceLocation pattern, int w, int h) {
|
||||
var entry = PatternRegistry.lookupPattern(pattern);
|
||||
this.strokeOrder = !entry.isPerWorld();
|
||||
var data = PatternDrawingUtil.loadPatterns(List.of(new Pair<>(entry.getPrototype(), HexCoord.getOrigin())));
|
||||
this.patterns = data.patterns();
|
||||
this.pathfinderDots = data.pathfinderDots();
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
}
|
||||
public PatternDrawable(ResourceLocation pattern, int w, int h) {
|
||||
var entry = PatternRegistry.lookupPattern(pattern);
|
||||
this.strokeOrder = !entry.isPerWorld();
|
||||
var data = PatternDrawingUtil.loadPatterns(List.of(new Pair<>(entry.getPrototype(), HexCoord.getOrigin())));
|
||||
this.patterns = data.patterns();
|
||||
this.pathfinderDots = data.pathfinderDots();
|
||||
this.width = w;
|
||||
this.height = h;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int xOffset, int yOffset) {
|
||||
long time = (System.currentTimeMillis() - startTime) / 50;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(xOffset - 0.5f + width / 2f, yOffset + height / 2f, 0);
|
||||
poseStack.scale(0.25f, 0.25f, 1);
|
||||
PatternDrawingUtil.drawPattern(poseStack, 0, 0, this.patterns, this.pathfinderDots, this.strokeOrder, time,
|
||||
0xff_333030, 0xff_191818, 0xc8_0c0a0c, 0x80_666363);
|
||||
poseStack.popPose();
|
||||
}
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int xOffset, int yOffset) {
|
||||
long time = (System.currentTimeMillis() - startTime) / 50;
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(xOffset - 0.5f + width / 2f, yOffset + height / 2f, 0);
|
||||
poseStack.scale(0.25f, 0.25f, 1);
|
||||
PatternDrawingUtil.drawPattern(poseStack, 0, 0, this.patterns, this.pathfinderDots, this.strokeOrder, time,
|
||||
0xff_333030, 0xff_191818, 0xc8_0c0a0c, 0x80_666363);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
package at.petrak.hexcasting.interop.utils;
|
||||
|
||||
import at.petrak.hexcasting.api.spell.math.HexCoord;
|
||||
import at.petrak.hexcasting.api.spell.math.HexPattern;
|
||||
import at.petrak.hexcasting.api.utils.HexUtils;
|
||||
import at.petrak.hexcasting.client.RenderLib;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.util.FastColor;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public final class PatternDrawingUtil {
|
||||
public static void drawPattern(PoseStack poseStack, int x, int y, List<PatternEntry> patterns, List<Vec2> dots, boolean strokeOrder, long animTicks, int outer, int innerLight, int innerDark, int dotColor) {
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(x, y, 1);
|
||||
var mat = poseStack.last().pose();
|
||||
var prevShader = RenderSystem.getShader();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
// RenderSystem.disableDepthTest();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// mark center
|
||||
// RenderLib.drawSpot(mat, Vec2.ZERO, 0f, 0f, 0f, 1f);
|
||||
|
||||
for (var pat : patterns) {
|
||||
RenderLib.drawLineSeq(mat, pat.zappyPoints(), 5f, 0, outer, outer, null);
|
||||
RenderLib.drawLineSeq(mat, pat.zappyPoints(), 2f, 0,
|
||||
strokeOrder ? innerDark : innerLight,
|
||||
innerLight,
|
||||
strokeOrder ? animTicks / 20f : null);
|
||||
|
||||
if (strokeOrder) {
|
||||
RenderLib.drawSpot(mat, pat.zappyPoints().get(0), 2.5f, 1f, 0.1f, 0.15f, 0.6f);
|
||||
}
|
||||
}
|
||||
|
||||
float dotR = FastColor.ARGB32.red(dotColor) / 255f;
|
||||
float dotG = FastColor.ARGB32.green(dotColor) / 255f;
|
||||
float dotB = FastColor.ARGB32.blue(dotColor) / 255f;
|
||||
float dotA = FastColor.ARGB32.alpha(dotColor) / 255f;
|
||||
|
||||
for (var dot : dots) {
|
||||
RenderLib.drawSpot(mat, dot, 1.5f, dotR, dotG, dotB, dotA);
|
||||
}
|
||||
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShader(() -> prevShader);
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
public static PatternRenderingData loadPatterns(List<Pair<HexPattern, HexCoord>> patterns) {
|
||||
var patternEntries = new ArrayList<PatternEntry>(patterns.size());
|
||||
|
||||
var fakeScale = 1;
|
||||
var seenFakePoints = new ArrayList<Vec2>();
|
||||
var seenCoords = new HashSet<HexCoord>();
|
||||
for (var pair : patterns) {
|
||||
var pattern = pair.getFirst();
|
||||
var origin = pair.getSecond();
|
||||
for (var pos : pattern.positions(origin)) {
|
||||
var px = HexUtils.coordToPx(pos, fakeScale, Vec2.ZERO);
|
||||
seenFakePoints.add(px);
|
||||
}
|
||||
|
||||
// And while we're looping add the (COORD ONLY) things internally
|
||||
patternEntries.add(new PatternEntry(pattern, origin, new ArrayList<>()));
|
||||
seenCoords.addAll(pattern.positions(origin));
|
||||
}
|
||||
var fakeCom = HexUtils.FindCenter(seenFakePoints);
|
||||
|
||||
var maxDx = -1f;
|
||||
var maxDy = -1f;
|
||||
for (var dot : seenFakePoints) {
|
||||
var dx = Mth.abs(dot.x - fakeCom.x);
|
||||
if (dx > maxDx) {
|
||||
maxDx = dx;
|
||||
}
|
||||
var dy = Mth.abs(dot.y - fakeCom.y);
|
||||
if (dy > maxDy) {
|
||||
maxDy = dy;
|
||||
}
|
||||
}
|
||||
var hexSize = Math.min(12, Math.min(120 / 2.5f / maxDx, 70 / 2.5f / maxDy));
|
||||
|
||||
var seenRealPoints = new ArrayList<Vec2>();
|
||||
for (var pat : patternEntries) {
|
||||
for (var pos : pat.pattern().positions(pat.origin())) {
|
||||
var px = HexUtils.coordToPx(pos, hexSize, Vec2.ZERO);
|
||||
seenRealPoints.add(px);
|
||||
}
|
||||
}
|
||||
var realCom = HexUtils.FindCenter(seenRealPoints);
|
||||
|
||||
// and NOW for real!
|
||||
for (var pat : patternEntries) {
|
||||
var localOrigin = HexUtils.coordToPx(pat.origin(), hexSize, realCom.negated());
|
||||
var points = pat.pattern().toLines(hexSize, localOrigin);
|
||||
pat.zappyPoints().addAll(RenderLib.makeZappy(points, 10f, 0.8f, 0f));
|
||||
}
|
||||
|
||||
var pathfinderDots = seenCoords.stream()
|
||||
.map(coord -> HexUtils.coordToPx(coord, hexSize, realCom.negated())).toList();
|
||||
|
||||
return new PatternRenderingData(patternEntries, pathfinderDots, hexSize);
|
||||
}
|
||||
|
||||
public record PatternRenderingData(List<PatternEntry> patterns, List<Vec2> pathfinderDots, float hexSize) {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
public class JewelerHammerHandler {
|
||||
@SubscribeEvent
|
||||
public static void jewelerHammerBreakSpeed(PlayerEvent.BreakSpeed evt) {
|
||||
ItemStack stack = evt.getPlayer().getMainHandItem();
|
||||
if (stack.is(HexItems.JEWELER_HAMMER.get())) {
|
||||
if (Block.isShapeFullBlock(evt.getState().getShape(evt.getPlayer().level, evt.getPos()))) {
|
||||
evt.setCanceled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package at.petrak.hexcasting.common.misc;
|
||||
package at.petrak.hexcasting.forge.misc;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
@ -11,31 +11,34 @@ import java.util.Map;
|
|||
import java.util.WeakHashMap;
|
||||
|
||||
public final class PlayerPositionRecorder {
|
||||
private static final Map<Player, Vec3> LAST_SECOND_POSITION_MAP = new WeakHashMap<>();
|
||||
private static final Map<Player, Vec3> LAST_POSITION_MAP = new WeakHashMap<>();
|
||||
private static final Map<Player, Vec3> LAST_SECOND_POSITION_MAP = new WeakHashMap<>();
|
||||
private static final Map<Player, Vec3> LAST_POSITION_MAP = new WeakHashMap<>();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityUpdate(TickEvent.WorldTickEvent evt) {
|
||||
if (evt.phase == TickEvent.Phase.END && evt.world instanceof ServerLevel world) {
|
||||
for (ServerPlayer player : world.players()) {
|
||||
var prev = LAST_POSITION_MAP.get(player);
|
||||
if (prev != null)
|
||||
@SubscribeEvent
|
||||
public static void onEntityUpdate(TickEvent.WorldTickEvent evt) {
|
||||
if (evt.phase == TickEvent.Phase.END && evt.world instanceof ServerLevel world) {
|
||||
for (ServerPlayer player : world.players()) {
|
||||
var prev = LAST_POSITION_MAP.get(player);
|
||||
if (prev != null) {
|
||||
LAST_SECOND_POSITION_MAP.put(player, prev);
|
||||
LAST_POSITION_MAP.put(player, player.position());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LAST_POSITION_MAP.put(player, player.position());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Vec3 getMotion(ServerPlayer player) {
|
||||
Vec3 vec = LAST_POSITION_MAP.get(player);
|
||||
Vec3 prev = LAST_SECOND_POSITION_MAP.get(player);
|
||||
public static Vec3 getMotion(ServerPlayer player) {
|
||||
Vec3 vec = LAST_POSITION_MAP.get(player);
|
||||
Vec3 prev = LAST_SECOND_POSITION_MAP.get(player);
|
||||
|
||||
if (vec == null)
|
||||
if (vec == null) {
|
||||
return Vec3.ZERO;
|
||||
}
|
||||
|
||||
if (prev == null)
|
||||
if (prev == null) {
|
||||
return player.position().subtract(vec);
|
||||
}
|
||||
|
||||
return vec.subtract(prev);
|
||||
}
|
||||
return vec.subtract(prev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
package at.petrak.hexcasting.common.recipe.ingredient;
|
||||
|
||||
import at.petrak.hexcasting.api.cap.DataHolder;
|
||||
import at.petrak.hexcasting.api.cap.HexCapabilities;
|
||||
import at.petrak.hexcasting.api.item.DataHolderItem;
|
||||
import at.petrak.hexcasting.api.spell.DatumType;
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||
import at.petrak.hexcasting.api.spell.Widget;
|
||||
import at.petrak.hexcasting.api.utils.NBTHelper;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraftforge.common.crafting.AbstractIngredient;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.common.crafting.IIngredientSerializer;
|
||||
import net.minecraftforge.common.crafting.NBTIngredient;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class UnsealedIngredient extends AbstractIngredient {
|
||||
private final ItemStack stack;
|
||||
|
||||
protected UnsealedIngredient(ItemStack stack) {
|
||||
super(Arrays.stream(DatumType.values())
|
||||
.filter((it) -> it != DatumType.EMPTY && it != DatumType.OTHER)
|
||||
.map((type) -> {
|
||||
ItemStack newStack = stack.copy();
|
||||
NBTHelper.putString(newStack, DataHolderItem.TAG_OVERRIDE_VISUALLY, SpellDatum.GetTagName(type));
|
||||
return new Ingredient.ItemValue(newStack);
|
||||
}));
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ingredient matching the given stack
|
||||
*/
|
||||
public static UnsealedIngredient of(ItemStack stack) {
|
||||
return new UnsealedIngredient(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@Nullable ItemStack input) {
|
||||
if (input == null)
|
||||
return false;
|
||||
if(this.stack.getItem() == input.getItem() && this.stack.getDamageValue() == input.getDamageValue()) {
|
||||
Optional<DataHolder> holder = HexCapabilities.getCapability(input, HexCapabilities.DATUM);
|
||||
if (holder.isPresent()) {
|
||||
return holder.get().readRawDatum() != null && holder.get().writeDatum(SpellDatum.make(Widget.NULL), true);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimple() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IIngredientSerializer<? extends Ingredient> getSerializer() {
|
||||
return UnsealedIngredient.Serializer.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JsonElement toJson() {
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty("type", Objects.toString(CraftingHelper.getID(NBTIngredient.Serializer.INSTANCE)));
|
||||
json.addProperty("item", Objects.toString(stack.getItem().getRegistryName()));
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
public static class Serializer implements IIngredientSerializer<UnsealedIngredient> {
|
||||
public static final UnsealedIngredient.Serializer INSTANCE = new UnsealedIngredient.Serializer();
|
||||
|
||||
@Override
|
||||
public @NotNull UnsealedIngredient parse(FriendlyByteBuf buffer) {
|
||||
return new UnsealedIngredient(buffer.readItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull UnsealedIngredient parse(@NotNull JsonObject json) {
|
||||
return new UnsealedIngredient(CraftingHelper.getItemStack(json, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buffer, UnsealedIngredient ingredient) {
|
||||
buffer.writeItem(ingredient.stack);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue