circles can now store their own pigments.

This commit is contained in:
Talia-12 2023-06-15 00:07:56 +10:00
parent 4d4262aeff
commit 75b4eb7a4b
11 changed files with 66 additions and 46 deletions

View file

@ -3,6 +3,7 @@ package at.petrak.hexcasting.api.casting.circles;
import at.petrak.hexcasting.api.block.HexBlockEntity;
import at.petrak.hexcasting.api.block.circle.BlockCircleComponent;
import at.petrak.hexcasting.api.misc.MediaConstants;
import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.api.utils.MediaHelper;
import at.petrak.hexcasting.common.items.magic.ItemCreativeUnlocker;
import at.petrak.hexcasting.common.lib.HexItems;
@ -47,7 +48,8 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
TAG_EXECUTION_STATE = "executor",
TAG_MEDIA = "media",
TAG_ERROR_MSG = "errorMsg",
TAG_ERROR_DISPLAY = "errorDisplay";
TAG_ERROR_DISPLAY = "errorDisplay",
TAG_PIGMENT = "pigment";
// We might try to load the executor in loadModData when the level doesn't exist yet,
// so save the tag and load it lazy
@ -62,6 +64,8 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
protected Component displayMsg = null;
@Nullable
protected ItemStack displayItem = null;
@Nullable
protected FrozenPigment pigment = null;
public BlockEntityAbstractImpetus(BlockEntityType<?> pType, BlockPos pWorldPosition, BlockState pBlockState) {
@ -228,6 +232,7 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
public void setMedia(long media) {
this.media = media;
sync();
}
public long extractMediaFromInsertedItem(ItemStack stack, boolean simulate) {
@ -264,6 +269,20 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
//endregion
public FrozenPigment getPigment() {
if (pigment != null)
return pigment;
if (executionState != null && executionState.casterPigment != null)
return executionState.casterPigment;
return FrozenPigment.DEFAULT.get();
}
public @Nullable FrozenPigment setPigment(@Nullable FrozenPigment pigment) {
this.pigment = pigment;
return this.pigment;
}
@Override
protected void saveModData(CompoundTag tag) {
if (this.executionState != null) {
@ -278,6 +297,8 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
this.displayItem.save(itemTag);
tag.put(TAG_ERROR_DISPLAY, itemTag);
}
if (this.pigment != null)
tag.put(TAG_PIGMENT, this.pigment.serializeToNBT());
}
@Override
@ -302,6 +323,8 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
this.displayMsg = null;
this.displayItem = null;
}
if (tag.contains(TAG_PIGMENT, Tag.TAG_COMPOUND))
this.pigment = FrozenPigment.fromNBT(tag.getCompound(TAG_PIGMENT));
}
public void applyScryingLensOverlay(List<Pair<ItemStack, Component>> lines,

View file

@ -37,7 +37,7 @@ public class CircleExecutionState {
TAG_ENTERED_FROM = "entered_from",
TAG_IMAGE = "image",
TAG_CASTER = "caster",
TAG_COLORIZER = "colorizer";
TAG_PIGMENT = "pigment";
public final BlockPos impetusPos;
public final Direction impetusDir;
@ -48,14 +48,14 @@ public class CircleExecutionState {
public Direction enteredFrom;
public CastingImage currentImage;
public @Nullable UUID caster;
public FrozenPigment colorizer;
public @Nullable FrozenPigment casterPigment;
public final AABB bounds;
protected CircleExecutionState(BlockPos impetusPos, Direction impetusDir, Set<BlockPos> knownPositions,
List<BlockPos> reachedPositions, BlockPos currentPos, Direction enteredFrom,
CastingImage currentImage, @Nullable UUID caster, FrozenPigment colorizer) {
CastingImage currentImage, @Nullable UUID caster, @Nullable FrozenPigment casterPigment) {
this.impetusPos = impetusPos;
this.impetusDir = impetusDir;
this.knownPositions = knownPositions;
@ -64,7 +64,7 @@ public class CircleExecutionState {
this.enteredFrom = enteredFrom;
this.currentImage = currentImage;
this.caster = caster;
this.colorizer = colorizer;
this.casterPigment = casterPigment;
this.bounds = BlockEntityAbstractImpetus.getBounds(new ArrayList<>(this.knownPositions));
}
@ -133,10 +133,9 @@ public class CircleExecutionState {
reachedPositions.add(impetus.getBlockPos());
var start = seenGoodPositions.get(0);
FrozenPigment colorizer;
FrozenPigment colorizer = null;
UUID casterUUID;
if (caster == null) {
colorizer = FrozenPigment.DEFAULT.get();
casterUUID = null;
} else {
colorizer = HexAPI.instance().getColorizer(caster);
@ -172,7 +171,8 @@ public class CircleExecutionState {
if (this.caster != null)
out.putUUID(TAG_CASTER, this.caster);
out.put(TAG_COLORIZER, this.colorizer.serializeToNBT());
if (this.casterPigment != null)
out.put(TAG_PIGMENT, this.casterPigment.serializeToNBT());
return out;
}
@ -200,10 +200,12 @@ public class CircleExecutionState {
if (nbt.hasUUID(TAG_CASTER))
caster = nbt.getUUID(TAG_CASTER);
FrozenPigment colorizer = FrozenPigment.fromNBT(nbt.getCompound(TAG_COLORIZER));
FrozenPigment pigment = null;
if (nbt.contains(TAG_PIGMENT, Tag.TAG_COMPOUND))
pigment = FrozenPigment.fromNBT(nbt.getCompound(TAG_PIGMENT));
return new CircleExecutionState(startPos, startDir, knownPositions, reachedPositions, currentPos,
enteredFrom, image, caster, colorizer);
enteredFrom, image, caster, pigment);
}
/**

View file

@ -106,7 +106,7 @@ public interface ICircleComponent {
if (impetus == null || impetus.getExecutionState() == null)
colorizer = new FrozenPigment(new ItemStack(HexItems.DYE_COLORIZERS.get(DyeColor.RED)), activator);
else
colorizer = impetus.getExecutionState().colorizer;
colorizer = impetus.getPigment();
if (bs.getBlock() instanceof BlockCircleComponent bcc) {
var outDir = bcc.normalDir(pos, bs, world);

View file

@ -291,6 +291,8 @@ public abstract class CastingEnvironment {
public abstract FrozenPigment getColorizer();
public abstract @Nullable FrozenPigment setPigment(@Nullable FrozenPigment pigment);
public abstract void produceParticles(ParticleSpray particles, FrozenPigment colorizer);
public abstract void printMessage(Component message);

View file

@ -9,8 +9,6 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment;
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect;
import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.common.lib.HexItems;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
@ -147,27 +145,23 @@ public class CircleCastEnv extends CastingEnvironment {
@Override
public FrozenPigment getColorizer() {
var out = this.getColorizerFromImpetus();
if (out != null)
return out;
// TODO: colouriser from an adjacent inventory also?
return new FrozenPigment(new ItemStack(HexItems.DYE_COLORIZERS.get(DyeColor.PURPLE)), Util.NIL_UUID);
}
private @Nullable FrozenPigment getColorizerFromImpetus() {
var impetus = this.getImpetus();
if (impetus == null)
return null;
var state = impetus.getExecutionState();
if (state == null)
return null;
return state.colorizer;
return FrozenPigment.DEFAULT.get();
return impetus.getPigment();
}
@Override
public void produceParticles(ParticleSpray particles, FrozenPigment colorizer) {
particles.sprayParticles(this.world, colorizer);
public @Nullable FrozenPigment setPigment(@Nullable FrozenPigment pigment) {
var impetus = this.getImpetus();
if (impetus == null)
return null;
return impetus.setPigment(pigment);
}
@Override
public void produceParticles(ParticleSpray particles, FrozenPigment pigment) {
particles.sprayParticles(this.world, pigment);
}
@Override

View file

@ -15,6 +15,7 @@ import at.petrak.hexcasting.api.mod.HexStatistics;
import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.api.utils.HexUtils;
import at.petrak.hexcasting.api.utils.MediaHelper;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
@ -188,6 +189,13 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
return advs.getOrStartProgress(adv).isDone();
}
@Override
public @Nullable FrozenPigment setPigment(@Nullable FrozenPigment pigment) {
IXplatAbstractions.INSTANCE.setColorizer(caster, pigment);
return null;
}
@Override
public void produceParticles(ParticleSpray particles, FrozenPigment colorizer) {
particles.sprayParticles(this.world, colorizer);

View file

@ -16,7 +16,7 @@ class MishapOthersName(val confidant: Player) : Mishap() {
dyeColor(DyeColor.BLACK)
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
val seconds = if (this.confidant == ctx.caster) 5 else 60;
val seconds = if (this.confidant == ctx.caster) 5 else 60
ctx.mishapEnvironment.blind(seconds * 20)
}
@ -49,7 +49,7 @@ class MishapOthersName(val confidant: Player) : Mishap() {
}
@JvmStatic
fun getTrueNameFromArgs(datums: List<Iota>, caster: Player): Player? {
fun getTrueNameFromArgs(datums: List<Iota>, caster: Player?): Player? {
return datums.firstNotNullOfOrNull { getTrueNameFromDatum(it, caster) }
}
}

View file

@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.api.misc.MediaConstants
import at.petrak.hexcasting.api.pigment.FrozenPigment
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.Util
import net.minecraft.world.item.ItemStack
object OpColorize : SpellAction {
@ -38,13 +39,8 @@ object OpColorize : SpellAction {
private data class Spell(val stack: ItemStack) : RenderedSpell {
override fun cast(ctx: CastingEnvironment) {
val copy = stack.copy()
val caster = ctx.caster
if (caster != null && ctx.withdrawItem(copy::sameItem, 1, true)) {
IXplatAbstractions.INSTANCE.setColorizer(
ctx.caster,
FrozenPigment(copy, caster.uuid)
)
}
if (ctx.withdrawItem(copy::sameItem, 1, true))
ctx.setPigment(FrozenPigment(copy, ctx.caster?.uuid ?: Util.NIL_UUID))
}
}
}

View file

@ -51,7 +51,7 @@ class OpConjureBlock(val light: Boolean) : SpellAction {
if (worldState.canBeReplaced(placeContext)) {
val block = if (this.light) HexBlocks.CONJURED_LIGHT else HexBlocks.CONJURED_BLOCK
if (ctx.caster != null && !IXplatAbstractions.INSTANCE.isPlacingAllowed(ctx.world, pos, ItemStack(block), ctx.caster))
if (!IXplatAbstractions.INSTANCE.isPlacingAllowed(ctx.world, pos, ItemStack(block), ctx.caster))
return
val state = block.getStateForPlacement(placeContext)

View file

@ -53,7 +53,7 @@ class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) :
)
}
val trueName = ctx.caster?.let { MishapOthersName.getTrueNameFromArgs(patterns, it) }
val trueName = MishapOthersName.getTrueNameFromArgs(patterns, ctx.caster)
if (trueName != null)
throw MishapOthersName(trueName)

View file

@ -35,14 +35,9 @@ object OpTheOnlyReasonAnyoneDownloadedPsi : SpellAction {
private data class Spell(val pos: BlockPos) : RenderedSpell {
override fun cast(ctx: CastingEnvironment) {
val caster = ctx.caster ?: return // TODO: fix!
// https://github.com/VazkiiMods/Psi/blob/master/src/main/java/vazkii/psi/common/spell/trick/PieceTrickOvergrow.java
val hit = BlockHitResult(Vec3.ZERO, Direction.UP, pos, false)
val save: ItemStack = caster.getItemInHand(InteractionHand.MAIN_HAND)
caster.setItemInHand(InteractionHand.MAIN_HAND, ItemStack(Items.BONE_MEAL))
val fakeContext = UseOnContext(caster, InteractionHand.MAIN_HAND, hit)
caster.setItemInHand(InteractionHand.MAIN_HAND, save)
val fakeContext = UseOnContext(ctx.world, ctx.caster, InteractionHand.MAIN_HAND, ItemStack(Items.BONE_MEAL), hit)
Items.BONE_MEAL.useOn(fakeContext)
}
}