Yet more refactoring

This commit is contained in:
Sollace 2021-03-06 23:11:17 +02:00
parent 3be00acad2
commit 63c1b4ef7f
18 changed files with 53 additions and 85 deletions

View file

@ -18,19 +18,27 @@ import net.minecraft.entity.player.PlayerEntity;
public interface EquinePredicates {
Predicate<Entity> IS_PLAYER = e -> e instanceof PlayerEntity;
Predicate<Entity> RACE_INTERACT_WITH_CLOUDS = entity -> Equine.of(entity).getSpecies().canInteractWithClouds();
Predicate<Entity> RACE_INTERACT_WITH_CLOUDS = raceMatches(Race::canInteractWithClouds);
Predicate<Entity> PLAYER_EARTH = IS_PLAYER.and(entity -> Equine.of(entity).getSpecies() == Race.EARTH);
Predicate<Entity> PLAYER_BAT = IS_PLAYER.and(entity -> Equine.of(entity).getSpecies() == Race.BAT);
Predicate<Entity> PLAYER_UNICORN = IS_PLAYER.and(entity -> Equine.of(entity).getSpecies().canCast());
Predicate<Entity> PLAYER_CHANGELING = IS_PLAYER.and(entity -> Equine.of(entity).getSpecies() == Race.CHANGELING);
Predicate<Entity> PLAYER_PEGASUS = IS_PLAYER.and(entity -> ((PlayerEntity)entity).abilities.creativeMode || RACE_INTERACT_WITH_CLOUDS.test(entity));
Predicate<Entity> PLAYER_EARTH = IS_PLAYER.and(ofRace(Race.EARTH));
Predicate<Entity> PLAYER_BAT = IS_PLAYER.and(ofRace(Race.BAT));
Predicate<Entity> PLAYER_UNICORN = IS_PLAYER.and(raceMatches(Race::canCast));
Predicate<Entity> PLAYER_CHANGELING = IS_PLAYER.and(ofRace(Race.CHANGELING));
Predicate<Entity> PLAYER_PEGASUS = IS_PLAYER.and(e -> ((PlayerEntity)e).abilities.creativeMode || RACE_INTERACT_WITH_CLOUDS.test(e));
Predicate<Entity> IS_CASTER = e -> !e.removed && (e instanceof Caster || PLAYER_UNICORN.test(e));
Predicate<LivingEntity> HAS_WANT_IT_NEED_IT = e -> EnchantmentHelper.getEquipmentLevel(UEnchantments.WANT_IT_NEED_IT, e) > 0;
static Predicate<Entity> carryingSpell(@Nullable SpellType<?> type) {
return IS_PLAYER.and(entity -> Pony.of((PlayerEntity)entity).getSpellSlot().get(type, false).isPresent());
return IS_PLAYER.and(e -> Pony.of((PlayerEntity)e).getSpellSlot().get(type, false).isPresent());
}
static Predicate<Entity> ofRace(Race race) {
return raceMatches(race::equals);
}
static Predicate<Entity> raceMatches(Predicate<Race> predicate) {
return e -> Equine.of(e).map(Equine::getSpecies).filter(predicate).isPresent();
}
}

View file

@ -16,13 +16,12 @@ import com.minelittlepony.unicopia.util.VecHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
/**
* Interface for any magically capable entities that can cast or persist spells.
*/
public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affine, Magical, ParticleSource {
public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affine, ParticleSource {
Physics getPhysics();
@ -76,15 +75,7 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
}
default Stream<Entity> findAllEntitiesInRange(double radius, @Nullable Predicate<Entity> test) {
return findAllEntitiesInRange(getOriginVector(), radius, test);
}
default Stream<Entity> findAllEntitiesInRange(Vec3d origin, double radius, @Nullable Predicate<Entity> test) {
return VecHelper.findInRange(getEntity(), getWorld(), origin, radius, test).stream();
}
default Stream<Entity> findAllEntitiesInRange(Vec3d origin, double radius) {
return findAllEntitiesInRange(origin, radius, null);
return VecHelper.findInRange(getEntity(), getWorld(), getOriginVector(), radius, test).stream();
}
default Stream<Entity> findAllEntitiesInRange(double radius) {
@ -106,10 +97,9 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
return Optional.of((Caster<?>)entity);
}
if (entity instanceof LivingEntity && !(entity instanceof Magical)) {
return PonyContainer.of(entity).map(PonyContainer::getCaster);
}
return Optional.empty();
return PonyContainer.of(entity)
.map(PonyContainer::get)
.filter(c -> c instanceof Caster<?>)
.map(c -> (Caster<?>)c);
}
}

