fix conflicts
This commit is contained in:
commit
999def56ba
27 changed files with 259 additions and 163 deletions
|
@ -18,6 +18,6 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"delta": -2,
|
||||
"modifier": 0.5,
|
||||
"type": "hexcasting:amethyst_shard_reducer"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue