mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-07 22:16:44 +01:00
Simplify projectile delegate code
This commit is contained in:
parent
8e65a265f9
commit
89e8f0dccc
10 changed files with 39 additions and 47 deletions
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -20,6 +19,8 @@ import net.minecraft.nbt.NbtCompound;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public abstract class AbstractDelegatingSpell implements ProjectileSpell {
|
||||
private static final Function<Object, ProjectileSpell> PROJECTILE_SPELL = a -> a instanceof ProjectileSpell p ? p : null;
|
||||
private static final Function<Object, ProjectileDelegate> PROJECTILE_DELEGATE = a -> a instanceof ProjectileDelegate p ? p : null;
|
||||
|
||||
private boolean isDirty;
|
||||
|
||||
|
@ -57,6 +58,7 @@ public abstract class AbstractDelegatingSpell implements ProjectileSpell {
|
|||
public SpellTraits getTraits() {
|
||||
return getDelegates().stream().map(Spell::getTraits).reduce(SpellTraits.EMPTY, SpellTraits::union);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
|
@ -84,35 +86,27 @@ public abstract class AbstractDelegatingSpell implements ProjectileSpell {
|
|||
|
||||
@Override
|
||||
public void onDestroyed(Caster<?> caster) {
|
||||
getDelegates().forEach(spell -> spell.onDestroyed(caster));
|
||||
getDelegates().forEach(a -> a.onDestroyed(caster));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
return execute(getDelegates().stream(), spell -> spell.tick(source, situation));
|
||||
return execute(getDelegates().stream(), a -> a.tick(source, situation));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileDelegate).forEach(a -> {
|
||||
((ProjectileDelegate<MagicProjectileEntity>)a).onImpact(projectile, pos, state);
|
||||
});
|
||||
getDelegates(PROJECTILE_DELEGATE).forEach(a -> a.onImpact(projectile, pos, state));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileDelegate).forEach(a -> {
|
||||
((ProjectileDelegate<MagicProjectileEntity>)a).onImpact(projectile, entity);
|
||||
});
|
||||
getDelegates(PROJECTILE_DELEGATE).forEach(a -> a.onImpact(projectile, entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureProjectile(MagicProjectileEntity projectile, Caster<?> caster) {
|
||||
getDelegates().stream().filter(a -> a instanceof ProjectileSpell).forEach(a -> {
|
||||
((ProjectileSpell)a).configureProjectile(projectile, caster);
|
||||
});
|
||||
getDelegates(PROJECTILE_SPELL).forEach(a -> a.configureProjectile(projectile, caster));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,6 +128,10 @@ public abstract class AbstractDelegatingSpell implements ProjectileSpell {
|
|||
|
||||
protected abstract void saveDelegates(NbtCompound compound);
|
||||
|
||||
private <T> Stream<T> getDelegates(Function<? super Spell, T> cast) {
|
||||
return getDelegates().stream().map(cast).filter(Objects::nonNull);
|
||||
}
|
||||
|
||||
private static boolean execute(Stream<Spell> spells, Function<Spell, Boolean> action) {
|
||||
return spells.reduce(false, (u, a) -> action.apply(a), (a, b) -> a || b);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
/**
|
||||
* Magic effects that can be thrown.
|
||||
*/
|
||||
public interface ProjectileSpell extends Spell, ProjectileDelegate<MagicProjectileEntity> {
|
||||
|
||||
public interface ProjectileSpell extends Spell, ProjectileDelegate {
|
||||
@Override
|
||||
default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (!projectile.isClient()) {
|
||||
|
|
|
@ -24,7 +24,6 @@ import net.minecraft.entity.FallingBlockEntity;
|
|||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
|
@ -198,7 +197,6 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell
|
|||
return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void applyRadialEffect(Caster<?> source, Entity target, double distance, double radius) {
|
||||
|
||||
|
@ -212,10 +210,10 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell
|
|||
@Nullable
|
||||
Entity master = source.getMaster();
|
||||
|
||||
if (target instanceof MagicProjectileEntity) {
|
||||
Item item = ((MagicProjectileEntity)target).getStack().getItem();
|
||||
if (item instanceof ProjectileDelegate && master != null) {
|
||||
((ProjectileDelegate<ProjectileEntity>) item).onImpact(((ProjectileEntity)target), master);
|
||||
if (target instanceof MagicProjectileEntity projectile) {
|
||||
Item item = projectile.getStack().getItem();
|
||||
if (item instanceof ProjectileDelegate p && master != null) {
|
||||
p.onImpact(projectile, master);
|
||||
}
|
||||
} else if (target instanceof PersistentProjectileEntity) {
|
||||
if (master != null) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.IItemEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
@ -14,7 +15,6 @@ import net.minecraft.entity.LivingEntity;
|
|||
import net.minecraft.entity.attribute.EntityAttributeInstance;
|
||||
import net.minecraft.entity.attribute.EntityAttributes;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
@ -50,7 +50,7 @@ public class FilledJarItem extends JarItem implements ChameleonItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(ProjectileEntity projectile, Entity entity) {
|
||||
public void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
super.onImpact(projectile, entity);
|
||||
|
||||
if (!entity.isAttackable() || !(projectile instanceof FlyingItemEntity)) {
|
||||
|
@ -119,11 +119,8 @@ public class FilledJarItem extends JarItem implements ChameleonItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onImpact(ProjectileEntity projectile) {
|
||||
if (!(projectile instanceof FlyingItemEntity)) {
|
||||
return;
|
||||
}
|
||||
ItemStack stack = getAppearanceStack(((FlyingItemEntity)projectile).getStack());
|
||||
protected void onImpact(MagicProjectileEntity projectile) {
|
||||
ItemStack stack = getAppearanceStack(projectile.getStack());
|
||||
stack.damage(1, projectile.world.random, null);
|
||||
projectile.dropStack(stack);
|
||||
projectile.world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, projectile.getBlockPos(), Block.getRawIdFromState(Blocks.GLASS.getDefaultState()));
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.entity.PhysicsBodyProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.DispenserBlock;
|
||||
|
@ -51,7 +52,7 @@ public class HeavyProjectileItem extends ProjectileItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(ProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
if (projectile.world.getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) {
|
||||
float damage = projectile instanceof FlyingItemEntity ? getProjectileDamage(((FlyingItemEntity)projectile).getStack()) : 0;
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import com.minelittlepony.unicopia.entity.IItemEntity;
|
|||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
@ -13,7 +15,6 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.LightningEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.entity.Entity.RemovalReason;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
@ -81,16 +82,16 @@ public class JarItem extends ProjectileItem implements ItemImpl.GroundTickCallba
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(ProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {
|
||||
onImpact(projectile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(ProjectileEntity projectile, Entity entity) {
|
||||
public void onImpact(MagicProjectileEntity projectile, Entity entity) {
|
||||
onImpact(projectile);
|
||||
}
|
||||
|
||||
protected void onImpact(ProjectileEntity projectile) {
|
||||
protected void onImpact(MagicProjectileEntity projectile) {
|
||||
if (!projectile.world.isClient()) {
|
||||
ServerWorld world = (ServerWorld)projectile.world;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraft.util.Hand;
|
|||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
abstract class ProjectileItem extends Item implements ProjectileDelegate<ProjectileEntity> {
|
||||
abstract class ProjectileItem extends Item implements ProjectileDelegate {
|
||||
|
||||
private final float projectileDamage;
|
||||
|
||||
|
|
|
@ -290,16 +290,15 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Li
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void forEachDelegates(Consumer<ProjectileDelegate<MagicProjectileEntity>> consumer) {
|
||||
protected void forEachDelegates(Consumer<ProjectileDelegate> consumer) {
|
||||
getSpellSlot().forEach(spell -> {
|
||||
if (SpellPredicate.HAS_PROJECTILE_EVENTS.test(spell)) {
|
||||
consumer.accept((ProjectileDelegate<MagicProjectileEntity>)spell);
|
||||
consumer.accept((ProjectileDelegate)spell);
|
||||
}
|
||||
return Operation.SKIP;
|
||||
}, true);
|
||||
if (getItem().getItem() instanceof ProjectileDelegate) {
|
||||
consumer.accept(((ProjectileDelegate<MagicProjectileEntity>)getItem().getItem()));
|
||||
consumer.accept(((ProjectileDelegate)getItem().getItem()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,17 +2,16 @@ package com.minelittlepony.unicopia.projectile;
|
|||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public interface ProjectileDelegate<T extends ProjectileEntity> {
|
||||
public interface ProjectileDelegate {
|
||||
/**
|
||||
* Called once the projectile lands either hitting the ground or an entity.
|
||||
*/
|
||||
default void onImpact(T projectile, BlockPos pos, BlockState state) {}
|
||||
default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {}
|
||||
|
||||
/**
|
||||
* Called once the projectile lands either hitting the ground or an entity.
|
||||
*/
|
||||
default void onImpact(T projectile, Entity entity) {}
|
||||
default void onImpact(MagicProjectileEntity projectile, Entity entity) {}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public interface ProjectileUtil {
|
|||
* Checks if the given entity is a projectile that is not stuck in the ground.
|
||||
*/
|
||||
static boolean isFlyingProjectile(Entity e) {
|
||||
return isProjectile(e) && !(e instanceof MixinPersistentProjectileEntity && ((MixinPersistentProjectileEntity)e).isInGround());
|
||||
return isProjectile(e) && !(e instanceof MixinPersistentProjectileEntity m && m.isInGround());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,8 +42,8 @@ public interface ProjectileUtil {
|
|||
*/
|
||||
static void setThrowableHeading(Entity throwable, Vec3d heading, float velocity, float inaccuracy) {
|
||||
|
||||
if (throwable instanceof ProjectileEntity) {
|
||||
((ProjectileEntity)throwable).setVelocity(heading.x, heading.y, heading.z, velocity, inaccuracy);
|
||||
if (throwable instanceof ProjectileEntity p) {
|
||||
p.setVelocity(heading.x, heading.y, heading.z, velocity, inaccuracy);
|
||||
} else {
|
||||
heading = heading.normalize().multiply(velocity);
|
||||
|
||||
|
|
Loading…
Reference in a new issue