sentinels are now dimension-bound

This commit is contained in:
yrsegal@gmail.com 2022-04-08 20:17:07 -04:00
parent 5ca14d327e
commit a43d92c6a1
11 changed files with 59 additions and 9 deletions

View file

@ -34,7 +34,7 @@ public class HexAdditionalRenderers {
var maybeSentinelCap = player.getCapability(HexCapabilities.SENTINEL).resolve();
if (maybeSentinelCap.isPresent()) {
var cap = maybeSentinelCap.get();
if (cap.hasSentinel) {
if (cap.hasSentinel && player.getLevel().dimension().equals(cap.dimension)) {
renderSentinel(cap, player, evt.getPoseStack(), evt.getPartialTick());
}
}

View file

@ -83,6 +83,7 @@ data class CastingContext(
val sentinel = maybeSentinel.get()
if (sentinel.hasSentinel
&& sentinel.extendsRange
&& world.dimension() == sentinel.dimension
&& vec.distanceToSqr(sentinel.position) < Operator.MAX_DISTANCE_FROM_SENTINEL * Operator.MAX_DISTANCE_FROM_SENTINEL
)
return true

View file

@ -0,0 +1,22 @@
package at.petrak.hexcasting.common.casting.mishaps
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.Widget
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.DyeColor
class MishapLocationInWrongDimension(val properDimension: ResourceLocation) : Mishap() {
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
dyeColor(DyeColor.MAGENTA)
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
stack.add(SpellDatum.make(Widget.GARBAGE))
}
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("wrong_dimension", actionName(errorCtx.action!!), properDimension.toString(),
ctx.world.dimension().registryName.toString())
}

View file

@ -3,7 +3,11 @@ package at.petrak.hexcasting.common.casting.operators.spells.sentinel;
import at.petrak.hexcasting.HexUtils;
import at.petrak.hexcasting.common.lib.HexCapabilities;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
@ -16,15 +20,18 @@ public class CapSentinel implements ICapabilitySerializable<CompoundTag> {
public static final String TAG_EXISTS = "exists";
public static final String TAG_EXTENDS_RANGE = "extends_range";
public static final String TAG_POSITION = "position";
public static final String TAG_DIMENSION = "dimension";
public boolean hasSentinel;
public boolean extendsRange;
public Vec3 position;
public ResourceKey<Level> dimension;
public CapSentinel(boolean hasSentinel, boolean extendsRange, Vec3 position) {
public CapSentinel(boolean hasSentinel, boolean extendsRange, Vec3 position, ResourceKey<Level> dimension) {
this.hasSentinel = hasSentinel;
this.extendsRange = extendsRange;
this.position = position;
this.dimension = dimension;
}
@NotNull
@ -39,6 +46,7 @@ public class CapSentinel implements ICapabilitySerializable<CompoundTag> {
tag.putBoolean(TAG_EXISTS, this.hasSentinel);
tag.putBoolean(TAG_EXTENDS_RANGE, this.extendsRange);
tag.put(TAG_POSITION, HexUtils.serializeToNBT(this.position));
tag.putString(TAG_DIMENSION, dimension.getRegistryName().toString());
return tag;
}
@ -47,6 +55,7 @@ public class CapSentinel implements ICapabilitySerializable<CompoundTag> {
public void deserializeNBT(CompoundTag tag) {
this.hasSentinel = tag.getBoolean(TAG_EXISTS);
this.extendsRange = tag.getBoolean(TAG_EXTENDS_RANGE);
this.dimension = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(tag.getString(TAG_DIMENSION)));
this.position = HexUtils.DeserializeVec3FromNBT(tag.getLongArray(TAG_POSITION));
}
}

View file

@ -40,6 +40,7 @@ class OpCreateSentinel(val extendsRange: Boolean) : SpellOperator {
cap.hasSentinel = true
cap.extendsRange = extendsRange
cap.position = target
cap.dimension = ctx.world.dimension()
HexMessages.getNetwork().send(PacketDistributor.PLAYER.with { ctx.caster }, MsgSentinelStatusUpdateAck(cap))
}

View file

@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.spell.RenderedSpell
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.api.spell.SpellOperator
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.mishaps.MishapLocationInWrongDimension
import at.petrak.hexcasting.common.lib.HexCapabilities
import at.petrak.hexcasting.common.network.HexMessages
import at.petrak.hexcasting.common.network.MsgSentinelStatusUpdateAck
@ -18,7 +19,11 @@ object OpDestroySentinel : SpellOperator {
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
val particles = mutableListOf<ParticleSpray>()
val maybeCap = ctx.caster.getCapability(HexCapabilities.SENTINEL).resolve()
maybeCap.ifPresent { particles.add(ParticleSpray.Cloud(it.position, 2.0)) }
maybeCap.ifPresent {
if (it.dimension != ctx.world.dimension())
throw MishapLocationInWrongDimension(it.dimension.registryName)
particles.add(ParticleSpray.Cloud(it.position, 2.0))
}
return Triple(
Spell,

View file

@ -5,6 +5,7 @@ import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.Widget
import at.petrak.hexcasting.common.casting.mishaps.MishapLocationInWrongDimension
import at.petrak.hexcasting.common.lib.HexCapabilities
object OpGetSentinelPos : ConstManaOperator {
@ -16,6 +17,8 @@ object OpGetSentinelPos : ConstManaOperator {
return spellListOf(Widget.NULL)
val cap = maybeCap.get()
if (cap.dimension != ctx.world.dimension())
throw MishapLocationInWrongDimension(cap.dimension.registryName)
return spellListOf(
if (cap.hasSentinel)
cap.position

View file

@ -6,6 +6,7 @@ import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.Widget
import at.petrak.hexcasting.common.casting.mishaps.MishapLocationInWrongDimension
import at.petrak.hexcasting.common.lib.HexCapabilities
import net.minecraft.world.phys.Vec3
@ -20,6 +21,9 @@ object OpGetSentinelWayfind : ConstManaOperator {
return spellListOf(Widget.NULL)
val cap = maybeCap.get()
if (cap.dimension != ctx.world.dimension())
throw MishapLocationInWrongDimension(cap.dimension.registryName)
val sentinelPos = if (!cap.hasSentinel)
return spellListOf(Widget.NULL)
else

View file

@ -16,6 +16,7 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityManager;
@ -53,7 +54,7 @@ public class HexCapabilities {
// generate a new instance of the capability
new OpFlight.CapFlight(false, 0, Vec3.ZERO, 0.0));
evt.addCapability(new ResourceLocation(HexMod.MOD_ID, CapSentinel.CAP_NAME),
new CapSentinel(false, false, Vec3.ZERO));
new CapSentinel(false, false, Vec3.ZERO, Level.OVERWORLD));
evt.addCapability(new ResourceLocation(HexMod.MOD_ID, CapPreferredColorizer.CAP_NAME),
new CapPreferredColorizer(FrozenColorizer.DEFAULT));
} else if (evt.getObject() instanceof Villager) {
@ -89,6 +90,7 @@ public class HexCapabilities {
sentinel.hasSentinel = protoSentinel.hasSentinel;
sentinel.position = protoSentinel.position;
sentinel.extendsRange = protoSentinel.extendsRange;
sentinel.dimension = protoSentinel.dimension;
});
});
var protoCapColor = proto.getCapability(PREFERRED_COLORIZER).resolve();

View file

@ -5,6 +5,7 @@ import at.petrak.hexcasting.common.lib.HexCapabilities;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
@ -20,7 +21,7 @@ public record MsgSentinelStatusUpdateAck(CapSentinel update) {
var buf = new FriendlyByteBuf(buffer);
var tag = buf.readAnySizeNbt();
var sentinel = new CapSentinel(false, false, Vec3.ZERO);
var sentinel = new CapSentinel(false, false, Vec3.ZERO, Level.OVERWORLD);
sentinel.deserializeNBT(tag);
return new MsgSentinelStatusUpdateAck(sentinel);
}
@ -43,6 +44,7 @@ public record MsgSentinelStatusUpdateAck(CapSentinel update) {
cap.hasSentinel = update().hasSentinel;
cap.extendsRange = update().extendsRange;
cap.position = update().position;
cap.dimension = update().dimension;
})
);
ctx.get().setPacketHandled(true);

View file

@ -273,6 +273,7 @@
"hexcasting.mishap.not_enough_args": "%s expected %s or more arguments but the stack was only %s tall",
"hexcasting.mishap.too_many_close_parens": "Used Retrospection without first using Introspection",
"hexcasting.mishap.location_too_far": "%s is out of range for %s",
"hexcasting.mishap.wrong_dimension": "%s cannot see %s from %s",
"hexcasting.mishap.entity_too_far": "%s is out of range for %s",
"hexcasting.mishap.eval_too_deep": "Recursively evaluated too deep",
"hexcasting.mishap.bad_item": "%s needs %s but got %s",