View file

@ -1,9 +0,0 @@
package com.minelittlepony.unicopia.ability.magic;
/**
* Any entities with magical abilities.
* Casters are automatically considered magic, for obvious reasons.
*/
public interface Magical {
}

View file

@ -3,7 +3,6 @@ package com.minelittlepony.unicopia.ability.magic.spell;
import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.ability.magic.Attached;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Magical;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.block.state.StateMaps;
import com.minelittlepony.unicopia.particle.ParticleUtils;
@ -122,7 +121,7 @@ public class FireSpell extends AbstractSpell implements Thrown, Attached {
protected boolean applyEntitySingle(Entity owner, World world, Entity e) {
if ((!e.equals(owner) ||
(owner instanceof PlayerEntity && !EquinePredicates.PLAYER_UNICORN.test(owner))) && !(e instanceof ItemEntity)
&& !(e instanceof Magical)) {
&& !(e instanceof Caster<?>)) {
e.setOnFireFor(60);
e.damage(getDamageCause(e, (LivingEntity)owner), 0.1f);
playEffect(world, e.getBlockPos());

View file

@ -19,6 +19,7 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@ -70,7 +71,7 @@ public class SiphoningSpell extends AbstractPlacedSpell {
}
private Stream<LivingEntity> getTargets(Caster<?> source) {
return VecHelper.findInRange(null, source.getWorld(), source.getOriginVector(), 4 + source.getLevel().get(), e -> e instanceof LivingEntity)
return VecHelper.findInRange(null, source.getWorld(), source.getOriginVector(), 4 + source.getLevel().get(), EntityPredicates.EXCEPT_CREATIVE_SPECTATOR_OR_PEACEFUL.and(e -> e instanceof LivingEntity))
.stream()
.map(e -> (LivingEntity)e);
}

View file

@ -11,8 +11,8 @@ import javax.annotation.Nullable;
import com.google.common.collect.Multimap;
import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.player.PlayerAttributes;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.item.enchantment.AttributedEnchantment;
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
import net.minecraft.client.MinecraftClient;
@ -45,9 +45,10 @@ public class ModifierTooltipRenderer implements ItemTooltipCallback {
Map<EquipmentSlot, Multimap<EntityAttribute, EntityAttributeModifier>> modifiers = new HashMap<>();
Living<?> living = Equine.of(MinecraftClient.getInstance().player);
getEnchantments(stack).filter(p -> p.getRight() instanceof AttributedEnchantment).forEach(pair -> {
((AttributedEnchantment)pair.getRight()).getModifiers(living, pair.getLeft(), modifiers);
Equine.<PlayerEntity, Pony>of(MinecraftClient.getInstance().player).ifPresent(eq -> {
getEnchantments(stack).filter(p -> p.getRight() instanceof AttributedEnchantment).forEach(pair -> {
((AttributedEnchantment)pair.getRight()).getModifiers(eq, pair.getLeft(), modifiers);
});
});
modifiers.forEach((slot, modifs) -> {

View file

@ -69,10 +69,7 @@ public interface Equine<T extends Entity> extends NbtSerialisable, Tickable, Pro
return Optional.empty();
}
@Nullable
static <T extends Equine<?>> T of(Entity entity) {
return PonyContainer.<Entity, T>of(entity)
.map(PonyContainer::get)
.orElse(null);
static <E extends Entity, T extends Equine<E>> Optional<T> of(@Nullable E entity) {
return PonyContainer.<E, T>of(entity).map(PonyContainer::get);
}
}

View file

@ -1,6 +1,5 @@
package com.minelittlepony.unicopia.entity;
import com.minelittlepony.unicopia.ability.magic.Magical;
import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
@ -20,7 +19,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class FloatingArtefactEntity extends Entity implements Magical {
public class FloatingArtefactEntity extends Entity {
private static final TrackedData<ItemStack> ITEM = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.ITEM_STACK);
private static final TrackedData<Byte> STATE = DataTracker.registerData(FloatingArtefactEntity.class, TrackedDataHandlerRegistry.BYTE);

View file

@ -4,10 +4,7 @@ import java.util.Optional;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.ability.magic.Caster;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
public interface PonyContainer<T extends Equine<?>> {
@ -16,18 +13,7 @@ public interface PonyContainer<T extends Equine<?>> {
T get();
@SuppressWarnings("unchecked")
@Nullable
default <E extends LivingEntity> Caster<E> getCaster() {
T ientity = get();
if (ientity instanceof Caster) {
return (Caster<E>)ientity;
}
return null;
}
@SuppressWarnings("unchecked")
static <E extends Entity, T extends Equine<?>> Optional<PonyContainer<T>> of(Entity entity) {
static <E extends Entity, T extends Equine<?>> Optional<PonyContainer<T>> of(@Nullable Entity entity) {
if (entity instanceof PonyContainer) {
return Optional.of(((PonyContainer<T>)entity));
}

View file

@ -53,7 +53,7 @@ public class RaceChangeStatusEffect extends StatusEffect {
return;
}
Equine<?> eq = Equine.of(entity);
Equine<?> eq = Equine.of(entity).orElse(null);
if (eq == null) {
return;

View file

@ -17,7 +17,7 @@ abstract class MixinBrain<E extends LivingEntity> {
@Inject(method = "tick", at = @At("HEAD"))
public void beforeTickAi(ServerWorld world, E entity, CallbackInfo into) {
Equine<?> eq = Equine.of(entity);
Equine<?> eq = Equine.of(entity).orElse(null);
if (eq instanceof Living<?> && eq.getPhysics().isGravityNegative()) {
((RotatedView)world).pushRotation((int)entity.getY());

View file

@ -1,7 +1,5 @@
package com.minelittlepony.unicopia.mixin;
import javax.annotation.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -19,12 +17,9 @@ import net.minecraft.text.TranslatableText;
abstract class MixinDamageSource {
@Inject(method = "getDeathMessage", at = @At("RETURN"), cancellable = true)
private void onGetDeathMessage(LivingEntity entity, CallbackInfoReturnable<Text> info) {
Equine<?> eq = Equine.of(entity);
@Nullable
Entity attacker = eq == null ? null : eq.getAttacker();
DamageSource self = (DamageSource)(Object)this;
Equine.of(entity).map(Equine::getAttacker).ifPresent(attacker -> {
DamageSource self = (DamageSource)(Object)this;
if (attacker != null) {
Entity prime = entity.getPrimeAdversary();
if (prime != null && !(attacker instanceof Owned<?> && ((Owned<?>)attacker).getMaster() == prime)) {
info.setReturnValue(new TranslatableText("death.attack.generic.and_also", info.getReturnValue(), attacker.getDisplayName()));
@ -32,6 +27,6 @@ abstract class MixinDamageSource {
}
info.setReturnValue(new TranslatableText("death.attack." + self.getName() + ".player", entity.getDisplayName(), attacker.getDisplayName()));
}
});
}
}

View file

@ -34,7 +34,7 @@ abstract class MixinMobEntity extends LivingEntity implements PonyContainer<Equi
@Inject(method = "tickNewAi", at = @At("HEAD"))
public void beforeTickAi(CallbackInfo into) {
Equine<?> eq = Equine.of(this);
Equine<?> eq = Equine.of(this).orElse(null);
if (eq instanceof Living<?> && eq.getPhysics().isGravityNegative()) {
((RotatedView)world).pushRotation((int)getY());

View file

@ -76,9 +76,9 @@ abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<P
@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;",
at = @At("RETURN"))
private void onDropItem(ItemStack itemStack_1, boolean scatter, boolean retainOwnership, CallbackInfoReturnable<ItemEntity> info) {
PonyContainer.of(info.getReturnValue()).ifPresent(container -> {
container.get().setSpecies(get().getSpecies());
container.get().getPhysics().setBaseGravityModifier(get().getPhysics().getGravityModifier());
Equine.of(info.getReturnValue()).ifPresent(eq -> {
eq.setSpecies(get().getSpecies());
eq.getPhysics().setBaseGravityModifier(get().getPhysics().getGravityModifier());
});
}

View file

@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.unicopia.entity.PonyContainer;
import com.minelittlepony.unicopia.entity.Equine;
import net.minecraft.entity.Entity;
import net.minecraft.entity.projectile.ProjectileEntity;
@ -19,8 +19,8 @@ abstract class MixinProjectileEntity extends Entity {
at = @At("HEAD"),
cancellable = true)
private void onOnEntityHit(EntityHitResult hit, CallbackInfo info) {
PonyContainer.of(hit.getEntity()).ifPresent(container -> {
if (container.get().onProjectileImpact((ProjectileEntity)(Object)this)) {
Equine.of(hit.getEntity()).ifPresent(eq -> {
if (eq.onProjectileImpact((ProjectileEntity)(Object)this)) {
info.cancel();
}
});

View file

@ -18,7 +18,7 @@ import net.minecraft.entity.ai.TargetPredicate;
abstract class MixinTargetPredicate {
@Inject(method = "test", at = @At("HEAD"), cancellable = true)
public void onTest(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable<Boolean> info) {
Equine<?> eq = Equine.of(targetEntity);
Equine<?> eq = Equine.of(targetEntity).orElse(null);
if (eq instanceof Pony) {
((Pony)eq).getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(spell -> {
if (spell.getDisguise().getAppearance() == baseEntity) {

View file

@ -20,13 +20,15 @@ abstract class MixinEntityRenderDispatcher {
@Inject(method = RENDER, at = @At("HEAD"), cancellable = true)
private <E extends Entity> void beforeRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) {
if (WorldRenderDelegate.INSTANCE.onEntityRender((EntityRenderDispatcher)(Object)this, Equine.of(entity), x, y, z, yaw, tickDelta, matrices, vertexConsumers, light)) {
info.cancel();
}
Equine.of(entity).ifPresent(eq -> {
if (WorldRenderDelegate.INSTANCE.onEntityRender((EntityRenderDispatcher)(Object)this, eq, x, y, z, yaw, tickDelta, matrices, vertexConsumers, light)) {
info.cancel();
}
});
}
@Inject(method = RENDER, at = @At("RETURN"))
private <E extends Entity> void afterRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) {
WorldRenderDelegate.INSTANCE.afterEntityRender(Equine.of(entity), matrices);
Equine.of(entity).ifPresent(eq -> WorldRenderDelegate.INSTANCE.afterEntityRender(eq, matrices));
}
}

View file

@ -5,7 +5,6 @@ import com.minelittlepony.unicopia.UEntities;
import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Levelled;
import com.minelittlepony.unicopia.ability.magic.Magical;
import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
@ -46,7 +45,7 @@ import net.minecraft.world.World;
*
* Can also carry a spell if needed.
*/
public class MagicProjectileEntity extends ThrownItemEntity implements Magical, Caster<LivingEntity> {
public class MagicProjectileEntity extends ThrownItemEntity implements Caster<LivingEntity> {
private static final TrackedData<Float> DAMAGE = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);