diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java
index 2a9440d6..b282d928 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/CastingEnvironment.java
@@ -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!
*
* 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.
*
*/
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.
*
@@ -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.
*/
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java
new file mode 100644
index 00000000..54699144
--- /dev/null
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/MishapEnvironment.java
@@ -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.
+ *
+ * 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);
+ }
+}
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt
index 27cc2008..15c57f3b 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/eval/vm/CastingVM.kt
@@ -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
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt
index 98b8ac90..92ee5a68 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/Mishap.kt
@@ -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()
- 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
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt
index cb8e7463..2553f4c7 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadBrainsweep.kt
@@ -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) {
+ // TODO: you can just instakill things with this
trulyHurt(mob, HexDamageSources.overcastDamageFrom(ctx.caster), mob.health)
}
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt
index 143be43e..6942ac1a 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadEntity.kt
@@ -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) {
- yeetHeldItemsTowards(ctx, entity.position())
+ ctx.mishapEnvironment.yeetHeldItemsTowards(entity.position())
}
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) =
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt
index 8cd78780..ba804ff4 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapBadOffhandItem.kt
@@ -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) {
- // FIXME: Missing implementation in mishap
- //yeetHeldItem(ctx, hand)
+ ctx.mishapEnvironment.dropHeldItems()
}
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context) = if (item.isEmpty)
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt
index be14215a..46b5e5be 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapDivideByZero.kt
@@ -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) {
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) =
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt
index 37cc1e98..b2d375c8 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEntityTooFarAway.kt
@@ -12,8 +12,7 @@ class MishapEntityTooFarAway(val entity: Entity) : Mishap() {
dyeColor(DyeColor.PINK)
override fun execute(ctx: CastingEnvironment, errorCtx: Context, stack: MutableList) {
- // 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 =
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooDeep.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooDeep.kt
index 9070c3ef..be522af6 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooDeep.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapEvalTooDeep.kt
@@ -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) {
- // 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) =
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapError.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt
similarity index 89%
rename from Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapError.kt
rename to Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt
index 8a5cec36..4c47ddad 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapError.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapInternalException.kt
@@ -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)
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationTooFarAway.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationTooFarAway.kt
index 5869754a..e79203d0 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationTooFarAway.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapLocationTooFarAway.kt
@@ -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) {
- yeetHeldItemsTowards(ctx, location)
+ ctx.mishapEnvironment.yeetHeldItemsTowards(this.location)
}
override fun errorMessage(ctx: CastingEnvironment, errorCtx: Context): Component =
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt
index b1addc1c..7eae838c 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapNoAkashicRecord.kt
@@ -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) {
- 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) =
diff --git a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt
index 15d68ce0..65380ca8 100644
--- a/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt
+++ b/Common/src/main/java/at/petrak/hexcasting/api/casting/mishaps/MishapOthersName.kt
@@ -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) {
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) =
diff --git a/Common/src/main/java/at/petrak/hexcasting/common/casting/env/PlayerBasedMishapEnv.java b/Common/src/main/java/at/petrak/hexcasting/common/casting/env/PlayerBasedMishapEnv.java
new file mode 100644
index 00000000..87c5fd12
--- /dev/null
+++ b/Common/src/main/java/at/petrak/hexcasting/common/casting/env/PlayerBasedMishapEnv.java
@@ -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));
+ }
+}