Skip to content

Commit

Permalink
Merge branch 'main' into inlinepatterns
Browse files Browse the repository at this point in the history
  • Loading branch information
SamsTheNerd authored Aug 16, 2024
2 parents cbe821b + de10fa6 commit 051c52f
Show file tree
Hide file tree
Showing 44 changed files with 308 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ default Iota emptyIota() {
* @return if the writing succeeded/would succeed
*/
boolean writeIota(@Nullable Iota iota, boolean simulate);

/**
* @return whether it is possible to write to this IotaHolder
*/
boolean writeable();
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ public ItemDelegatingEntityIotaHolder(Supplier<ItemStack> stackSupplier, Consume
return delegate == null ? null : delegate.readIotaTag();
}

@Override
public boolean writeable() {
var delegate = IXplatAbstractions.INSTANCE.findDataHolder(this.stackSupplier.get());
return delegate != null && delegate.writeable();
}

@Override
public boolean writeIota(@Nullable Iota datum, boolean simulate) {
var stacc = this.stackSupplier.get();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package at.petrak.hexcasting.api.advancements;

import com.google.gson.JsonElement;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.BuiltInExceptionProvider;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.advancements.critereon.MinMaxBounds;
import net.minecraft.util.GsonHelper;

import javax.annotation.Nullable;
import java.util.Objects;
import java.util.function.Function;

public class MinMaxLongs extends MinMaxBounds<Long> {
public static final MinMaxLongs ANY = new MinMaxLongs(null, null);
@Nullable
private final Long minSq;
@Nullable
private final Long maxSq;

private static MinMaxLongs create(StringReader reader, @Nullable Long min, @Nullable Long max) throws CommandSyntaxException {
if (min != null && max != null && min > max) {
throw ERROR_SWAPPED.createWithContext(reader);
} else {
return new MinMaxLongs(min, max);
}
}

@Nullable
private static Long squareOpt(@Nullable Long l) {
return l == null ? null : l * l;
}

private MinMaxLongs(@Nullable Long min, @Nullable Long max) {
super(min, max);
this.minSq = squareOpt(min);
this.maxSq = squareOpt(max);
}

public static MinMaxLongs exactly(long l) {
return new MinMaxLongs(l, l);
}

public static MinMaxLongs between(long min, long max) {
return new MinMaxLongs(min, max);
}

public static MinMaxLongs atLeast(long min) {
return new MinMaxLongs(min, null);
}

public static MinMaxLongs atMost(long max) {
return new MinMaxLongs(null, max);
}

public boolean matches(long l) {
if (this.min != null && this.min > l) {
return false;
} else {
return this.max == null || this.max >= l;
}
}

public boolean matchesSqr(long l) {
if (this.minSq != null && this.minSq > l) {
return false;
} else {
return this.maxSq == null || this.maxSq >= l;
}
}

public static MinMaxLongs fromJson(@Nullable JsonElement json) {
return fromJson(json, ANY, GsonHelper::convertToLong, MinMaxLongs::new);
}

public static MinMaxLongs fromReader(StringReader reader) throws CommandSyntaxException {
return fromReader(reader, (l) -> l);
}

public static MinMaxLongs fromReader(StringReader reader, Function<Long, Long> map) throws CommandSyntaxException {
BuiltInExceptionProvider builtInExceptions = CommandSyntaxException.BUILT_IN_EXCEPTIONS;
Objects.requireNonNull(builtInExceptions);
return fromReader(reader, MinMaxLongs::create, Long::parseLong, builtInExceptions::readerInvalidInt, map);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ public ResourceLocation getId() {
protected Instance createInstance(JsonObject json, ContextAwarePredicate predicate,
DeserializationContext context) {
return new Instance(predicate,
MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_SPENT)),
MinMaxBounds.Ints.fromJson(json.get(TAG_MEDIA_WASTED)));
MinMaxLongs.fromJson(json.get(TAG_MEDIA_SPENT)),
MinMaxLongs.fromJson(json.get(TAG_MEDIA_WASTED)));
}

public void trigger(ServerPlayer player, int mediaSpent, int mediaWasted) {
public void trigger(ServerPlayer player, long mediaSpent, long mediaWasted) {
super.trigger(player, inst -> inst.test(mediaSpent, mediaWasted));
}

public static class Instance extends AbstractCriterionTriggerInstance {
protected final MinMaxBounds.Ints mediaSpent;
protected final MinMaxBounds.Ints mediaWasted;
protected final MinMaxLongs mediaSpent;
protected final MinMaxLongs mediaWasted;

public Instance(ContextAwarePredicate predicate, MinMaxBounds.Ints mediaSpent,
MinMaxBounds.Ints mediaWasted) {
public Instance(ContextAwarePredicate predicate, MinMaxLongs mediaSpent,
MinMaxLongs mediaWasted) {
super(SpendMediaTrigger.ID, predicate);
this.mediaSpent = mediaSpent;
this.mediaWasted = mediaWasted;
Expand All @@ -56,7 +56,7 @@ public JsonObject serializeToJson(SerializationContext ctx) {
return json;
}

private boolean test(int mediaSpentIn, int mediaWastedIn) {
private boolean test(long mediaSpentIn, long mediaWastedIn) {
return this.mediaSpent.matches(mediaSpentIn) && this.mediaWasted.matches(mediaWastedIn);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ public boolean tick(BlockEntityAbstractImpetus impetus) {
var ctrl = executor.acceptControlFlow(this.currentImage, env, this.enteredFrom, this.currentPos,
executorBlockState, world);

if (env.getImpetus() == null)
return false; //the impetus got removed during the cast and no longer exists in the world. stop casting

if (ctrl instanceof ICircleComponent.ControlFlow.Stop) {
// acceptControlFlow should have already posted the error
halt = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import at.petrak.hexcasting.api.casting.ParticleSpray;
import at.petrak.hexcasting.api.casting.PatternShapeMatch;
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation;
import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell;
Expand Down Expand Up @@ -66,6 +67,8 @@ public final void triggerCreateEvent() {

protected Map<CastingEnvironmentComponent.Key<?>, @NotNull CastingEnvironmentComponent> componentMap = new HashMap<>();
private final List<PostExecution> postExecutions = new ArrayList<>();

private final List<PostCast> postCasts = new ArrayList<>();
private final List<ExtractMedia.Pre> preMediaExtract = new ArrayList<>();
private final List<ExtractMedia.Post> postMediaExtract = new ArrayList<>();

Expand Down Expand Up @@ -113,6 +116,8 @@ public <T extends CastingEnvironmentComponent> void addExtension(@NotNull T exte
componentMap.put(extension.getKey(), extension);
if (extension instanceof PostExecution postExecution)
postExecutions.add(postExecution);
if (extension instanceof PostCast postCast)
postCasts.add(postCast);
if (extension instanceof ExtractMedia extractMedia)
if (extension instanceof ExtractMedia.Pre pre) {
preMediaExtract.add(pre);
Expand All @@ -132,6 +137,8 @@ public void removeExtension(@NotNull CastingEnvironmentComponent.Key<?> key) {

if (extension instanceof PostExecution postExecution)
postExecutions.remove(postExecution);
if (extension instanceof PostCast postCast)
postCasts.remove(postCast);
if (extension instanceof ExtractMedia extractMedia)
if (extension instanceof ExtractMedia.Pre pre) {
preMediaExtract.remove(pre);
Expand Down Expand Up @@ -188,6 +195,14 @@ public void postExecution(CastResult result) {
postExecutionComponent.onPostExecution(result);
}

/**
* Do things after the whole cast is finished (i.e. every pattern to be executed has been executed).
*/
public void postCast(CastingImage image) {
for (var postCastComponent : postCasts)
postCastComponent.onPostCast(image);
}

public abstract Vec3 mishapSprayPos();

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.petrak.hexcasting.api.casting.eval;

import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
import net.minecraft.core.BlockPos;
import net.minecraft.world.phys.Vec3;

Expand All @@ -15,6 +16,13 @@ interface PostExecution extends CastingEnvironmentComponent {
void onPostExecution(CastResult result);
}

interface PostCast extends CastingEnvironmentComponent {
/**
* Do things after the whole cast is finished (i.e. every pattern to be executed has been executed).
*/
void onPostCast(CastingImage image);
}

interface ExtractMedia extends CastingEnvironmentComponent {
/**
* Receives the cost that is being extracted, should return the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ protected long extractMediaFromInventory(long costLeft, boolean allowOvercast) {
}

this.caster.awardStat(HexStatistics.MEDIA_USED, (int) (startCost - costLeft));
HexAdvancementTriggers.SPEND_MEDIA_TRIGGER.trigger(
this.caster,
startCost - costLeft,
costLeft < 0 ? -costLeft : 0
);

return costLeft;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import at.petrak.hexcasting.api.casting.eval.CastResult;
import at.petrak.hexcasting.api.casting.eval.ExecutionClientView;
import at.petrak.hexcasting.api.casting.eval.ResolvedPattern;
import at.petrak.hexcasting.api.casting.eval.vm.CastingImage;
import at.petrak.hexcasting.api.casting.iota.PatternIota;
import at.petrak.hexcasting.api.casting.math.HexCoord;
import at.petrak.hexcasting.api.casting.math.HexPattern;
import at.petrak.hexcasting.api.mod.HexStatistics;
import at.petrak.hexcasting.api.pigment.FrozenPigment;
import at.petrak.hexcasting.common.msgs.*;
Expand All @@ -19,10 +21,14 @@

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class StaffCastEnv extends PlayerBasedCastEnv {
private final InteractionHand castingHand;

private final Set<HexPattern> castPatterns = new HashSet<>();
private int soundsPlayed = 0;


public StaffCastEnv(ServerPlayer caster, InteractionHand castingHand) {
super(caster, castingHand);
Expand All @@ -35,22 +41,33 @@ public void postExecution(CastResult result) {
super.postExecution(result);

if (result.component1() instanceof PatternIota patternIota) {
var packet = new MsgNewSpiralPatternsS2C(
this.caster.getUUID(), List.of(patternIota.getPattern()), Integer.MAX_VALUE
);
IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet);
castPatterns.add(patternIota.getPattern());
}

// we always want to play this sound one at a time
var sound = result.getSound().sound();
if (sound != null) {
if (soundsPlayed < 100 && sound != null) { // TODO: Make configurable
var soundPos = this.caster.position();
this.world.playSound(null, soundPos.x, soundPos.y, soundPos.z,
sound, SoundSource.PLAYERS, 1f, 1f);
soundsPlayed++;
}
}

@Override
public void postCast(CastingImage image) {
super.postCast(image);

var packet = new MsgNewSpiralPatternsS2C(
this.caster.getUUID(), castPatterns.stream().toList(), Integer.MAX_VALUE
);
IXplatAbstractions.INSTANCE.sendPacketToPlayer(this.caster, packet);
IXplatAbstractions.INSTANCE.sendPacketTracking(this.caster, packet);

castPatterns.clear();
soundsPlayed = 0;
}

@Override
public long extractMediaEnvironment(long cost) {
if (this.caster.isCreative())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
val (stackDescs, ravenmind) = generateDescs()

val isStackClear = image.stack.isEmpty() && image.parenCount == 0 && !image.escapeNext && ravenmind == null

this.env.postCast(image)
return ExecutionClientView(isStackClear, lastResolutionType, stackDescs, ravenmind)
}

Expand Down Expand Up @@ -161,7 +163,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
*/
@Throws(MishapTooManyCloseParens::class)
private fun handleParentheses(iota: Iota): Pair<CastingImage, ResolvedPatternType>? {
val sig = (iota as? PatternIota)?.pattern?.anglesSignature()
val sig = (iota as? PatternIota)?.pattern?.angles

var displayDepth = this.image.parenCount

Expand All @@ -176,13 +178,13 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
} else {

when (sig) {
SpecialPatterns.CONSIDERATION.anglesSignature() -> {
SpecialPatterns.CONSIDERATION.angles -> {
this.image.copy(
escapeNext = true,
) to ResolvedPatternType.EVALUATED
}

SpecialPatterns.EVANITION.anglesSignature() -> {
SpecialPatterns.EVANITION.angles -> {
val newParens = this.image.parenthesized.toMutableList()
val last = newParens.removeLastOrNull()
val newParenCount = this.image.parenCount + if (last == null || last.escaped || last.iota !is PatternIota) 0 else when (last.iota.pattern) {
Expand All @@ -193,7 +195,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
this.image.copy(parenthesized = newParens, parenCount = newParenCount) to if (last == null) ResolvedPatternType.ERRORED else ResolvedPatternType.UNDONE
}

SpecialPatterns.INTROSPECTION.anglesSignature() -> {
SpecialPatterns.INTROSPECTION.angles -> {
// we have escaped the parens onto the stack; we just also record our count.
val newParens = this.image.parenthesized.toMutableList()
newParens.add(ParenthesizedIota(iota, false))
Expand All @@ -203,7 +205,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
) to if (this.image.parenCount == 0) ResolvedPatternType.EVALUATED else ResolvedPatternType.ESCAPED
}

SpecialPatterns.RETROSPECTION.anglesSignature() -> {
SpecialPatterns.RETROSPECTION.angles -> {
val newParenCount = this.image.parenCount - 1
displayDepth--
if (newParenCount == 0) {
Expand Down Expand Up @@ -246,19 +248,19 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
) to ResolvedPatternType.ESCAPED
} else {
when (sig) {
SpecialPatterns.CONSIDERATION.anglesSignature() -> {
SpecialPatterns.CONSIDERATION.angles -> {
this.image.copy(
escapeNext = true
) to ResolvedPatternType.EVALUATED
}

SpecialPatterns.INTROSPECTION.anglesSignature() -> {
SpecialPatterns.INTROSPECTION.angles -> {
this.image.copy(
parenCount = this.image.parenCount + 1
) to ResolvedPatternType.EVALUATED
}

SpecialPatterns.RETROSPECTION.anglesSignature() -> {
SpecialPatterns.RETROSPECTION.angles -> {
throw MishapTooManyCloseParens()
}

Expand Down
Loading

0 comments on commit 051c52f

Please sign in to comment.