block up mishap envs
This commit is contained in:
parent
50554d5bf7
commit
2233c7697d
15 changed files with 146 additions and 89 deletions
|
@ -2,7 +2,6 @@ package at.petrak.hexcasting.api.casting.eval;
|
|||
|
||||
import at.petrak.hexcasting.api.casting.ParticleSpray;
|
||||
import at.petrak.hexcasting.api.casting.PatternShapeMatch;
|
||||
import at.petrak.hexcasting.api.casting.eval.SpellCircleContext;
|
||||
import at.petrak.hexcasting.api.casting.eval.sideeffects.EvalSound;
|
||||
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
|
||||
import at.petrak.hexcasting.api.casting.mishaps.MishapDisallowedSpell;
|
||||
|
@ -10,7 +9,6 @@ import at.petrak.hexcasting.api.casting.mishaps.MishapEntityTooFarAway;
|
|||
import at.petrak.hexcasting.api.casting.mishaps.MishapLocationTooFarAway;
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer;
|
||||
import at.petrak.hexcasting.api.mod.HexConfig;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
@ -50,23 +48,22 @@ public abstract class CastingEnvironment {
|
|||
* Get the caster. Might be null!
|
||||
* <p>
|
||||
* Implementations should NOT rely on this in general, use the methods on this class instead.
|
||||
* This is mostly for things like mishaps.
|
||||
* This is mostly for spells (flight, etc)
|
||||
*/
|
||||
@Nullable
|
||||
public abstract ServerPlayer getCaster();
|
||||
|
||||
/**
|
||||
* Get an interface used to do mishaps
|
||||
*/
|
||||
public abstract MishapEnvironment getMishapEnvironment();
|
||||
|
||||
/**
|
||||
* Get the sound that this I/O module makes.
|
||||
* <p>
|
||||
*/
|
||||
public abstract EvalSound getSoundType();
|
||||
|
||||
/**
|
||||
* Get the spell circle running this cast. Might be null if not casting from a spell circle!
|
||||
*/
|
||||
@Nullable
|
||||
public abstract SpellCircleContext getSpellCircle();
|
||||
|
||||
/**
|
||||
* If something about this ARE itself is invalid, mishap.
|
||||
* <p>
|
||||
|
@ -134,9 +131,11 @@ public abstract class CastingEnvironment {
|
|||
throw new MishapLocationTooFarAway(vec, "too_far");
|
||||
}
|
||||
}
|
||||
|
||||
public final void assertVecInRange(BlockPos vec) throws MishapLocationTooFarAway {
|
||||
this.assertVecInRange(new Vec3(vec.x(), vec.y(), vec.z()));
|
||||
this.assertVecInRange(new Vec3(vec.getX(), vec.getY(), vec.getZ()));
|
||||
}
|
||||
|
||||
public final boolean canEditBlockAt(BlockPos vec) {
|
||||
// TODO winfy: fill this in
|
||||
return false;
|
||||
|
@ -200,9 +199,15 @@ public abstract class CastingEnvironment {
|
|||
}
|
||||
|
||||
public static record HeldItemInfo(ItemStack stack, InteractionHand hand) {
|
||||
public ItemStack component1() { return stack; }
|
||||
public InteractionHand component2() { return hand; }
|
||||
public ItemStack component1() {
|
||||
return stack;
|
||||
}
|
||||
|
||||
public InteractionHand component2() {
|
||||
return hand;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the slot from which to take blocks and items.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package at.petrak.hexcasting.api.casting.eval;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Kinda like {@link CastingEnvironment} but for executing mishaps.
|
||||
* <p>
|
||||
* To avoid horrible O(mn) scope problems we offer a set of stock bad effects.
|
||||
* The player is exposed nullably if you like though.
|
||||
*/
|
||||
public abstract class MishapEnvironment {
|
||||
@Nullable
|
||||
protected final ServerPlayer caster;
|
||||
protected final ServerLevel world;
|
||||
|
||||
protected MishapEnvironment(ServerLevel world, @Nullable ServerPlayer caster) {
|
||||
this.caster = caster;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public abstract void yeetHeldItemsTowards(Vec3 targetPos);
|
||||
|
||||
public abstract void dropHeldItems();
|
||||
|
||||
public abstract void drown();
|
||||
|
||||
public abstract void damage(float healthProportion);
|
||||
|
||||
public abstract void removeXp(int amount);
|
||||
|
||||
public abstract void blind(int ticks);
|
||||
|
||||
protected void yeetItem(ItemStack stack, Vec3 srcPos, Vec3 delta) {
|
||||
var entity = new ItemEntity(
|
||||
this.world,
|
||||
srcPos.x, srcPos.y, srcPos.z,
|
||||
stack,
|
||||
delta.x + (Math.random() - 0.5) * 0.1,
|
||||
delta.y + (Math.random() - 0.5) * 0.1,
|
||||
delta.z + (Math.random() - 0.5) * 0.1
|
||||
);
|
||||
entity.setPickUpDelay(40);
|
||||
this.world.addWithUUID(entity);
|
||||
}
|
||||
}
|
|
@ -128,7 +128,7 @@ class CastingVM(var image: CastingImage, val env: CastingEnvironment) {
|
|||
null,
|
||||
listOf(
|
||||
OperatorSideEffect.DoMishap(
|
||||
MishapError(exception),
|
||||
MishapInternalException(exception),
|
||||
Mishap.Context(
|
||||
(iota as? PatternIota)?.pattern ?: HexPattern(HexDir.WEST),
|
||||
null
|
||||
|
|
|
@ -13,11 +13,8 @@ import at.petrak.hexcasting.ktxt.*
|
|||
import net.minecraft.Util
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.InteractionHand
|
||||
import net.minecraft.world.damagesource.DamageSource
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.item.ItemEntity
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
@ -69,40 +66,6 @@ abstract class Mishap : Throwable() {
|
|||
protected fun actionName(name: Component?): Component =
|
||||
name ?: "hexcasting.spell.null".asTranslatedComponent.lightPurple
|
||||
|
||||
protected fun yeetHeldItemsTowards(env: CastingEnvironment, targetPos: Vec3) {
|
||||
// Knock the player's items out of their hands
|
||||
val items = mutableListOf<ItemStack>()
|
||||
val caster = env.caster
|
||||
if (caster != null) {
|
||||
// FIXME: handle null caster case
|
||||
return
|
||||
}
|
||||
for (hand in InteractionHand.values()) {
|
||||
items.add(caster.getItemInHand(hand).copy())
|
||||
caster.setItemInHand(hand, ItemStack.EMPTY)
|
||||
}
|
||||
|
||||
val pos = caster.position()
|
||||
val delta = targetPos.subtract(pos).normalize().scale(0.5)
|
||||
|
||||
for (item in items) {
|
||||
yeetItem(env, item, pos, delta)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun yeetItem(env: CastingEnvironment, stack: ItemStack, pos: Vec3, delta: Vec3) {
|
||||
val entity = ItemEntity(
|
||||
env.world,
|
||||
pos.x, pos.y, pos.z,
|
||||
stack,
|
||||
delta.x + (Math.random() - 0.5) * 0.1,
|
||||
delta.y + (Math.random() - 0.5) * 0.1,
|
||||
delta.z + (Math.random() - 0.5) * 0.1
|
||||
)
|
||||
entity.setPickUpDelay(40)
|
||||
env.world.addWithUUID(entity)
|
||||
}
|
||||
|
||||
protected fun blockAtPos(ctx: CastingEnvironment, pos: BlockPos): Component {
|
||||
return ctx.world.getBlockState(pos).block.name
|
||||
}
|
||||
|
@ -111,7 +74,7 @@ abstract class Mishap : Throwable() {
|
|||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
public fun trulyHurt(entity: LivingEntity, source: DamageSource, amount: Float) {
|
||||
fun trulyHurt(entity: LivingEntity, source: DamageSource, amount: Float) {
|
||||
entity.setHurtWithStamp(source, entity.level.gameTime)
|
||||
|
||||
val targetHealth = entity.health - amount
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package at.petrak.hexcasting.api.casting.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||
import at.petrak.hexcasting.api.casting.ParticleSpray
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.entity.Mob
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
@ -15,6 +15,7 @@ class MishapBadBrainsweep(val mob: Mob, val pos: BlockPos) : Mishap() {
|
|||
dyeColor(DyeColor.GREEN)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
// TODO: you can just instakill things with this
|
||||
trulyHurt(mob, HexDamageSources.overcastDamageFrom(ctx.caster), mob.health)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class MishapBadEntity(val entity: Entity, val wanted: Component) : Mishap() {
|
|||
dyeColor(DyeColor.BROWN)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
yeetHeldItemsTowards(ctx, entity.position())
|
||||
ctx.mishapEnvironment.yeetHeldItemsTowards(entity.position())
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) =
|
||||
|
|
|
@ -14,8 +14,7 @@ class MishapBadOffhandItem(val item: ItemStack, val hand: InteractionHand, val w
|
|||
dyeColor(DyeColor.BROWN)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
// FIXME: Missing implementation in mishap
|
||||
//yeetHeldItem(ctx, hand)
|
||||
ctx.mishapEnvironment.dropHeldItems()
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item.isEmpty)
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package at.petrak.hexcasting.api.casting.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.misc.HexDamageSources
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.iota.DoubleIota
|
||||
import at.petrak.hexcasting.api.casting.iota.GarbageIota
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.iota.Vec3Iota
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.utils.asTranslatedComponent
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
@ -19,11 +18,7 @@ class MishapDivideByZero(val operand1: Component, val operand2: Component, val s
|
|||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
stack.add(GarbageIota())
|
||||
val caster = ctx.caster
|
||||
if (caster != null) {
|
||||
// FIXME case where caster is null
|
||||
trulyHurt(caster, HexDamageSources.OVERCAST, caster.health / 2)
|
||||
}
|
||||
ctx.mishapEnvironment.damage(0.5f)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) =
|
||||
|
|
|
@ -12,8 +12,7 @@ class MishapEntityTooFarAway(val entity: Entity) : Mishap() {
|
|||
dyeColor(DyeColor.PINK)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
// Knock the player's items out of their hands
|
||||
yeetHeldItemsTowards(ctx, entity.position())
|
||||
ctx.mishapEnvironment.yeetHeldItemsTowards(entity.position())
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component =
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package at.petrak.hexcasting.api.casting.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapEvalTooDeep : Mishap() {
|
||||
|
@ -10,11 +10,7 @@ class MishapEvalTooDeep : Mishap() {
|
|||
dyeColor(DyeColor.BLUE)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
// FIXME what if caster is null
|
||||
val caster = ctx.caster
|
||||
if (caster != null) {
|
||||
caster.airSupply -= 290
|
||||
}
|
||||
ctx.mishapEnvironment.drown()
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) =
|
||||
|
|
|
@ -5,7 +5,7 @@ import at.petrak.hexcasting.api.casting.iota.Iota
|
|||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
class MishapError(val exception: Exception) : Mishap() {
|
||||
class MishapInternalException(val exception: Exception) : Mishap() {
|
||||
override fun accentColor(ctx: CastingEnvironment, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.BLACK)
|
||||
|
|
@ -13,7 +13,7 @@ class MishapLocationTooFarAway(val location: Vec3, val type: String = "too_far")
|
|||
dyeColor(DyeColor.MAGENTA)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
yeetHeldItemsTowards(ctx, location)
|
||||
ctx.mishapEnvironment.yeetHeldItemsTowards(this.location)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component =
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package at.petrak.hexcasting.api.casting.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
|
@ -11,11 +11,7 @@ class MishapNoAkashicRecord(val pos: BlockPos) : Mishap() {
|
|||
dyeColor(DyeColor.PURPLE)
|
||||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
val caster = ctx.caster
|
||||
if (caster != null) {
|
||||
// FIXME: handle null case
|
||||
caster.giveExperiencePoints(-100)
|
||||
}
|
||||
ctx.mishapEnvironment.removeXp(100)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) =
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package at.petrak.hexcasting.api.casting.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
|
||||
import at.petrak.hexcasting.api.casting.iota.EntityIota
|
||||
import at.petrak.hexcasting.api.casting.iota.Iota
|
||||
import at.petrak.hexcasting.api.casting.iota.ListIota
|
||||
import net.minecraft.world.effect.MobEffectInstance
|
||||
import net.minecraft.world.effect.MobEffects
|
||||
import at.petrak.hexcasting.api.misc.FrozenColorizer
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.DyeColor
|
||||
|
||||
|
@ -19,11 +17,7 @@ class MishapOthersName(val confidant: Player) : Mishap() {
|
|||
|
||||
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList<Iota>) {
|
||||
val seconds = if (this.confidant == ctx.caster) 5 else 60;
|
||||
val caster = ctx.caster
|
||||
if (caster != null) {
|
||||
// FIXME: handle null caster case
|
||||
caster.addEffect(MobEffectInstance(MobEffects.BLINDNESS, seconds * 20))
|
||||
}
|
||||
ctx.mishapEnvironment.blind(seconds * 20)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) =
|
||||
|
|
59
Common/src/main/java/at/petrak/hexcasting/common/casting/env/PlayerBasedMishapEnv.java
vendored
Normal file
59
Common/src/main/java/at/petrak/hexcasting/common/casting/env/PlayerBasedMishapEnv.java
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
package at.petrak.hexcasting.common.casting.env;
|
||||
|
||||
import at.petrak.hexcasting.api.casting.eval.MishapEnvironment;
|
||||
import at.petrak.hexcasting.api.casting.mishaps.Mishap;
|
||||
import at.petrak.hexcasting.api.misc.HexDamageSources;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class PlayerBasedMishapEnv extends MishapEnvironment {
|
||||
public PlayerBasedMishapEnv(ServerPlayer player) {
|
||||
super(player.getLevel(), player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void yeetHeldItemsTowards(Vec3 targetPos) {
|
||||
var pos = this.caster.position();
|
||||
var delta = targetPos.subtract(pos).normalize().scale(0.5);
|
||||
|
||||
for (var hand : InteractionHand.values()) {
|
||||
var stack = this.caster.getItemInHand(hand);
|
||||
this.caster.setItemInHand(hand, ItemStack.EMPTY);
|
||||
this.yeetItem(stack, pos, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropHeldItems() {
|
||||
var delta = this.caster.getLookAngle();
|
||||
this.yeetHeldItemsTowards(this.caster.position().add(delta));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damage(float healthProportion) {
|
||||
Mishap.trulyHurt(this.caster, HexDamageSources.OVERCAST, this.caster.getHealth() * healthProportion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drown() {
|
||||
if (this.caster.getAirSupply() < 200) {
|
||||
this.caster.hurt(DamageSource.DROWN, 2f);
|
||||
}
|
||||
this.caster.setAirSupply(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeXp(int amount) {
|
||||
this.caster.giveExperiencePoints(-amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blind(int ticks) {
|
||||
this.caster.addEffect(new MobEffectInstance(MobEffects.BLINDNESS, ticks));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue