mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
Observe spawn protection and mob griefing rules when trying to apply spells that affect blocks
This commit is contained in:
parent
c31eba5f04
commit
6e24ca9c6f
7 changed files with 25 additions and 13 deletions
|
@ -15,8 +15,10 @@ import com.minelittlepony.unicopia.util.VecHelper;
|
|||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
|
@ -58,6 +60,13 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
|
|||
return getEntity().getBlockPos();
|
||||
}
|
||||
|
||||
default boolean canModifyAt(BlockPos pos) {
|
||||
if (getMaster() instanceof PlayerEntity) {
|
||||
return !getWorld().canPlayerModifyAt((PlayerEntity)getMaster(), pos);
|
||||
}
|
||||
return getWorld().getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING);
|
||||
}
|
||||
|
||||
default void playSound(SoundEvent sound, float volume, float pitch) {
|
||||
getWorld().playSound(null, getEntity().getX(), getEntity().getY(), getEntity().getZ(), sound, getEntity().getSoundCategory(), volume, pitch);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class CatapultSpell extends AbstractSpell implements ProjectileSpell {
|
|||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (!projectile.isClient()) {
|
||||
if (!projectile.isClient() && projectile.canModifyAt(pos)) {
|
||||
createBlockEntity(projectile.world, pos, e -> apply(projectile, e));
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,9 @@ public class CatapultSpell extends AbstractSpell implements ProjectileSpell {
|
|||
EntityHitResult result = (EntityHitResult)ray;
|
||||
Optional.ofNullable(result.getEntity()).ifPresent(apply);
|
||||
} else if (ray.getType() == HitResult.Type.BLOCK) {
|
||||
createBlockEntity(caster.getWorld(), ((BlockHitResult)ray).getBlockPos(), apply);
|
||||
if (caster.canModifyAt(((BlockHitResult)ray).getBlockPos())) {
|
||||
createBlockEntity(caster.getWorld(), ((BlockHitResult)ray).getBlockPos(), apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import net.minecraft.nbt.NbtCompound;
|
|||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
/**
|
||||
|
@ -135,7 +136,7 @@ public class DarkVortexSpell extends AttractiveSpell {
|
|||
if (radius > 5) {
|
||||
Vec3d origin = getOrigin(source);
|
||||
PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius)).forEach(i -> {
|
||||
if (!source.getWorld().getFluidState(i).isEmpty()) {
|
||||
if (!canAffect(source, i)) {
|
||||
return;
|
||||
}
|
||||
if (source.getOrigin().isWithinDistance(i, getEventHorizonRadius())) {
|
||||
|
@ -153,6 +154,12 @@ public class DarkVortexSpell extends AttractiveSpell {
|
|||
return super.applyEntities(source);
|
||||
}
|
||||
|
||||
protected boolean canAffect(Caster<?> source, BlockPos pos) {
|
||||
return source.canModifyAt(pos)
|
||||
&& source.getWorld().getFluidState(pos).isEmpty()
|
||||
&& source.getWorld().getBlockState(pos).getHardness(source.getWorld(), pos) >= 0;
|
||||
}
|
||||
|
||||
// 1. force decreases with distance: distance scale 1 -> 0
|
||||
// 2. max force (at dist 0) is taken from accumulated mass
|
||||
// 3. force reaches 0 at distance of drawDropOffRange
|
||||
|
@ -226,9 +233,3 @@ public class DarkVortexSpell extends AttractiveSpell {
|
|||
accumulatedMass = compound.getFloat("accumulatedMass");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public class FireSpell extends AbstractAreaEffectSpell implements ProjectileSpel
|
|||
}
|
||||
|
||||
return PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, Math.max(0, 4 + getTraits().get(Trait.POWER)))).reduce(false,
|
||||
(r, i) -> applyBlocks(source.getWorld(), i),
|
||||
(r, i) -> source.canModifyAt(i) && applyBlocks(source.getWorld(), i),
|
||||
(a, b) -> a || b)
|
||||
|| applyEntities(null, source.getWorld(), source.getOriginVector());
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class IceSpell extends AbstractSpell {
|
|||
|
||||
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range)
|
||||
.forEach(i -> {
|
||||
if (applyBlockSingle(owner, source.getWorld(), i)) {
|
||||
if (source.canModifyAt(i) && applyBlockSingle(owner, source.getWorld(), i)) {
|
||||
ParticleUtils.spawnParticle(source.getWorld(), ParticleTypes.SPLASH, new Vec3d(
|
||||
i.getX() + source.getWorld().random.nextFloat(),
|
||||
i.getY() + 1,
|
||||
|
|
|
@ -44,7 +44,7 @@ public class InfernoSpell extends FireSpell {
|
|||
for (int i = 0; i < radius; i++) {
|
||||
BlockPos pos = new BlockPos(shape.computePoint(w.random).add(origin));
|
||||
|
||||
if (converter.convert(w, pos)) {
|
||||
if (source.canModifyAt(pos) && converter.convert(w, pos)) {
|
||||
playEffect(w, pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class ScorchSpell extends FireSpell {
|
|||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
BlockPos pos = PosHelper.findSolidGroundAt(source.getWorld(), source.getOrigin(), source.getPhysics().getGravitySignum());
|
||||
|
||||
if (StateMaps.FIRE_AFFECTED.convert(source.getWorld(), pos)) {
|
||||
if (source.canModifyAt(pos) && StateMaps.FIRE_AFFECTED.convert(source.getWorld(), pos)) {
|
||||
source.spawnParticles(new Sphere(false, Math.max(1, getTraits().get(Trait.POWER))), 5, p -> {
|
||||
source.addParticle(ParticleTypes.SMOKE, PosHelper.offset(p, pos), Vec3d.ZERO);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue