HexCasting/Common/src/main/java/at/petrak/hexcasting/api/casting/iota/Iota.java

99 lines
3.5 KiB
Java

package at.petrak.hexcasting.api.casting.iota;
import at.petrak.hexcasting.api.casting.eval.CastResult;
import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType;
import at.petrak.hexcasting.api.casting.eval.sideeffects.OperatorSideEffect;
import at.petrak.hexcasting.api.casting.eval.vm.CastingVM;
import at.petrak.hexcasting.api.casting.eval.vm.SpellContinuation;
import at.petrak.hexcasting.api.casting.math.HexDir;
import at.petrak.hexcasting.api.casting.math.HexPattern;
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
import at.petrak.hexcasting.api.casting.mishaps.MishapUnescapedValue;
import at.petrak.hexcasting.common.lib.hex.HexEvalSounds;
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public abstract class Iota {
@NotNull
protected final Object payload;
@NotNull
protected final IotaType<?> type;
protected Iota(@NotNull IotaType<?> type, @NotNull Object payload) {
this.type = type;
this.payload = payload;
}
public @NotNull IotaType<?> getType() {
return this.type;
}
abstract public boolean isTruthy();
/**
* Compare this to another object, within a tolerance.
*/
abstract protected boolean toleratesOther(Iota that);
/**
* Serialize this under the {@code data} tag.
* <p>
* You probably don't want to call this directly; use {@link IotaType#serialize}.
*/
abstract public @NotNull Tag serialize();
/**
* This method is called when this iota is executed (i.e. Hermes is run on a list containing it, unescaped).
* By default it will return a {@link CastResult} indicating an error has occurred.
*/
public @NotNull CastResult execute(CastingVM vm, ServerLevel world, SpellContinuation continuation) {
return new CastResult(
continuation,
null,
List.of(
new OperatorSideEffect.DoMishap(
new MishapUnescapedValue(this),
new Mishap.Context(new HexPattern(HexDir.WEST, List.of()), null)
)
), // Should never matter
ResolvedPatternType.INVALID,
HexEvalSounds.MISHAP
);
}
/**
* This method is called to determine whether the iota is above the max serialisation depth/serialisation count limits. It should return every "iota" that is a subelement of this iota.
* For example, if you implemented a Map<Iota, Iota>, then it should be an iterable over the keys *and* values of the map. If you implemented a typed List<Double> iota for some reason, it would
* probably be a good idea to supply an iterable over those doubles mapped to double iotas.
*/
public @Nullable Iterable<Iota> subIotas() {
return null;
}
public Component display() {
return this.type.display(this.serialize());
}
/**
* Helper method to see if two iotas have the same type.
*/
public static boolean typesMatch(Iota a, Iota b) {
var resA = HexIotaTypes.REGISTRY.getKey(a.getType());
var resB = HexIotaTypes.REGISTRY.getKey(b.getType());
return resA != null && resA.equals(resB);
}
/**
* Helper method to see if either iota tolerates the other.
*/
public static boolean tolerates(Iota a, Iota b) {
return a.toleratesOther(b) || b.toleratesOther(a);
}
}