From 9adcbabad33b67cc474100af1874a066f782f53d Mon Sep 17 00:00:00 2001 From: gamma-delta <29877714+gamma-delta@users.noreply.github.com> Date: Sun, 20 Mar 2022 23:23:31 -0500 Subject: [PATCH] possibly implement hoppering into impetus. i dont know. --- .../java/at/petrak/hexcasting/HexConfig.java | 19 ++-- .../impetuses/BlockEntityAbstractImpetus.java | 88 ++++++++++++++++++- .../common/casting/CastingContext.kt | 2 +- .../common/casting/CastingHarness.kt | 27 ++++-- .../common/casting/SpellCircleContext.kt | 59 +++++++++++++ 5 files changed, 178 insertions(+), 17 deletions(-) create mode 100644 src/main/java/at/petrak/hexcasting/common/casting/SpellCircleContext.kt diff --git a/src/main/java/at/petrak/hexcasting/HexConfig.java b/src/main/java/at/petrak/hexcasting/HexConfig.java index 7d4ec72c..82a57758 100644 --- a/src/main/java/at/petrak/hexcasting/HexConfig.java +++ b/src/main/java/at/petrak/hexcasting/HexConfig.java @@ -5,13 +5,13 @@ import net.minecraft.world.item.Tiers; import net.minecraftforge.common.ForgeConfigSpec; public class HexConfig { - - public static ForgeConfigSpec.DoubleValue manaToHealthRate; - - public static ForgeConfigSpec.IntValue dustManaAmount; public static ForgeConfigSpec.IntValue shardManaAmount; public static ForgeConfigSpec.IntValue chargedCrystalManaAmount; + public static ForgeConfigSpec.IntValue smallBudAmount; + public static ForgeConfigSpec.IntValue mediumBudAmount; + public static ForgeConfigSpec.IntValue largeBudAmount; + public static ForgeConfigSpec.DoubleValue manaToHealthRate; public static ForgeConfigSpec.IntValue opBreakHarvestLevel; public static ForgeConfigSpec.IntValue maxRecurseDepth; @@ -20,19 +20,18 @@ public class HexConfig { public HexConfig(ForgeConfigSpec.Builder builder) { - manaToHealthRate = builder.comment("How many points of mana a half-heart is worth when casting from HP") - .defineInRange("manaToHealthRate", 200_000.0 / 20.0, 0.0, Double.POSITIVE_INFINITY); - - builder.push("items"); + builder.push("Mana Amounts"); dustManaAmount = builder.comment("How much mana a single Amethyst Dust item is worth") .defineInRange("dustManaAmount", 10_000, 0, Integer.MAX_VALUE); shardManaAmount = builder.comment("How much mana a single Amethyst Shard item is worth") .defineInRange("shardManaAmount", 50_000, 0, Integer.MAX_VALUE); chargedCrystalManaAmount = builder.comment("How much mana a single Charged Amethyst Crystal item is worth") .defineInRange("chargedCrystalManaAmount", 100_000, 0, Integer.MAX_VALUE); + manaToHealthRate = builder.comment("How many points of mana a half-heart is worth when casting from HP") + .defineInRange("manaToHealthRate", 200_000.0 / 20.0, 0.0, Double.POSITIVE_INFINITY); builder.pop(); - builder.push("spells"); + builder.push("Spells"); maxRecurseDepth = builder.comment("How many times a spell can recursively cast other spells") .defineInRange("maxRecurseDepth", 64, 0, Integer.MAX_VALUE); opBreakHarvestLevel = builder.comment( @@ -41,7 +40,7 @@ public class HexConfig { ).defineInRange("opBreakHarvestLevel", 3, 0, 4); builder.pop(); - builder.push("spell_circles"); + builder.push("Spell Circles"); maxSpellCircleLength = builder.comment("The maximum number of slates in a spell circle") .defineInRange("maxSpellCircleLength", 256, 4, Integer.MAX_VALUE); } diff --git a/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityAbstractImpetus.java b/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityAbstractImpetus.java index 09ed5521..9d31c2ed 100644 --- a/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityAbstractImpetus.java +++ b/src/main/java/at/petrak/hexcasting/common/blocks/circles/impetuses/BlockEntityAbstractImpetus.java @@ -7,9 +7,11 @@ import at.petrak.hexcasting.common.blocks.ModBlockEntity; import at.petrak.hexcasting.common.casting.CastingContext; import at.petrak.hexcasting.common.casting.CastingHarness; import at.petrak.hexcasting.common.casting.colors.FrozenColorizer; +import at.petrak.hexcasting.common.items.HexItems; import at.petrak.hexcasting.common.lib.HexCapabilities; import at.petrak.hexcasting.common.lib.HexSounds; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtUtils; @@ -21,17 +23,25 @@ import net.minecraft.tags.BlockTags; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.UUID; -public abstract class BlockEntityAbstractImpetus extends ModBlockEntity { +public abstract class BlockEntityAbstractImpetus extends ModBlockEntity implements ICapabilityProvider { public static final String TAG_ACTIVATOR = "activator", TAG_COLORIZER = "colorizer", @@ -49,10 +59,13 @@ public abstract class BlockEntityAbstractImpetus extends ModBlockEntity { @Nullable private List trackedBlocks = null; private boolean foundAll = false; + private int mana = 0; + private LazyOptional inventoryHandlerLazy; public BlockEntityAbstractImpetus(BlockEntityType pType, BlockPos pWorldPosition, BlockState pBlockState) { super(pType, pWorldPosition, pBlockState); + inventoryHandlerLazy = LazyOptional.of(() -> ITEM_HANDLER); } abstract public boolean playerAlwaysInRange(); @@ -278,6 +291,21 @@ public abstract class BlockEntityAbstractImpetus extends ModBlockEntity { return scale[note]; } + @NotNull + @Override + public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { + if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return inventoryHandlerLazy.cast(); + } + return super.getCapability(cap, side); + } + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + inventoryHandlerLazy.invalidate(); + } + @Override protected void saveModData(CompoundTag tag) { if (this.activator != null && this.colorizer != null && this.nextBlock != null && this.trackedBlocks != null) { @@ -321,4 +349,62 @@ public abstract class BlockEntityAbstractImpetus extends ModBlockEntity { private static final int[] BLUES_SCALE = {0, 3, 5, 6, 7, 10, 12}; private static final int[] BAD_TIME = {0, 0, 12, 7, 6, 5, 3, 0, 3, 5}; private static final int[] SUSSY_BAKA = {5, 8, 10, 11, 10, 8, 5, 3, 7, 5}; + + protected IItemHandler ITEM_HANDLER = new IItemHandler() { + @Override + public int getSlots() { + return 1; + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + return ItemStack.EMPTY; + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { + var manamount = getManaAmount(stack); + if (manamount != null) { + if (!simulate) { + BlockEntityAbstractImpetus.this.mana += manamount; + } + return ItemStack.EMPTY.copy(); + } + return stack.copy(); + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + return ItemStack.EMPTY.copy(); + } + + @Override + public int getSlotLimit(int slot) { + return 64; + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + return getManaAmount(stack) != null; + } + + // a separate method from the ctx or harness or whatever cause it's different and special + private static @Nullable Integer getManaAmount(ItemStack stack) { + int baseAmt; + if (stack.is(HexItems.AMETHYST_DUST.get())) { + baseAmt = HexConfig.dustManaAmount.get(); + } else if (stack.is(Items.AMETHYST_SHARD)) { + baseAmt = HexConfig.shardManaAmount.get(); + } else if (stack.is(HexItems.CHARGED_AMETHYST.get())) { + baseAmt = HexConfig.chargedCrystalManaAmount.get(); + } else { + return null; + } + + return baseAmt * stack.getCount(); + } + }; } diff --git a/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt b/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt index 0a945037..8505a9cf 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/CastingContext.kt @@ -17,7 +17,7 @@ import java.util.function.Predicate import kotlin.math.min /** - * Info about the moment the spell started being cast. + * Transient info about the moment the spell started being cast. */ data class CastingContext( val caster: ServerPlayer, diff --git a/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt b/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt index 81ac5acc..363d093d 100644 --- a/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt +++ b/src/main/java/at/petrak/hexcasting/common/casting/CastingHarness.kt @@ -2,8 +2,8 @@ package at.petrak.hexcasting.common.casting import at.petrak.hexcasting.HexConfig import at.petrak.hexcasting.HexMod -import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.PatternRegistry +import at.petrak.hexcasting.api.spell.ParticleSpray import at.petrak.hexcasting.api.spell.SpellDatum import at.petrak.hexcasting.common.casting.colors.FrozenColorizer import at.petrak.hexcasting.common.items.ItemWand @@ -33,10 +33,16 @@ class CastingHarness private constructor( var parenthesized: List, var escapeNext: Boolean, val ctx: CastingContext, - val prepackagedColorizer: FrozenColorizer? + val spellCircleContext: SpellCircleContext?, + val prepackagedColorizer: FrozenColorizer? // for trinkets with colorizers ) { - constructor(ctx: CastingContext) : this(mutableListOf(), 0, mutableListOf(), false, ctx, null) + @JvmOverloads + constructor( + ctx: CastingContext, + spellCircleContext: SpellCircleContext? = null, + prepackagedColorizer: FrozenColorizer? = null + ) : this(mutableListOf(), 0, mutableListOf(), false, ctx, spellCircleContext, prepackagedColorizer) /** * Given a pattern, do all the updating/side effects/etc required. @@ -52,8 +58,8 @@ class CastingHarness private constructor( * handle it functionally. */ fun getUpdate(newPat: HexPattern, world: ServerLevel): CastResult { + this.ctx.caster.awardStat(HexStatistics.PATTERNS_DRAWN) try { - this.ctx.caster.awardStat(HexStatistics.PATTERNS_DRAWN) // wouldn't it be nice to be able to go paren' // i guess i'll call it paren2 val paren2 = this.handleParentheses(newPat) @@ -321,6 +327,10 @@ class CastingHarness private constructor( out.put(TAG_PREPACKAGED_COLORIZER, this.prepackagedColorizer.serialize()) } + if (this.spellCircleContext != null) { + out.put(TAG_SPELL_CIRCLE, this.spellCircleContext.serializeToNBT()) + } + return out } @@ -331,6 +341,7 @@ class CastingHarness private constructor( const val TAG_PARENTHESIZED = "parenthesized" const val TAG_ESCAPE_NEXT = "escape_next" const val TAG_PREPACKAGED_COLORIZER = "prepackaged_colorizer" + const val TAG_SPELL_CIRCLE = "spell_circle" @JvmStatic fun DeserializeFromNBT(nbt: Tag?, caster: ServerPlayer, wandHand: InteractionHand): CastingHarness { @@ -360,7 +371,13 @@ class CastingHarness private constructor( null } - CastingHarness(stack, parenCount, parenthesized, escapeNext, ctx, colorizer) + val spellCircleContext = if (nbt.contains(TAG_SPELL_CIRCLE)) { + SpellCircleContext.DeserializeFromNBT(nbt.getCompound(TAG_SPELL_CIRCLE)) + } else { + null + } + + CastingHarness(stack, parenCount, parenthesized, escapeNext, ctx, spellCircleContext, colorizer) } catch (exn: Exception) { HexMod.LOGGER.warn("Couldn't load harness from nbt tag, falling back to default: $nbt: $exn") CastingHarness(ctx) diff --git a/src/main/java/at/petrak/hexcasting/common/casting/SpellCircleContext.kt b/src/main/java/at/petrak/hexcasting/common/casting/SpellCircleContext.kt new file mode 100644 index 00000000..082a5858 --- /dev/null +++ b/src/main/java/at/petrak/hexcasting/common/casting/SpellCircleContext.kt @@ -0,0 +1,59 @@ +package at.petrak.hexcasting.common.casting + +import net.minecraft.core.BlockPos +import net.minecraft.nbt.CompoundTag +import net.minecraft.world.phys.AABB + +/** + * Optional field on a [CastingContext] for the spell circle + */ +data class SpellCircleContext(val impetusPos: BlockPos, val aabb: AABB, val playerAlwaysInRange: Boolean) { + fun serializeToNBT(): CompoundTag { + val out = CompoundTag() + + out.putInt(TAG_IMPETUS_X, impetusPos.x) + out.putInt(TAG_IMPETUS_Y, impetusPos.y) + out.putInt(TAG_IMPETUS_Z, impetusPos.z) + + out.putDouble(TAG_MIN_X, aabb.minX) + out.putDouble(TAG_MIN_Y, aabb.minY) + out.putDouble(TAG_MIN_Z, aabb.minZ) + out.putDouble(TAG_MAX_X, aabb.maxX) + out.putDouble(TAG_MAX_Y, aabb.maxY) + out.putDouble(TAG_MAX_Z, aabb.maxZ) + + out.putBoolean(TAG_PLAYER_ALWAYS_IN_RANGE, playerAlwaysInRange) + + return out + } + + companion object { + const val TAG_IMPETUS_X = "impetus_x" + const val TAG_IMPETUS_Y = "impetus_y" + const val TAG_IMPETUS_Z = "impetus_z" + const val TAG_MIN_X = "min_x" + const val TAG_MIN_Y = "min_y" + const val TAG_MIN_Z = "min_z" + const val TAG_MAX_X = "max_x" + const val TAG_MAX_Y = "max_y" + const val TAG_MAX_Z = "max_z" + const val TAG_PLAYER_ALWAYS_IN_RANGE = "player_always_in_range" + + fun DeserializeFromNBT(tag: CompoundTag): SpellCircleContext { + val impX = tag.getInt(TAG_IMPETUS_X) + val impY = tag.getInt(TAG_IMPETUS_Y) + val impZ = tag.getInt(TAG_IMPETUS_Z) + + val minX = tag.getDouble(TAG_MIN_X) + val minY = tag.getDouble(TAG_MIN_Y) + val minZ = tag.getDouble(TAG_MIN_Z) + val maxX = tag.getDouble(TAG_MAX_X) + val maxY = tag.getDouble(TAG_MAX_Y) + val maxZ = tag.getDouble(TAG_MAX_Z) + + val playerAIR = tag.getBoolean(TAG_PLAYER_ALWAYS_IN_RANGE) + + return SpellCircleContext(BlockPos(impX, impY, impZ), AABB(minX, minY, minZ, maxX, maxY, maxZ), playerAIR) + } + } +}