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