ok i think it works this time

This commit is contained in:
gamma-delta 2022-05-19 10:27:02 -05:00
parent d634824ae7
commit cb8b4be953
44 changed files with 354 additions and 1261 deletions

View file

@ -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;
}

View file

@ -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
}
}
}

View file

@ -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)
}

View file

@ -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()
)
}

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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)
}
}

View file

@ -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)
}
}

View file

@ -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)
}
}

View file

@ -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))
}
}

View file

@ -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) })
}
}

View file

@ -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)))
}
}

View file

@ -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()
}
}

View file

@ -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())
}
}

View file

@ -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())
}
}

View file

@ -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())
}
}

View file

@ -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())
}
}

View file

@ -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())
}
}

View file

@ -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())
}
}

View file

@ -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())
}
}

View file

@ -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]
)
}
}

View file

@ -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
}
)
}
}

View file

@ -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)
}
}

View file

@ -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]
)
}
}

View file

@ -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)
)
}
}

View file

@ -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())
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}