Added caster utils to easily find magically enabled entities in the world, and make it easier to get out an effect of a given type

This commit is contained in:
Sollace 2019-02-13 22:43:08 +02:00
parent 0ab3867b9d
commit 4ba567d5e5
7 changed files with 114 additions and 14 deletions

View file

@ -97,9 +97,9 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
@Nullable @Nullable
@Override @Override
public IMagicEffect getEffect(boolean update) { public <T extends IMagicEffect> T getEffect(@Nullable Class<T> type, boolean update) {
return effectDelegate.get(update); return effectDelegate.get(type, update);
} }
@Override @Override
public boolean hasEffect() { public boolean hasEffect() {

View file

@ -55,9 +55,14 @@ public class EffectSync<T extends EntityLivingBase> {
return effect != null; return effect != null;
} }
public IMagicEffect get(boolean update) { @SuppressWarnings("unchecked")
public <E extends IMagicEffect> E get(Class<E> type, boolean update) {
if (!update) { if (!update) {
return effect; if (effect == null || type == null || type.isAssignableFrom(effect.getClass())) {
return (E)effect;
}
return null;
} }
NBTTagCompound comp = owned.getEntity().getDataManager().get(param); NBTTagCompound comp = owned.getEntity().getDataManager().get(param);
@ -82,7 +87,11 @@ public class EffectSync<T extends EntityLivingBase> {
} }
} }
return effect; if (effect == null || type == null || type.isAssignableFrom(effect.getClass())) {
return (E)effect;
}
return null;
} }
public void set(@Nullable IMagicEffect effect) { public void set(@Nullable IMagicEffect effect) {

View file

@ -369,8 +369,8 @@ class PlayerCapabilities implements IPlayer {
@Nullable @Nullable
@Override @Override
public IMagicEffect getEffect(boolean update) { public <T extends IMagicEffect> T getEffect(@Nullable Class<T> type, boolean update) {
return effectDelegate.get(update); return effectDelegate.get(type, update);
} }
@Override @Override

View file

@ -1,7 +1,6 @@
package com.minelittlepony.unicopia.render; package com.minelittlepony.unicopia.render;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellDisguise; import com.minelittlepony.unicopia.spell.SpellDisguise;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -50,9 +49,9 @@ public class DisguiseRenderer {
} }
public boolean renderDisguiseToGui(IPlayer player) { public boolean renderDisguiseToGui(IPlayer player) {
IMagicEffect effect = player.getEffect(false); SpellDisguise effect = player.getEffect(SpellDisguise.class, false);
if (!(effect instanceof SpellDisguise) || effect.getDead()) { if (effect == null || effect.getDead()) {
return false; return false;
} }
@ -63,7 +62,7 @@ public class DisguiseRenderer {
return false; return false;
} }
Entity e = ((SpellDisguise)effect).getDisguise(); Entity e = effect.getDisguise();
// Check for a disguise and render it in our place. // Check for a disguise and render it in our place.
if (e != null) { if (e != null) {

View file

@ -0,0 +1,69 @@
package com.minelittlepony.unicopia.spell;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Predicates;
import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
public class CasterUtils {
public static Stream<ICaster<?>> findAllSpellsInRange(ICaster<?> source, double radius) {
BlockPos origin = source.getOrigin();
BlockPos begin = origin.add(-radius, -radius, -radius);
BlockPos end = origin.add(radius, radius, radius);
AxisAlignedBB bb = new AxisAlignedBB(begin, end);
return source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e ->
!e.isDead && (e instanceof ICaster || e instanceof EntityPlayer)
).stream().filter(e -> {
double dist = e.getDistance(origin.getX(), origin.getY(), origin.getZ());
double dist2 = e.getDistance(origin.getX(), origin.getY() - e.getEyeHeight(), origin.getZ());
return dist <= radius || dist2 <= radius;
})
.map(CasterUtils::toCaster)
.filter(o -> o.isPresent() && o.get() != source)
.map(Optional::get);
}
static Stream<ICaster<?>> findAllSpellsInRange(ICaster<?> source, AxisAlignedBB bb) {
return source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e ->
!e.isDead && (e instanceof ICaster || Predicates.MAGI.test(e))
).stream()
.map(CasterUtils::toCaster)
.filter(o -> o.isPresent() && o.get() != source)
.map(Optional::get);
}
@SuppressWarnings("unchecked")
static <T extends IMagicEffect> Optional<T> toMagicEffect(Class<T> type, @Nullable Entity entity) {
return toCaster(entity)
.filter(ICaster::hasEffect)
.map(caster -> caster.getEffect(type, false))
.filter(e -> !e.getDead());
}
static Optional<ICaster<?>> toCaster(@Nullable Entity entity) {
if (entity instanceof ICaster<?>) {
return Optional.of((ICaster<?>)entity);
}
if (entity instanceof EntityPlayer) {
return Optional.of(PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity));
}
return Optional.empty();
}
}

View file

@ -14,6 +14,7 @@ import com.minelittlepony.util.vector.VecHelper;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -23,7 +24,12 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
void setEffect(@Nullable IMagicEffect effect); void setEffect(@Nullable IMagicEffect effect);
@Nullable @Nullable
IMagicEffect getEffect(boolean update); default IMagicEffect getEffect(boolean update) {
return getEffect(null, update);
}
@Nullable
<T extends IMagicEffect> T getEffect(@Nullable Class<T> type, boolean update);
@Nullable @Nullable
default IMagicEffect getEffect() { default IMagicEffect getEffect() {
@ -39,14 +45,23 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
return getOwner(); return getOwner();
} }
/**
* Gets the unique id associated with this caste.
*/
default UUID getUniqueId() { default UUID getUniqueId() {
return getEntity().getUniqueID(); return getEntity().getUniqueID();
} }
/**
* gets the minecraft world
*/
default World getWorld() { default World getWorld() {
return getEntity().getEntityWorld(); return getEntity().getEntityWorld();
} }
/**
* Gets the center position where this caster is located.
*/
default BlockPos getOrigin() { default BlockPos getOrigin() {
return getEntity().getPosition(); return getEntity().getPosition();
} }
@ -69,6 +84,14 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
} }
} }
default Stream<ICaster<?>> findAllSpellsInRange(double radius) {
return CasterUtils.findAllSpellsInRange(this, radius);
}
default Stream<ICaster<?>> findAllSpellsInRange(AxisAlignedBB bb) {
return CasterUtils.findAllSpellsInRange(this, bb);
}
default Stream<Entity> findAllEntitiesInRange(double radius) { default Stream<Entity> findAllEntitiesInRange(double radius) {
return VecHelper.findAllEntitiesInRange(getEntity(), getWorld(), getOrigin(), radius); return VecHelper.findAllEntitiesInRange(getEntity(), getWorld(), getOrigin(), radius);
} }

View file

@ -32,7 +32,7 @@ public class VecHelper {
Vec3d pos = e.getPositionEyes(partialTicks); Vec3d pos = e.getPositionEyes(partialTicks);
Vec3d look = e.getLook(partialTicks).scale(distance); Vec3d look = e.getLook(partialTicks).scale(distance);
return e.world.rayTraceBlocks(pos, pos.add(look), false, false, true); return e.getEntityWorld().rayTraceBlocks(pos, pos.add(look), false, false, true);
} }
/** /**