fix conflicts

This commit is contained in:
gamma-delta 2022-04-08 22:01:19 -05:00
commit 999def56ba
27 changed files with 259 additions and 163 deletions

View file

@ -18,6 +18,6 @@
}
}
],
"delta": -2,
"modifier": 0.5,
"type": "hexcasting:amethyst_shard_reducer"
}
}

View file

@ -140,6 +140,14 @@ object PatternRegistry {
throw IllegalArgumentException("could not find a pattern for $opId")
}
/**
* Internal use only.
*/
@JvmStatic
fun getAllPerWorldPatternNames(): Set<ResourceLocation> {
return this.perWorldPatternLookup.keys.toSet()
}
/**
* Special handling of a pattern. Before checking any of the normal angle-signature based patterns,
* a given pattern is run by all of these special handlers patterns. If none of them return non-null,
@ -215,4 +223,4 @@ object PatternRegistry {
"${this.specialHandlers.size} special handlers."
)
}
}
}

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

@ -13,7 +13,6 @@ import at.petrak.hexcasting.common.lib.HexSounds
import at.petrak.hexcasting.common.network.HexMessages
import at.petrak.hexcasting.common.network.MsgNewSpellPatternSyn
import at.petrak.hexcasting.common.network.MsgShiftScrollSyn
import at.petrak.hexcasting.common.network.MsgStackRequestSyn
import at.petrak.hexcasting.hexmath.HexAngle
import at.petrak.hexcasting.hexmath.HexCoord
import at.petrak.hexcasting.hexmath.HexDir
@ -39,14 +38,19 @@ import kotlin.math.roundToInt
const val SQRT_3 = 1.7320508f
class GuiSpellcasting(private val handOpenedWith: InteractionHand) : Screen(TextComponent("")) {
private var patterns: MutableList<ResolvedPattern> = mutableListOf()
class GuiSpellcasting(private val handOpenedWith: InteractionHand,
private var patterns: MutableList<ResolvedPattern>,
private var stackDescs: List<Component>) : Screen(TextComponent("")) {
private var drawState: PatternDrawState = PatternDrawState.BetweenPatterns
private val usedSpots: MutableSet<HexCoord> = HashSet()
private var ambianceSoundInstance: AbstractSoundInstance? = null
private var stackDescs: List<Component> = emptyList()
init {
for ((pattern, origin) in patterns) {
this.usedSpots.addAll(pattern.positions(origin))
}
}
fun recvServerUpdate(info: ControllerInfo) {
this.stackDescs = info.stackDesc
@ -67,10 +71,6 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand) : Screen(Text
}
}
fun recvStackUpdate(components: List<Component>) {
this.stackDescs = components
}
override fun init() {
val minecraft = Minecraft.getInstance()
val soundManager = minecraft.soundManager
@ -89,18 +89,6 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand) : Screen(Text
true // this means is it relative to the *player's ears*, not to a given point, thanks mojank
)
soundManager.play(this.ambianceSoundInstance!!)
val stack = minecraft.player!!.getItemInHand(this.handOpenedWith)
val stackPatterns = stack.tag?.getList(ItemWand.TAG_PATTERNS, Tag.TAG_COMPOUND.toInt())
if (stackPatterns != null) for (pat in stackPatterns) {
val pattern = ResolvedPattern.DeserializeFromNBT(pat as CompoundTag)
this.patterns.add(pattern)
this.usedSpots.addAll(pattern.pattern.positions(pattern.origin))
}
HexMessages.getNetwork().sendToServer(
MsgStackRequestSyn(this.handOpenedWith)
)
}
override fun mouseClicked(mxOut: Double, myOut: Double, pButton: Int): Boolean {

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

@ -20,4 +20,29 @@ class MishapOthersName(val other: Player) : Mishap() {
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
error("others_name", other.name)
}
companion object {
@JvmStatic
fun getTrueNameFromDatum(datum: SpellDatum<*>, caster: Player): Player? {
if (datum.payload is Player && datum.payload != caster)
return datum.payload
else if (datum.payload !is List<*>)
return null
val poolToSearch: MutableList<SpellDatum<*>> =
datum.payload.filterIsInstance<SpellDatum<*>>().toMutableList()
while (poolToSearch.isNotEmpty()) {
val datumToCheck = poolToSearch[0]
poolToSearch.removeAt(0)
if (datumToCheck.payload is Player && datumToCheck.payload != caster)
return datumToCheck.payload
else if (datumToCheck.payload is List<*>)
poolToSearch.addAll(datumToCheck.payload.filterIsInstance<SpellDatum<*>>())
}
return null
}
}
}

View file

@ -47,8 +47,9 @@ object OpWrite : SpellOperator {
if (!canWrite)
throw MishapBadOffhandItem.of(handStack, "iota.write")
if (datum.payload is Player && datum.payload != ctx.caster)
throw MishapOthersName(datum.payload)
val trueName = MishapOthersName.getTrueNameFromDatum(datum, ctx.caster)
if (trueName != null)
throw MishapOthersName(trueName)
return Triple(
Spell(datum),
@ -77,4 +78,4 @@ object OpWrite : SpellOperator {
}
}
}
}

View file

@ -21,7 +21,7 @@ object OpLastNToList : Operator {
val arg = stack.takeLast(1).getChecked<Double>(0)
val datum = stack[stack.lastIndex]
stack.removeLast()
if (arg < 0 || arg >= stack.size) {
if (arg < 0 || arg > stack.size) {
throw MishapInvalidIota(
datum,
0,
@ -40,4 +40,4 @@ object OpLastNToList : Operator {
return OperationResult(stack, sideEffects)
}
}
}

View file

@ -31,7 +31,8 @@ class OpGetEntitiesBy(val checker: Predicate<Entity>, val negate: Boolean) : Con
val entitiesGot = ctx.world.getEntities(
null,
aabb
) { (checker.test(it) != negate) && ctx.isEntityInRange(it) }
) { (checker.test(it) != negate) && ctx.isEntityInRange(it) && it.distanceToSqr(pos) <= radius * radius }
.sortedBy { it.distanceToSqr(pos) }
return spellListOf(entitiesGot)
}
@ -52,4 +53,4 @@ class OpGetEntitiesBy(val checker: Predicate<Entity>, val negate: Boolean) : Con
@JvmStatic
fun isLiving(e: Entity): Boolean = e is LivingEntity
}
}
}

View file

@ -23,7 +23,7 @@ class OpExplode(val fire: Boolean) : SpellOperator {
ctx.assertVecInRange(pos)
return Triple(
Spell(pos, strength, this.fire),
((1 + strength + if (this.fire) 2 else 0) * 50_000.0).toInt(),
((1 + Mth.clamp(strength.toFloat(), 0f, 10f) + if (this.fire) 2 else 0) * 50_000.0).toInt(),
listOf(ParticleSpray.Burst(pos, strength, 50))
)
}
@ -41,4 +41,4 @@ class OpExplode(val fire: Boolean) : SpellOperator {
)
}
}
}
}

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.location().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,8 +40,9 @@ 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,
@ -39,4 +44,4 @@ object OpDestroySentinel : SpellOperator {
HexMessages.getNetwork().send(PacketDistributor.PLAYER.with { ctx.caster }, MsgSentinelStatusUpdateAck(cap))
}
}
}
}

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
@ -23,4 +26,4 @@ object OpGetSentinelPos : ConstManaOperator {
Widget.NULL
)
}
}
}

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
@ -27,4 +31,4 @@ object OpGetSentinelWayfind : ConstManaOperator {
return spellListOf(sentinelPos.subtract(from).normalize())
}
}
}

View file

@ -5,11 +5,16 @@ import at.petrak.hexcasting.hexmath.HexPattern;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.arguments.ResourceLocationArgument;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import java.util.concurrent.CompletableFuture;
public class PatternResLocArgument extends ResourceLocationArgument {
private static final DynamicCommandExceptionType ERROR_UNKNOWN_PATTERN = new DynamicCommandExceptionType(
(errorer) ->
@ -20,6 +25,11 @@ public class PatternResLocArgument extends ResourceLocationArgument {
return new PatternResLocArgument();
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return SharedSuggestionProvider.suggest(PatternRegistry.getAllPerWorldPatternNames().stream().map(Object::toString), builder);
}
public static HexPattern getPattern(
CommandContext<CommandSourceStack> ctx, String pName) throws CommandSyntaxException {
var targetId = ctx.getArgument(pName, ResourceLocation.class);

View file

@ -1,19 +1,30 @@
package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.client.gui.GuiSpellcasting;
import net.minecraft.client.Minecraft;
import at.petrak.hexcasting.common.casting.CastingContext;
import at.petrak.hexcasting.common.casting.CastingHarness;
import at.petrak.hexcasting.common.casting.ResolvedPattern;
import at.petrak.hexcasting.common.lib.HexSounds;
import at.petrak.hexcasting.common.network.HexMessages;
import at.petrak.hexcasting.common.network.MsgOpenSpellGuiAck;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.PacketDistributor;
import java.util.ArrayList;
import java.util.List;
public class ItemWand extends Item {
public static final String TAG_HARNESS = "harness";
public static final String TAG_PATTERNS = "patterns";
public static final String TAG_HARNESS = "hexcasting:spell_harness";
public static final String TAG_PATTERNS = "hexcasting:spell_patterns";
public ItemWand(Properties pProperties) {
super(pProperties);
@ -21,8 +32,30 @@ public class ItemWand extends Item {
@Override
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
if (world.isClientSide()) {
ClientAccess.openSpellcastGui(hand);
if (player.isShiftKeyDown()) {
if (world.isClientSide()) {
player.playSound(HexSounds.FAIL_PATTERN.get(), 1f, 1f);
} else {
player.getPersistentData().remove(TAG_HARNESS);
player.getPersistentData().remove(TAG_PATTERNS);
}
}
if (!world.isClientSide() && player instanceof ServerPlayer serverPlayer) {
CompoundTag harnessTag = player.getPersistentData().getCompound(TAG_HARNESS);
ListTag patternsTag = player.getPersistentData().getList(TAG_PATTERNS, Tag.TAG_COMPOUND);
var ctx = new CastingContext(serverPlayer, hand);
CastingHarness harness = CastingHarness.DeserializeFromNBT(harnessTag, ctx);
List<ResolvedPattern> patterns = new ArrayList<>(patternsTag.size());
for (int i = 0; i < patternsTag.size(); i++) {
patterns.add(ResolvedPattern.DeserializeFromNBT(patternsTag.getCompound(i)));
}
HexMessages.getNetwork().send(PacketDistributor.PLAYER.with(() -> serverPlayer),
new MsgOpenSpellGuiAck(hand, patterns, harness.generateDescs()));
}
player.awardStat(Stats.ITEM_USED.get(this));
@ -30,18 +63,4 @@ public class ItemWand extends Item {
return InteractionResultHolder.success(player.getItemInHand(hand));
}
@Override
public void inventoryTick(ItemStack pStack, Level pLevel, Entity pEntity, int pSlotId, boolean pIsSelected) {
if (pEntity instanceof Player player && player.getMainHandItem() != pStack && player.getOffhandItem() != pStack) {
pStack.removeTagKey(TAG_HARNESS);
pStack.removeTagKey(TAG_PATTERNS);
}
}
private static class ClientAccess {
public static void openSpellcastGui(InteractionHand hand) {
Minecraft.getInstance().setScreen(new GuiSpellcasting(hand));
}
}
}

View file

@ -5,15 +5,18 @@ import at.petrak.hexcasting.common.casting.colors.CapPreferredColorizer;
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer;
import at.petrak.hexcasting.common.casting.operators.spells.great.OpFlight;
import at.petrak.hexcasting.common.casting.operators.spells.sentinel.CapSentinel;
import at.petrak.hexcasting.common.items.ItemWand;
import at.petrak.hexcasting.common.misc.Brainsweeping;
import at.petrak.hexcasting.common.network.HexMessages;
import at.petrak.hexcasting.common.network.MsgColorizerUpdateAck;
import at.petrak.hexcasting.common.network.MsgSentinelStatusUpdateAck;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
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;
@ -51,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) {
@ -69,28 +72,35 @@ public class HexCapabilities {
return;
}
if (evt.isWasDeath()) {
var proto = evt.getOriginal();
// Copy caps from this to new player
proto.reviveCaps();
var protoCapSentinel = proto.getCapability(SENTINEL).resolve();
protoCapSentinel.ifPresent(protoSentinel -> {
var capSentinel = player.getCapability(SENTINEL);
capSentinel.ifPresent(sentinel -> {
sentinel.hasSentinel = protoSentinel.hasSentinel;
sentinel.position = protoSentinel.position;
sentinel.extendsRange = protoSentinel.extendsRange;
});
var proto = evt.getOriginal();
// Copy harness data from this to new player
player.getPersistentData().put(ItemWand.TAG_PATTERNS,
proto.getPersistentData().getList(ItemWand.TAG_PATTERNS, Tag.TAG_COMPOUND));
player.getPersistentData().put(ItemWand.TAG_HARNESS,
proto.getPersistentData().getCompound(ItemWand.TAG_HARNESS));
// Copy caps from this to new player
proto.reviveCaps();
var protoCapSentinel = proto.getCapability(SENTINEL).resolve();
protoCapSentinel.ifPresent(protoSentinel -> {
var capSentinel = player.getCapability(SENTINEL);
capSentinel.ifPresent(sentinel -> {
sentinel.hasSentinel = protoSentinel.hasSentinel;
sentinel.position = protoSentinel.position;
sentinel.extendsRange = protoSentinel.extendsRange;
sentinel.dimension = protoSentinel.dimension;
});
var protoCapColor = proto.getCapability(PREFERRED_COLORIZER).resolve();
protoCapColor.ifPresent(protoColorizer -> {
var capColorizer = player.getCapability(PREFERRED_COLORIZER);
capColorizer.ifPresent(colorizer -> {
colorizer.colorizer = protoColorizer.colorizer;
});
});
var protoCapColor = proto.getCapability(PREFERRED_COLORIZER).resolve();
protoCapColor.ifPresent(protoColorizer -> {
var capColorizer = player.getCapability(PREFERRED_COLORIZER);
capColorizer.ifPresent(colorizer -> {
colorizer.colorizer = protoColorizer.colorizer;
});
proto.invalidateCaps();
}
});
proto.invalidateCaps();
}
@SubscribeEvent

View file

@ -37,9 +37,7 @@ public class HexMessages {
MsgColorizerUpdateAck::deserialize, MsgColorizerUpdateAck::handle);
NETWORK.registerMessage(messageIdx++, MsgCastParticleAck.class, MsgCastParticleAck::serialize,
MsgCastParticleAck::deserialize, MsgCastParticleAck::handle);
NETWORK.registerMessage(messageIdx++, MsgStackRequestSyn.class, MsgStackRequestSyn::serialize,
MsgStackRequestSyn::deserialize, MsgStackRequestSyn::handle);
NETWORK.registerMessage(messageIdx++, MsgStackRequestAck.class, MsgStackRequestAck::serialize,
MsgStackRequestAck::deserialize, MsgStackRequestAck::handle);
NETWORK.registerMessage(messageIdx++, MsgOpenSpellGuiAck.class, MsgOpenSpellGuiAck::serialize,
MsgOpenSpellGuiAck::deserialize, MsgOpenSpellGuiAck::handle);
}
}

View file

@ -1,11 +1,9 @@
package at.petrak.hexcasting.common.network;
import at.petrak.hexcasting.common.casting.CastingContext;
import at.petrak.hexcasting.common.casting.CastingHarness;
import at.petrak.hexcasting.common.casting.ResolvedPattern;
import at.petrak.hexcasting.common.casting.ResolvedPatternValidity;
import at.petrak.hexcasting.common.casting.*;
import at.petrak.hexcasting.common.items.ItemWand;
import at.petrak.hexcasting.common.lib.HexSounds;
import at.petrak.hexcasting.hexmath.HexCoord;
import at.petrak.hexcasting.hexmath.HexPattern;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.CompoundTag;
@ -55,16 +53,35 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
if (sender != null) {
var held = sender.getItemInHand(this.handUsed);
if (held.getItem() instanceof ItemWand) {
boolean autoFail = false;
if (!resolvedPatterns.isEmpty()) {
var allPoints = new ArrayList<HexCoord>();
for (int i = 0; i < resolvedPatterns.size() - 1; i++) {
ResolvedPattern pat = resolvedPatterns.get(i);
allPoints.addAll(pat.getPattern().positions(pat.getOrigin()));
}
var currentResolvedPattern = resolvedPatterns.get(resolvedPatterns.size() - 1);
var currentSpellPoints = currentResolvedPattern.getPattern().positions(currentResolvedPattern.getOrigin());
if (currentSpellPoints.stream().anyMatch(allPoints::contains))
autoFail = true;
}
var ctx = new CastingContext(sender, this.handUsed);
var tag = held.getOrCreateTag();
var tag = sender.getPersistentData();
var harness = CastingHarness.DeserializeFromNBT(tag.getCompound(ItemWand.TAG_HARNESS), ctx);
var clientInfo = harness.executeNewPattern(this.pattern, sender.getLevel());
ControllerInfo clientInfo;
if (autoFail) {
clientInfo = new ControllerInfo(false, harness.getStack().isEmpty(), true, harness.generateDescs());
} else {
clientInfo = harness.executeNewPattern(this.pattern, sender.getLevel());
if (clientInfo.getWasSpellCast()) {
sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(),
HexSounds.ACTUALLY_CAST.get(), SoundSource.PLAYERS, 1f,
1f + ((float) Math.random() - 0.5f) * 0.2f);
if (clientInfo.getWasSpellCast()) {
sender.level.playSound(null, sender.getX(), sender.getY(), sender.getZ(),
HexSounds.ACTUALLY_CAST.get(), SoundSource.PLAYERS, 1f,
1f + ((float) Math.random() - 0.5f) * 0.2f);
}
}
ListTag patterns = new ListTag();
@ -90,7 +107,7 @@ public record MsgNewSpellPatternSyn(InteractionHand handUsed, HexPattern pattern
tag.put(ItemWand.TAG_PATTERNS, patterns);
HexMessages.getNetwork()
.send(PacketDistributor.PLAYER.with(() -> sender), new MsgNewSpellPatternAck(clientInfo));
.send(PacketDistributor.PLAYER.with(() -> sender), new MsgNewSpellPatternAck(clientInfo));
}
}
});

View file

@ -1,10 +1,12 @@
package at.petrak.hexcasting.common.network;
import at.petrak.hexcasting.client.gui.GuiSpellcasting;
import at.petrak.hexcasting.common.casting.ResolvedPattern;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent;
@ -16,23 +18,38 @@ import java.util.function.Supplier;
/**
* Sent server->client when the player opens the spell gui to request the server provide the current stack.
*/
public record MsgStackRequestAck(List<Component> components) {
public record MsgOpenSpellGuiAck(InteractionHand hand, List<ResolvedPattern> patterns, List<Component> components) {
public static MsgStackRequestAck deserialize(ByteBuf buffer) {
public static MsgOpenSpellGuiAck deserialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
var hand = InteractionHand.values()[buf.readInt()];
var patternsLen = buf.readInt();
var patterns = new ArrayList<ResolvedPattern>(patternsLen);
for (int i = 0; i < patternsLen; i++) {
patterns.add(ResolvedPattern.DeserializeFromNBT(buf.readAnySizeNbt()));
}
var descsLen = buf.readInt();
var desc = new ArrayList<Component>(descsLen);
for (int i = 0; i < descsLen; i++) {
desc.add(buf.readComponent());
}
return new MsgStackRequestAck(desc);
return new MsgOpenSpellGuiAck(hand, patterns, desc);
}
public void serialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
buf.writeInt(this.hand.ordinal());
buf.writeInt(this.patterns.size());
for (var pattern : this.patterns) {
buf.writeNbt(pattern.serializeToNBT());
}
buf.writeInt(this.components.size());
for (var desc : this.components) {
buf.writeComponent(desc);
@ -43,10 +60,7 @@ public record MsgStackRequestAck(List<Component> components) {
ctx.get().enqueueWork(() ->
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
var mc = Minecraft.getInstance();
var screen = Minecraft.getInstance().screen;
if (screen instanceof GuiSpellcasting spellGui) {
spellGui.recvStackUpdate(this.components);
}
mc.setScreen(new GuiSpellcasting(hand, patterns, components));
})
);
ctx.get().setPacketHandled(true);

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

@ -9,6 +9,7 @@ import io.netty.buffer.ByteBuf;
import net.minecraft.ChatFormatting;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
@ -63,9 +64,14 @@ public record MsgShiftScrollSyn(InteractionHand hand, double scrollDelta, boolea
MutableComponent component;
if (hand == InteractionHand.OFF_HAND && stack.hasCustomHoverName()) {
component = new TranslatableComponent("hexcasting.tooltip.spellbook.page_with_name", newIdx, len, stack.getHoverName());
component = new TranslatableComponent("hexcasting.tooltip.spellbook.page_with_name",
new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE),
new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE),
stack.getHoverName());
} else {
component = new TranslatableComponent("hexcasting.tooltip.spellbook.page", newIdx, len);
component = new TranslatableComponent("hexcasting.tooltip.spellbook.page",
new TextComponent(String.valueOf(newIdx)).withStyle(ChatFormatting.WHITE),
new TextComponent(String.valueOf(len)).withStyle(ChatFormatting.WHITE));
}
sender.displayClientMessage(component.withStyle(ChatFormatting.GRAY), true);

View file

@ -1,49 +0,0 @@
package at.petrak.hexcasting.common.network;
import at.petrak.hexcasting.common.casting.CastingContext;
import at.petrak.hexcasting.common.casting.CastingHarness;
import at.petrak.hexcasting.common.items.ItemWand;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.PacketDistributor;
import java.util.function.Supplier;
/**
* Sent client->server when the player opens the spell GUI.
* Server will send back a MsgStackRequestAck packet
*/
public record MsgStackRequestSyn(InteractionHand handUsed) {
public static MsgStackRequestSyn deserialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
var hand = InteractionHand.values()[buf.readInt()];
return new MsgStackRequestSyn(hand);
}
public void serialize(ByteBuf buffer) {
var buf = new FriendlyByteBuf(buffer);
buf.writeInt(this.handUsed.ordinal());
}
public void handle(Supplier<NetworkEvent.Context> networkCtx) {
networkCtx.get().enqueueWork(() -> {
ServerPlayer sender = networkCtx.get().getSender();
if (sender != null) {
var held = sender.getItemInHand(this.handUsed);
if (held.getItem() instanceof ItemWand) {
var ctx = new CastingContext(sender, this.handUsed);
var tag = held.getOrCreateTag();
var harness = CastingHarness.DeserializeFromNBT(tag.getCompound(ItemWand.TAG_HARNESS), ctx);
HexMessages.getNetwork()
.send(PacketDistributor.PLAYER.with(() -> sender), new MsgStackRequestAck(harness.generateDescs()));
}
}
});
networkCtx.get().setPacketHandled(true);
}
}

View file

@ -14,11 +14,11 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AmethystShardReducerModifier extends LootModifier {
private final int delta;
private final double modifier;
public AmethystShardReducerModifier(int delta, LootItemCondition[] conditions) {
public AmethystShardReducerModifier(double modifier, LootItemCondition[] conditions) {
super(conditions);
this.delta = delta;
this.modifier = modifier;
}
@NotNull
@ -26,7 +26,7 @@ public class AmethystShardReducerModifier extends LootModifier {
protected List<ItemStack> doApply(List<ItemStack> generatedLoot, LootContext context) {
for (var stack : generatedLoot) {
if (stack.is(Items.AMETHYST_SHARD)) {
stack.grow(this.delta);
stack.shrink((int) (stack.getCount() * modifier));
}
}
return generatedLoot;
@ -36,14 +36,14 @@ public class AmethystShardReducerModifier extends LootModifier {
@Override
public AmethystShardReducerModifier read(ResourceLocation location, JsonObject json,
LootItemCondition[] conditions) {
var delta = GsonHelper.getAsInt(json, "delta");
return new AmethystShardReducerModifier(delta, conditions);
var modifier = GsonHelper.getAsDouble(json, "modifier");
return new AmethystShardReducerModifier(modifier, conditions);
}
@Override
public JsonObject write(AmethystShardReducerModifier instance) {
var obj = this.makeConditions(instance.conditions);
obj.addProperty("delta", instance.delta);
obj.addProperty("modifier", instance.modifier);
return obj;
}
}

View file

@ -278,6 +278,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",