Made Circles able to have a player again. Made the AABB of the circle used. Made StaffCastEnv and PackagedItemCastEnv give creative players inf media. Fixed CastingEnvironment.getHeldItemToOperateOn

This commit is contained in:
Talia-12 2023-04-02 22:26:12 +10:00
parent 337736e32d
commit 4b1e5e997e
17 changed files with 83 additions and 24 deletions

View file

@ -12,6 +12,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.WorldlyContainer;
@ -25,7 +26,6 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat;
@ -118,8 +118,8 @@ public abstract class BlockEntityAbstractImpetus extends HexBlockEntity implemen
return this.executionState;
}
public void startExecution() {
this.executionState = CircleExecutionState.createNew(this);
public void startExecution(@Nullable ServerPlayer player) {
this.executionState = CircleExecutionState.createNew(this, player);
}
@Contract(pure = true)

View file

@ -104,6 +104,11 @@ public abstract class CastingEnvironment {
*/
public abstract boolean isVecInRange(Vec3 vec);
/**
* Return whether the caster can edit blocks at the given permission (i.e. not adventure mode, etc.)
*/
public abstract boolean hasEditPermissionsAt(BlockPos vec);
public final boolean isVecInWorld(Vec3 vec) {
return this.world.isInWorldBounds(new BlockPos(vec))
&& this.world.getWorldBorder().isWithinBounds(vec.x, vec.z, 0.5);
@ -132,8 +137,7 @@ public abstract class CastingEnvironment {
}
public final boolean canEditBlockAt(BlockPos vec) {
// TODO winfy: fill this in
return false;
return this.isVecInRange(Vec3.atCenterOf(vec)) && this.hasEditPermissionsAt(vec);
}
/**
@ -159,7 +163,7 @@ public abstract class CastingEnvironment {
public abstract InteractionHand getCastingHand();
public InteractionHand otherHand() {
public InteractionHand getOtherHand() {
return HexUtils.otherHand(this.getCastingHand());
}
@ -176,6 +180,11 @@ public abstract class CastingEnvironment {
*/
protected abstract List<ItemStack> getUsableStacks(StackDiscoveryMode mode);
/**
* Get the primary/secondary item stacks this env can use (i.e. main hand and offhand for the player).
*/
protected abstract List<HeldItemInfo> getPrimaryStacks();
/**
* Return the slot from which to take blocks and items.
*/
@ -191,12 +200,12 @@ public abstract class CastingEnvironment {
return null;
}
public static record HeldItemInfo(ItemStack stack, InteractionHand hand) {
public static record HeldItemInfo(ItemStack stack, @Nullable InteractionHand hand) {
public ItemStack component1() {
return stack;
}
public InteractionHand component2() {
public @Nullable InteractionHand component2() {
return hand;
}
}
@ -205,9 +214,14 @@ public abstract class CastingEnvironment {
* Return the slot from which to take blocks and items.
*/
// TODO winfy: resolve the null here
// @Nullable
public HeldItemInfo getHeldItemToOperateOn(Predicate<ItemStack> stackOk) {
// TODO winfy: return something properly
public @Nullable HeldItemInfo getHeldItemToOperateOn(Predicate<ItemStack> stackOk) {
var stacks = this.getPrimaryStacks();
for (HeldItemInfo stack : stacks) {
if (stackOk.test(stack.stack)) {
return stack;
}
}
return null;
}

View file

@ -117,6 +117,11 @@ public class CircleCastEnv extends CastingEnvironment {
return this.bounds.contains(vec);
}
@Override
public boolean hasEditPermissionsAt(BlockPos vec) {
return true;
}
@Override
public InteractionHand getCastingHand() {
return InteractionHand.MAIN_HAND;
@ -124,7 +129,7 @@ public class CircleCastEnv extends CastingEnvironment {
@Override
public ItemStack getAlternateItem() {
return ItemStack.EMPTY.copy();
return ItemStack.EMPTY.copy(); // TODO: adjacent inventory/item frame?
}
@Override
@ -132,8 +137,17 @@ public class CircleCastEnv extends CastingEnvironment {
return new ArrayList<>(); // TODO: Could do something like get items in inventories adjacent to the circle?
}
@Override
protected List<HeldItemInfo> getPrimaryStacks() {
return List.of(); // TODO: Adjacent inv!
}
@Override
public FrozenColorizer getColorizer() {
if (this.caster != null)
return HexAPI.instance().getColorizer(this.caster);
// TODO: colouriser from an adjacent inventory also?
return new FrozenColorizer(new ItemStack(HexItems.DYE_COLORIZERS.get(DyeColor.PURPLE)), Util.NIL_UUID);
}

View file

@ -16,11 +16,13 @@ import at.petrak.hexcasting.api.mod.HexStatistics;
import at.petrak.hexcasting.api.utils.HexUtils;
import at.petrak.hexcasting.api.utils.MediaHelper;
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
@ -102,6 +104,16 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
};
}
@Override
protected List<HeldItemInfo> getPrimaryStacks() {
var primaryItem = this.caster.getItemInHand(this.castingHand);
if (primaryItem.isEmpty())
primaryItem = ItemStack.EMPTY.copy();
return List.of(new HeldItemInfo(getAlternateItem(), this.getOtherHand()), new HeldItemInfo(primaryItem, this.castingHand));
}
@Override
public boolean isVecInRange(Vec3 vec) {
var sentinel = HexAPI.instance().getSentinel(this.caster);
@ -116,6 +128,11 @@ public abstract class PlayerBasedCastEnv extends CastingEnvironment {
return vec.distanceToSqr(this.caster.position()) <= AMBIT_RADIUS * AMBIT_RADIUS;
}
@Override
public boolean hasEditPermissionsAt(BlockPos vec) {
return this.caster.gameMode.getGameModeForPlayer() != GameType.ADVENTURE && this.world.mayInteract(this.caster, vec);
}
@Override
public ItemStack getAlternateItem() {
var otherHand = HexUtils.otherHand(this.castingHand);

View file

@ -9,7 +9,7 @@ import net.minecraft.world.InteractionHand
import net.minecraft.world.item.DyeColor
import net.minecraft.world.item.ItemStack
class MishapBadOffhandItem(val item: ItemStack, val hand: InteractionHand, val wanted: Component) : Mishap() {
class MishapBadOffhandItem(val item: ItemStack, val hand: InteractionHand?, val wanted: Component) : Mishap() {
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.BROWN)
@ -24,7 +24,7 @@ class MishapBadOffhandItem(val item: ItemStack, val hand: InteractionHand, val w
companion object {
@JvmStatic
fun of(item: ItemStack, hand: InteractionHand, stub: String, vararg args: Any): MishapBadOffhandItem {
fun of(item: ItemStack, hand: InteractionHand?, stub: String, vararg args: Any): MishapBadOffhandItem {
return MishapBadOffhandItem(item, hand, "hexcasting.mishap.bad_item.$stub".asTranslatedComponent(*args))
}
}

View file

@ -32,7 +32,7 @@ public class BlockRightClickImpetus extends BlockAbstractImpetus {
if (tile instanceof BlockEntityRightClickImpetus impetus) {
if (pPlayer instanceof ServerPlayer serverPlayer) {
// impetus.activateSpellCircle(serverPlayer);
impetus.startExecution();
impetus.startExecution(serverPlayer);
}
return InteractionResult.SUCCESS;
}

View file

@ -92,9 +92,11 @@ public class BlockStoredPlayerImpetus extends BlockAbstractImpetus {
if (isPowered && pLevel.getBlockEntity(pPos) instanceof BlockEntityStoredPlayerImpetus tile) {
var player = tile.getStoredPlayer();
if (player instanceof ServerPlayer splayer) {
if (player == null) {
tile.startExecution(null);
} else if (player instanceof ServerPlayer splayer) {
// phew
tile.startExecution();
tile.startExecution(splayer);
}
}
}

View file

@ -69,8 +69,7 @@ public class BlockEntityLookingImpetus extends BlockEntityAbstractImpetus {
if (newLook != prevLookAmt) {
if (newLook == MAX_LOOK_AMOUNT) {
self.lookAmount = 0;
self.startExecution();
// self.activateSpellCircle(looker);
self.startExecution(looker);
} else {
if (newLook % 5 == 1) {
var t = (float) newLook / MAX_LOOK_AMOUNT;

View file

@ -3,6 +3,7 @@ package at.petrak.hexcasting.common.casting.operators.rw
import at.petrak.hexcasting.api.casting.castables.ConstMediaAction
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.iota.NullIota
import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.xplat.IXplatAbstractions
@ -13,7 +14,7 @@ object OpRead : ConstMediaAction {
val (handStack, hand) = ctx.getHeldItemToOperateOn {
val dataHolder = IXplatAbstractions.INSTANCE.findDataHolder(it)
dataHolder != null && (dataHolder.readIota(ctx.world) != null || dataHolder.emptyIota() != null)
}
} ?: return listOf(NullIota())
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack)
?: throw MishapBadOffhandItem.of(handStack, hand, "iota.read")

View file

@ -12,7 +12,7 @@ object OpReadable : ConstMediaAction {
override fun execute(args: List<Iota>, ctx: CastingEnvironment): List<Iota> {
val (handStack) = ctx.getHeldItemToOperateOn {
IXplatAbstractions.INSTANCE.findDataHolder(it) != null
}
} ?: return false.asActionResult
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack)
?: return false.asActionResult

View file

@ -15,7 +15,7 @@ object OpWritable : ConstMediaAction {
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it)
datumHolder != null
}
} ?: return false.asActionResult
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack) ?: return false.asActionResult
val success = datumHolder.writeIota(NullIota(), true)

View file

@ -9,6 +9,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName
import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.world.item.ItemStack
// we make this a spell cause imo it's a little ... anticlimactic for it to just make no noise
object OpWrite : SpellAction {
@ -23,7 +24,7 @@ object OpWrite : SpellAction {
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(it)
datumHolder != null && datumHolder.writeIota(datum, true)
}
} ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "iota.write") // TODO: hack
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack)
?: throw MishapBadOffhandItem.of(handStack, hand, "iota.write")

View file

@ -19,6 +19,8 @@ object OpColorize : SpellAction {
ctx: CastingEnvironment
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
val (handStack, hand) = ctx.getHeldItemToOperateOn(IXplatAbstractions.INSTANCE::isColorizer)
?: throw MishapBadOffhandItem.of(ItemStack.EMPTY, null, "colorizer") // TODO: hack
if (!IXplatAbstractions.INSTANCE.isColorizer(handStack)) {
throw MishapBadOffhandItem.of(
handStack,
@ -26,6 +28,7 @@ object OpColorize : SpellAction {
"colorizer"
)
}
return Triple(
Spell(handStack),
MediaConstants.DUST_UNIT,

View file

@ -23,7 +23,8 @@ object OpErase : SpellAction {
(hexHolder?.hasHex() == true) ||
(datumHolder?.writeIota(null, true) == true)
}
} ?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "eraseable") // TODO: hack
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack)
val datumHolder = IXplatAbstractions.INSTANCE.findDataHolder(handStack)

View file

@ -29,6 +29,10 @@ object OpMakeBattery : SpellAction {
val entity = args.getItemEntity(0, argc)
val (handStack, hand) = ctx.getHeldItemToOperateOn { it.`is`(HexTags.Items.PHIAL_BASE) }
?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "bottle") // TODO: hack
if (hand == null)
throw MishapBadOffhandItem.of(handStack, null, "havent_handled_null_hand_yet") // TODO: hack!
if (!handStack.`is`(HexTags.Items.PHIAL_BASE)) {
throw MishapBadOffhandItem.of(

View file

@ -28,6 +28,8 @@ class OpMakePackagedSpell<T : ItemPackagedHex>(val itemType: T, val cost: Int) :
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(it)
it.`is`(itemType) && hexHolder != null && !hexHolder.hasHex()
}
?: throw MishapBadOffhandItem(ItemStack.EMPTY.copy(), null, itemType.description) // TODO: hack
val hexHolder = IXplatAbstractions.INSTANCE.findHexHolder(handStack)
if (!handStack.`is`(itemType)) {
throw MishapBadOffhandItem(handStack, hand, itemType.description)

View file

@ -27,6 +27,7 @@ object OpRecharge : SpellAction {
val media = IXplatAbstractions.INSTANCE.findMediaHolder(it)
media != null && media.canRecharge() && media.insertMedia(-1, true) != 0L
}
?: throw MishapBadOffhandItem.of(ItemStack.EMPTY.copy(), null, "rechargable") // TODO: hack
val media = IXplatAbstractions.INSTANCE.findMediaHolder(handStack)