Further refactorings

This commit is contained in:
Sollace 2022-12-19 20:45:02 +01:00
parent a3163d431f
commit eed112ef4a
30 changed files with 158 additions and 154 deletions

View file

@ -21,24 +21,6 @@ public interface Owned<E extends Entity> {
@Nullable @Nullable
E getMaster(); E getMaster();
/**
* Updates the owner of this object.
*/
void setMaster(@Nullable E owner);
/**
* Updated the owner of this object to be the same as another.
*
* @param sibling
*/
default void setMaster(Owned<? extends E> sibling) {
setMaster(sibling.getMaster());
}
default boolean hasMaster() {
return getMaster() != null;
}
/** /**
* Gets the unique entity id of the entity that holds this object. * Gets the unique entity id of the entity that holds this object.
* <p> * <p>
@ -58,4 +40,20 @@ public interface Owned<E extends Entity> {
default boolean hasCommonOwner(Owned<?> sibling) { default boolean hasCommonOwner(Owned<?> sibling) {
return getMasterId().isPresent() && getMasterId().equals(sibling.getMasterId()); return getMasterId().isPresent() && getMasterId().equals(sibling.getMasterId());
} }
interface Mutable<E extends Entity> {
/**
* Updates the owner of this object.
*/
void setMaster(@Nullable E owner);
/**
* Updated the owner of this object to be the same as another.
*
* @param sibling
*/
default void setMaster(Owned<? extends E> sibling) {
setMaster(sibling.getMaster());
}
}
} }

View file

@ -16,7 +16,21 @@ import net.minecraft.entity.Entity;
* @param <E> The type of object that owns us. * @param <E> The type of object that owns us.
*/ */
public interface WeaklyOwned<E extends Entity> extends Owned<E>, WorldConvertable { public interface WeaklyOwned<E extends Entity> extends Owned<E>, WorldConvertable {
EntityReference<E> getMasterReference();
@Nullable
@Override
default E getMaster() {
return getMasterReference().get(asWorld());
}
@Override
default Optional<UUID> getMasterId() {
return getMasterReference().getId();
}
interface Mutable<E extends Entity> extends WeaklyOwned<E>, Owned.Mutable<E> {
@Override
EntityReference<E> getMasterReference(); EntityReference<E> getMasterReference();
/** /**
@ -38,15 +52,5 @@ public interface WeaklyOwned<E extends Entity> extends Owned<E>, WorldConvertabl
default void setMaster(E master) { default void setMaster(E master) {
getMasterReference().set(master); getMasterReference().set(master);
} }
@Nullable
@Override
default E getMaster() {
return getMasterReference().get(asWorld());
}
@Override
default Optional<UUID> getMasterId() {
return getMasterReference().getId();
} }
} }

View file

@ -16,7 +16,6 @@ import net.minecraft.block.FenceBlock;
import net.minecraft.block.LeavesBlock; import net.minecraft.block.LeavesBlock;
import net.minecraft.block.WallBlock; import net.minecraft.block.WallBlock;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
@ -127,9 +126,9 @@ public class UnicornTeleportAbility implements Ability<Pos> {
return; return;
} }
LivingEntity player = teleportee.getMaster(); Entity participant = teleportee.asEntity();
if (player == null) { if (participant == null) {
return; return;
} }
@ -137,24 +136,24 @@ public class UnicornTeleportAbility implements Ability<Pos> {
double distance = destination.distanceTo(teleportee) / 10; double distance = destination.distanceTo(teleportee) / 10;
if (player.hasVehicle()) { if (participant.hasVehicle()) {
Entity mount = player.getVehicle(); Entity mount = participant.getVehicle();
player.stopRiding(); participant.stopRiding();
Living.transmitPassengers(mount); Living.transmitPassengers(mount);
} }
Vec3d offset = teleportee.getOriginVector().subtract(teleporter.getOriginVector()); Vec3d offset = teleportee.getOriginVector().subtract(teleporter.getOriginVector());
player.teleport( participant.teleport(
destination.x + offset.x + (player.getX() - Math.floor(player.getX())), destination.x + offset.x + (participant.getX() - Math.floor(participant.getX())),
destination.y + offset.y, destination.y + offset.y,
destination.z + offset.z + (player.getZ() - Math.floor(player.getZ()))); destination.z + offset.z + (participant.getZ() - Math.floor(participant.getZ())));
teleporter.subtractEnergyCost(distance); teleporter.subtractEnergyCost(distance);
player.fallDistance /= distance; participant.fallDistance /= distance;
player.world.playSound(null, destination.pos(), USounds.ENTITY_PLAYER_UNICORN_TELEPORT, SoundCategory.PLAYERS, 1, 1); participant.world.playSound(null, destination.pos(), USounds.ENTITY_PLAYER_UNICORN_TELEPORT, SoundCategory.PLAYERS, 1, 1);
} }
private boolean enterable(World w, BlockPos pos) { private boolean enterable(World w, BlockPos pos) {

View file

@ -25,7 +25,8 @@ import net.minecraft.world.GameRules;
/** /**
* Interface for any magically capable entities that can cast or persist spells. * Interface for any magically capable entities that can cast or persist spells.
*/ */
public interface Caster<E extends Entity> extends Owned<LivingEntity>, public interface Caster<E extends Entity> extends
Owned<LivingEntity>,
Levelled, Levelled,
Affine, Affine,
ParticleSource<E>, ParticleSource<E>,
@ -43,6 +44,21 @@ public interface Caster<E extends Entity> extends Owned<LivingEntity>,
*/ */
boolean subtractEnergyCost(double amount); boolean subtractEnergyCost(double amount);
/**
* Gets the entity who originally cast the currently active spell.
* @return
*/
@Override
LivingEntity getMaster();
/**
* Gets the original caster responsible for this spell.
* If none is found, will return itself.
*/
default Caster<?> getOriginatingCaster() {
return of(getMaster()).orElse(this);
}
default boolean canModifyAt(BlockPos pos) { default boolean canModifyAt(BlockPos pos) {
return canModifyAt(pos, ModificationType.EITHER); return canModifyAt(pos, ModificationType.EITHER);
} }

View file

@ -11,7 +11,6 @@ import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.particle.UParticles;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
/** /**
@ -55,9 +54,8 @@ public class DispersableDisguiseSpell extends AbstractDisguiseSpell implements I
} }
} }
LivingEntity owner = source.getMaster(); Entity owner = source.asEntity();
Entity appearance = getDisguise().getAppearance();
Entity entity = getDisguise().getAppearance();
if (isSuppressed()) { if (isSuppressed()) {
suppressionCounter--; suppressionCounter--;
@ -67,9 +65,9 @@ public class DispersableDisguiseSpell extends AbstractDisguiseSpell implements I
((Pony)source).setInvisible(false); ((Pony)source).setInvisible(false);
} }
if (entity != null) { if (appearance != null) {
entity.setInvisible(true); appearance.setInvisible(true);
entity.setPos(entity.getX(), Integer.MIN_VALUE, entity.getY()); appearance.setPos(appearance.getX(), Integer.MIN_VALUE, appearance.getY());
} }
return true; return true;

View file

@ -12,7 +12,6 @@ import com.minelittlepony.unicopia.util.shape.Shape;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -55,19 +54,13 @@ public class RainboomAbilitySpell extends AbstractSpell {
// source.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, source.getPhysics().getMotionAngle()), source.getOriginVector(), Vec3d.ZERO); // source.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, source.getPhysics().getMotionAngle()), source.getOriginVector(), Vec3d.ZERO);
} }
LivingEntity owner = source.getMaster();
if (owner == null) {
return false;
}
source.findAllEntitiesInRange(RADIUS).forEach(e -> { source.findAllEntitiesInRange(RADIUS).forEach(e -> {
e.damage(MagicalDamageSource.create("rainboom", source).setBreakSunglasses(), 6); e.damage(MagicalDamageSource.create("rainboom", source).setBreakSunglasses(), 6);
}); });
EFFECT_RANGE.translate(source.getOrigin()).getBlockPositions().forEach(pos -> { EFFECT_RANGE.translate(source.getOrigin()).getBlockPositions().forEach(pos -> {
BlockState state = source.asWorld().getBlockState(pos); BlockState state = source.asWorld().getBlockState(pos);
if (state.isIn(UTags.FRAGILE) && source.canModifyAt(pos, ModificationType.PHYSICAL)) { if (state.isIn(UTags.FRAGILE) && source.canModifyAt(pos, ModificationType.PHYSICAL)) {
owner.world.breakBlock(pos, true); source.asWorld().breakBlock(pos, true);
} }
}); });

View file

@ -12,7 +12,7 @@ import com.minelittlepony.unicopia.item.GemstoneItem;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.Entity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -51,11 +51,7 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
public Optional<MagicProjectileEntity> throwProjectile(Caster<?> caster, float divergance) { public Optional<MagicProjectileEntity> throwProjectile(Caster<?> caster, float divergance) {
World world = caster.asWorld(); World world = caster.asWorld();
LivingEntity entity = caster.getMaster(); Entity entity = caster.asEntity();
if (entity == null) {
return Optional.empty();
}
caster.playSound(USounds.SPELL_CAST_SHOOT, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); caster.playSound(USounds.SPELL_CAST_SHOOT, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));

View file

@ -30,26 +30,28 @@ public class DisplacementSpell extends AbstractSpell implements HomingSpell, Pla
@Override @Override
public boolean tick(Caster<?> source, Situation situation) { public boolean tick(Caster<?> source, Situation situation) {
source.getMaster().setGlowing(true); Caster<?> originator = source.getOriginatingCaster();
originator.asEntity().setGlowing(true);
ticks--; ticks--;
if (source.isClient()) { if (originator.isClient()) {
return !isDead() || ticks >= -10; return !isDead() || ticks >= -10;
} }
if (ticks == 0) { if (ticks == 0) {
target.ifPresent(source.asWorld(), target -> { target.ifPresent(originator.asWorld(), target -> {
Vec3d destinationPos = target.getPos(); Vec3d destinationPos = target.getPos();
Vec3d destinationVel = target.getVelocity(); Vec3d destinationVel = target.getVelocity();
Vec3d sourcePos = source.getMaster().getPos(); Vec3d sourcePos = originator.getOriginVector();
Vec3d sourceVel = source.getMaster().getVelocity(); Vec3d sourceVel = originator.asEntity().getVelocity();
teleport(target, sourcePos, sourceVel); teleport(target, sourcePos, sourceVel);
teleport(source.getMaster(), destinationPos, destinationVel); teleport(originator.asEntity(), destinationPos, destinationVel);
source.subtractEnergyCost(destinationPos.distanceTo(sourcePos) / 20F); originator.subtractEnergyCost(destinationPos.distanceTo(sourcePos) / 20F);
}); });
} }
@ -94,7 +96,7 @@ public class DisplacementSpell extends AbstractSpell implements HomingSpell, Pla
@Override @Override
public void onDestroyed(Caster<?> caster) { public void onDestroyed(Caster<?> caster) {
caster.getMaster().setGlowing(false); caster.getOriginatingCaster().asEntity().setGlowing(false);
target.ifPresent(caster.asWorld(), e -> e.setGlowing(false)); target.ifPresent(caster.asWorld(), e -> e.setGlowing(false));
} }

View file

@ -13,7 +13,6 @@ import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.projectile.ProjectileDelegate; import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.VecHelper;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -73,7 +72,7 @@ public class FireSpell extends AbstractAreaEffectSpell implements ProjectileDele
return new Sphere(false, Math.max(0, 4 + getTraits().get(Trait.POWER))).translate(source.getOrigin()).getBlockPositions().reduce(false, return new Sphere(false, Math.max(0, 4 + getTraits().get(Trait.POWER))).translate(source.getOrigin()).getBlockPositions().reduce(false,
(r, i) -> source.canModifyAt(i) && applyBlocks(source.asWorld(), i), (r, i) -> source.canModifyAt(i) && applyBlocks(source.asWorld(), i),
(a, b) -> a || b) (a, b) -> a || b)
|| applyEntities(null, source.asWorld(), source.getOriginVector()); || applyEntities(source, source.getOriginVector());
} }
protected void generateParticles(Caster<?> source) { protected void generateParticles(Caster<?> source) {
@ -124,17 +123,19 @@ public class FireSpell extends AbstractAreaEffectSpell implements ProjectileDele
return false; return false;
} }
protected boolean applyEntities(@Nullable Entity owner, World world, Vec3d pos) { protected boolean applyEntities(Caster<?> source, Vec3d pos) {
return !VecHelper.findInRange(owner, world, pos, Math.max(0, 3 + getTraits().get(Trait.POWER)), i -> applyEntitySingle(owner, world, i)).isEmpty(); return source.findAllEntitiesInRange(Math.max(0, 3 + getTraits().get(Trait.POWER)), i -> applyEntitySingle(source, i)).count() > 0;
} }
protected boolean applyEntitySingle(@Nullable Entity owner, World world, Entity e) { protected boolean applyEntitySingle(Caster<?> source, Entity e) {
if ((!e.equals(owner) || LivingEntity master = source.getMaster();
(owner instanceof PlayerEntity && !EquinePredicates.PLAYER_UNICORN.test(owner))) && !(e instanceof ItemEntity)
if ((!(e.equals(source.asEntity()) || e.equals(master)) ||
(master instanceof PlayerEntity && !EquinePredicates.PLAYER_UNICORN.test(master))) && !(e instanceof ItemEntity)
&& !(e instanceof Caster<?>)) { && !(e instanceof Caster<?>)) {
e.setOnFireFor(60); e.setOnFireFor(60);
e.damage(getDamageCause(e, (LivingEntity)owner), 0.1f); e.damage(getDamageCause(e, master), 0.1f);
playEffect(world, e.getBlockPos()); playEffect(source.asWorld(), e.getBlockPos());
return true; return true;
} }

View file

@ -15,7 +15,6 @@ import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.TntEntity; import net.minecraft.entity.TntEntity;
import net.minecraft.entity.Entity.RemovalReason; import net.minecraft.entity.Entity.RemovalReason;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
@ -67,21 +66,21 @@ public class IceSpell extends AbstractSpell {
source.subtractEnergyCost(Math.min(10, blocksAffected)); source.subtractEnergyCost(Math.min(10, blocksAffected));
return applyEntities(source.getMaster(), source.asWorld(), source.getOriginVector()) && situation == Situation.PROJECTILE; return applyEntities(source, source.getOriginVector()) && situation == Situation.PROJECTILE;
} }
protected boolean applyEntities(LivingEntity owner, World world, Vec3d pos) { protected boolean applyEntities(Caster<?> source, Vec3d pos) {
return !VecHelper.findInRange(owner, world, pos, 3, i -> applyEntitySingle(owner, i)).isEmpty(); return !VecHelper.findInRange(source.asEntity(), source.asWorld(), pos, 3, i -> applyEntitySingle(source, i)).isEmpty();
} }
protected boolean applyEntitySingle(LivingEntity owner, Entity e) { protected boolean applyEntitySingle(Caster<?> source, Entity e) {
if (e instanceof TntEntity) { if (e instanceof TntEntity) {
e.remove(RemovalReason.DISCARDED); e.remove(RemovalReason.DISCARDED);
e.getEntityWorld().setBlockState(e.getBlockPos(), Blocks.TNT.getDefaultState()); e.getEntityWorld().setBlockState(e.getBlockPos(), Blocks.TNT.getDefaultState());
} else if (e.isOnFire()) { } else if (e.isOnFire()) {
e.extinguish(); e.extinguish();
} else { } else {
e.damage(MagicalDamageSource.create("cold", owner), 2); e.damage(MagicalDamageSource.create("cold", source.getMaster()), 2);
} }
return true; return true;

View file

@ -54,7 +54,7 @@ public class InfernoSpell extends FireSpell {
Vec3d vec = shape.computePoint(w.random).add(origin); Vec3d vec = shape.computePoint(w.random).add(origin);
if (!applyBlocks(w, new BlockPos(vec))) { if (!applyBlocks(w, new BlockPos(vec))) {
applyEntities(source.getMaster(), w, vec); applyEntities(source, vec);
} }
} }
} }

View file

@ -34,10 +34,12 @@ public class MindSwapSpell extends MimicSpell {
super.onDestroyed(caster); super.onDestroyed(caster);
if (initialized && !caster.isClient()) { if (initialized && !caster.isClient()) {
counterpart.ifPresent(caster.asWorld(), e -> { counterpart.ifPresent(caster.asWorld(), e -> {
EntitySwap.ALL.accept(e, caster.getMaster()); LivingEntity master = caster.getMaster();
EntitySwap.ALL.accept(e, master);
Inventory.swapInventories( Inventory.swapInventories(
e, myStoredInventory.or(() -> Inventory.of(e)), e, myStoredInventory.or(() -> Inventory.of(e)),
caster.getMaster(), theirStoredInventory.or(() -> Inventory.of(caster.getMaster())), master, theirStoredInventory.or(() -> Inventory.of(master)),
a -> {}, a -> {},
a -> {} a -> {}
); );
@ -60,13 +62,15 @@ public class MindSwapSpell extends MimicSpell {
initialized = true; initialized = true;
setDirty(); setDirty();
counterpart.ifPresent(caster.asWorld(), e -> { counterpart.ifPresent(caster.asWorld(), e -> {
LivingEntity master = caster.getMaster();
setDisguise(e); setDisguise(e);
Caster<?> other = Caster.of(e).get(); Caster<?> other = Caster.of(e).get();
SpellType.MIMIC.withTraits().apply(other).setDisguise(caster.getMaster()); SpellType.MIMIC.withTraits().apply(other).setDisguise(master);
EntitySwap.ALL.accept(caster.getMaster(), e); EntitySwap.ALL.accept(master, e);
Inventory.swapInventories( Inventory.swapInventories(
caster.getMaster(), Inventory.of(caster.getMaster()), master, Inventory.of(master),
e, Inventory.of(e), e, Inventory.of(e),
a -> myStoredInventory = Optional.of(a), a -> myStoredInventory = Optional.of(a),
a -> theirStoredInventory = Optional.of(a) a -> theirStoredInventory = Optional.of(a)
@ -78,7 +82,7 @@ public class MindSwapSpell extends MimicSpell {
} }
if (counterpart.getId().isPresent() && counterpart.get(caster.asWorld()) == null) { if (counterpart.getId().isPresent() && counterpart.get(caster.asWorld()) == null) {
caster.getMaster().damage(DamageSource.MAGIC, Float.MAX_VALUE); caster.getOriginatingCaster().asEntity().damage(DamageSource.MAGIC, Float.MAX_VALUE);
setDead(); setDead();
return false; return false;
} }

View file

@ -14,9 +14,7 @@ import com.minelittlepony.unicopia.util.Weighted;
import com.minelittlepony.unicopia.util.shape.Shape; import com.minelittlepony.unicopia.util.shape.Shape;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import net.minecraft.entity.EntityType; import net.minecraft.entity.*;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
@ -142,7 +140,7 @@ public class NecromancySpell extends AbstractAreaEffectSpell {
minion.equipStack(EquipmentSlot.HEAD, Items.IRON_HELMET.getDefaultStack()); minion.equipStack(EquipmentSlot.HEAD, Items.IRON_HELMET.getDefaultStack());
Equine.of(minion).filter(eq -> eq instanceof Creature).ifPresent(eq -> { Equine.of(minion).filter(eq -> eq instanceof Creature).ifPresent(eq -> {
((Creature)eq).setMaster(source); ((Creature)eq).setMaster(source.getMaster());
}); });
source.asWorld().spawnEntity(minion); source.asWorld().spawnEntity(minion);

View file

@ -4,6 +4,8 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
@ -107,6 +109,7 @@ public class SiphoningSpell extends AbstractAreaEffectSpell {
} }
private void collectHealth(Caster<?> source) { private void collectHealth(Caster<?> source) {
@Nullable
LivingEntity owner = source.getMaster(); LivingEntity owner = source.getMaster();
float maxHealthGain = owner == null ? 0 : owner.getMaxHealth() - owner.getHealth(); float maxHealthGain = owner == null ? 0 : owner.getMaxHealth() - owner.getHealth();

View file

@ -171,7 +171,7 @@ public class WorldRenderDelegate {
matrices.pop(); matrices.pop();
if (pony instanceof Living && pony.getPhysics().isGravityNegative()) { if (pony instanceof Living && pony.getPhysics().isGravityNegative()) {
flipAngles(((Living<?>)pony).getMaster()); flipAngles(pony.asEntity());
} }
} }
} }

View file

@ -23,7 +23,7 @@ import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.world.World; import net.minecraft.world.World;
public class CastSpellEntity extends LightEmittingEntity implements Caster<CastSpellEntity>, WeaklyOwned<LivingEntity> { public class CastSpellEntity extends LightEmittingEntity implements Caster<CastSpellEntity>, WeaklyOwned.Mutable<LivingEntity> {
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.FLOAT); private static final TrackedData<Float> GRAVITY = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
@ -88,6 +88,11 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
setMaster(caster); setMaster(caster);
} }
@Override
public LivingEntity getMaster() {
return WeaklyOwned.Mutable.super.getMaster();
}
@Override @Override
public LevelStore getLevel() { public LevelStore getLevel() {
return level; return level;

View file

@ -33,7 +33,7 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class Creature extends Living<LivingEntity> implements WeaklyOwned<LivingEntity> { public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutable<LivingEntity> {
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
private static final TrackedData<NbtCompound> MASTER = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); private static final TrackedData<NbtCompound> MASTER = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
public static final TrackedData<Float> GRAVITY = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.FLOAT); public static final TrackedData<Float> GRAVITY = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.FLOAT);

View file

@ -53,7 +53,7 @@ public class Enchantments implements NbtSerialisable, Tickable {
@Override @Override
public void tick() { public void tick() {
UEnchantments.REGISTRY.forEach(ench -> { UEnchantments.REGISTRY.forEach(ench -> {
int level = EnchantmentHelper.getEquipmentLevel(ench, entity.getMaster()); int level = EnchantmentHelper.getEquipmentLevel(ench, entity.asEntity());
boolean active = level > 0; boolean active = level > 0;

View file

@ -41,7 +41,7 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent; import net.minecraft.world.event.GameEvent;
public class FairyEntity extends PathAwareEntity implements DynamicLightSource, WeaklyOwned<LivingEntity> { public class FairyEntity extends PathAwareEntity implements DynamicLightSource, WeaklyOwned.Mutable<LivingEntity> {
private final EntityReference<LivingEntity> owner = new EntityReference<>(); private final EntityReference<LivingEntity> owner = new EntityReference<>();
private final EntityReference<LivingEntity> assignment = new EntityReference<>(); private final EntityReference<LivingEntity> assignment = new EntityReference<>();

View file

@ -108,11 +108,11 @@ public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider
if (source instanceof Pony) { if (source instanceof Pony) {
Pony player = (Pony)source; Pony player = (Pony)source;
source.getMaster().setInvisible(true); source.asEntity().setInvisible(true);
player.setInvisible(true); player.setInvisible(true);
if (entity instanceof Owned) { if (entity instanceof Owned.Mutable) {
((Owned<LivingEntity>)entity).setMaster(player); ((Owned.Mutable<LivingEntity>)entity).setMaster(player);
} }
if (entity instanceof PlayerEntity) { if (entity instanceof PlayerEntity) {
@ -120,7 +120,7 @@ public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider
} }
} }
return !isDead() && !source.getMaster().isDead(); return !isDead() && !source.asEntity().isDead();
} }
public static abstract class PlayerAccess extends PlayerEntity { public static abstract class PlayerAccess extends PlayerEntity {

View file

@ -16,7 +16,7 @@ public class EndermanBehaviour extends EntityBehaviour<EndermanEntity> {
entity.setTarget(null); entity.setTarget(null);
} }
ItemStack stack = source.getMaster().getStackInHand(Hand.MAIN_HAND); ItemStack stack = source.asEntity().getStackInHand(Hand.MAIN_HAND);
if (stack.getItem() instanceof BlockItem bi) { if (stack.getItem() instanceof BlockItem bi) {
entity.setCarriedBlock(bi.getBlock().getDefaultState()); entity.setCarriedBlock(bi.getBlock().getDefaultState());
} else { } else {

View file

@ -134,7 +134,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
remove(); remove();
entity = InteractionManager.instance().createPlayer(source.asEntity(), profile); entity = InteractionManager.instance().createPlayer(source.asEntity(), profile);
entity.setCustomName(source.getMaster().getName()); entity.setCustomName(source.asEntity().getName());
((PlayerEntity)entity).readNbt(nbt.getCompound("playerNbt")); ((PlayerEntity)entity).readNbt(nbt.getCompound("playerNbt"));
if (nbt.contains("playerVisibleParts", NbtElement.BYTE_TYPE)) { if (nbt.contains("playerVisibleParts", NbtElement.BYTE_TYPE)) {
entity.getDataTracker().set(Disguise.PlayerAccess.getModelBitFlag(), nbt.getByte("playerVisibleParts")); entity.getDataTracker().set(Disguise.PlayerAccess.getModelBitFlag(), nbt.getByte("playerVisibleParts"));

View file

@ -42,7 +42,7 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
} }
if (nearby > 1) { if (nearby > 1) {
if (Equine.of(entity).filter(eq -> eq instanceof Owned<?> o && o.hasMaster()).isPresent()) { if (Equine.of(entity).filter(eq -> eq instanceof Owned<?> o && o.getMaster() != null).isPresent()) {
return; return;
} }
@ -59,8 +59,8 @@ public class CorruptInfluenceStatusEffect extends StatusEffect {
clone.copyPositionAndRotation(entity); clone.copyPositionAndRotation(entity);
Equine.of(clone).ifPresent(eq -> { Equine.of(clone).ifPresent(eq -> {
if (eq instanceof Owned) { if (eq instanceof Owned.Mutable) {
((Owned<Entity>)eq).setMaster(mob); ((Owned.Mutable<Entity>)eq).setMaster(mob);
} }
}); });
mob.world.spawnEntity(clone); mob.world.spawnEntity(clone);

View file

@ -288,23 +288,11 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
return interpolator; return interpolator;
} }
/**
* @deprecated use asEntity()
*/
@Override @Override
@Deprecated(forRemoval = true)
public final LivingEntity getMaster() { public final LivingEntity getMaster() {
return asEntity(); return asEntity();
} }
/**
* @deprecated Pony cannot belong to other entities
*/
@Override
@Deprecated
public void setMaster(@Nullable LivingEntity owner) {
}
public void onSpawn() { public void onSpawn() {
if (entity.world instanceof ServerWorld sw if (entity.world instanceof ServerWorld sw
&& getObservedSpecies() == Race.BAT && getObservedSpecies() == Race.BAT

View file

@ -16,7 +16,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.GameMode; import net.minecraft.world.GameMode;
public class DummyClientPlayerEntity extends AbstractClientPlayerEntity implements Owned<PlayerEntity> { public class DummyClientPlayerEntity extends AbstractClientPlayerEntity implements Owned<PlayerEntity>, Owned.Mutable<PlayerEntity> {
private PlayerListEntry playerInfo; private PlayerListEntry playerInfo;

View file

@ -12,7 +12,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class DummyPlayerEntity extends PlayerEntity implements Owned<PlayerEntity> { public class DummyPlayerEntity extends PlayerEntity implements Owned<PlayerEntity>, Owned.Mutable<PlayerEntity> {
private PlayerEntity owner; private PlayerEntity owner;

View file

@ -116,7 +116,9 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
@Override @Override
public void onUnequipped(Living<?> wearer, long timeWorn) { public void onUnequipped(Living<?> wearer, long timeWorn) {
if (wearer.getMaster() instanceof PlayerEntity player && player.isCreative()) { LivingEntity entity = wearer.asEntity();
if (entity instanceof PlayerEntity player && player.isCreative()) {
return; return;
} }
@ -125,24 +127,24 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
LocalDifficulty difficulty = wearer.asWorld().getLocalDifficulty(wearer.getOrigin()); LocalDifficulty difficulty = wearer.asWorld().getLocalDifficulty(wearer.getOrigin());
float amount = attachedTime * (1 + difficulty.getClampedLocalDifficulty()); float amount = attachedTime * (1 + difficulty.getClampedLocalDifficulty());
amount = Math.min(amount, wearer.getMaster().getMaxHealth()); amount = Math.min(amount, entity.getMaxHealth());
if (wearer.getMaster() instanceof PlayerEntity) { if (entity instanceof PlayerEntity player) {
((PlayerEntity)wearer.getMaster()).getHungerManager().setFoodLevel(1); player.getHungerManager().setFoodLevel(1);
} }
wearer.getMaster().damage(MagicalDamageSource.ALICORN_AMULET, amount); entity.damage(MagicalDamageSource.ALICORN_AMULET, amount);
wearer.getMaster().addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 200, 1)); entity.addStatusEffect(new StatusEffectInstance(StatusEffects.NAUSEA, 200, 1));
if (timeWorn > ItemTracker.HOURS) { if (timeWorn > ItemTracker.HOURS) {
wearer.getMaster().addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 200, 3)); entity.addStatusEffect(new StatusEffectInstance(StatusEffects.WEAKNESS, 200, 3));
} }
if (attachedTime > 120) { if (attachedTime > 120) {
wearer.getMaster().takeKnockback(1, 1, 1); entity.takeKnockback(1, 1, 1);
wearer.updateVelocity(); wearer.updateVelocity();
} }
EFFECT_SCALES.keySet().forEach(attribute -> { EFFECT_SCALES.keySet().forEach(attribute -> {
EntityAttributeInstance instance = wearer.getMaster().getAttributeInstance(attribute); EntityAttributeInstance instance = entity.getAttributeInstance(attribute);
@Nullable @Nullable
EntityAttributeModifier modifier = instance.getModifier(EFFECT_UUID); EntityAttributeModifier modifier = instance.getModifier(EFFECT_UUID);
if (modifier != null) { if (modifier != null) {
@ -207,8 +209,8 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
reserves.getExertion().add(reserves.getExertion().getMax()); reserves.getExertion().add(reserves.getExertion().getMax());
reserves.getEnergy().add(reserves.getEnergy().getMax() / 2F); reserves.getEnergy().add(reserves.getEnergy().getMax() / 2F);
living.getMaster().removeStatusEffect(StatusEffects.WEAKNESS); living.asEntity().removeStatusEffect(StatusEffects.WEAKNESS);
living.getMaster().removeStatusEffect(StatusEffects.NAUSEA); living.asEntity().removeStatusEffect(StatusEffects.NAUSEA);
} }
if (!poweringUp) { if (!poweringUp) {
@ -226,7 +228,7 @@ public class AlicornAmuletItem extends AmuletItem implements ItemTracker.Trackab
if (fullSecond) { if (fullSecond) {
EFFECT_SCALES.entrySet().forEach(attribute -> { EFFECT_SCALES.entrySet().forEach(attribute -> {
float seconds = (float)attachedTicks / ItemTracker.SECONDS; float seconds = (float)attachedTicks / ItemTracker.SECONDS;
EntityAttributeInstance instance = living.getMaster().getAttributeInstance(attribute.getKey()); EntityAttributeInstance instance = living.asEntity().getAttributeInstance(attribute.getKey());
@Nullable @Nullable
EntityAttributeModifier modifier = instance.getModifier(EFFECT_UUID); EntityAttributeModifier modifier = instance.getModifier(EFFECT_UUID);
float desiredValue = attribute.getValue() * seconds; float desiredValue = attribute.getValue() * seconds;

View file

@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.entity.Living;
import net.minecraft.enchantment.EnchantmentTarget; import net.minecraft.enchantment.EnchantmentTarget;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributeModifier;
@ -34,9 +33,8 @@ public class AttributedEnchantment extends SimpleEnchantment {
@Override @Override
public void onUserTick(Living<?> user, int level) { public void onUserTick(Living<?> user, int level) {
if (shouldChangeModifiers(user, level)) { if (shouldChangeModifiers(user, level)) {
LivingEntity entity = user.getMaster();
modifiers.forEach((attr, modifierSupplier) -> { modifiers.forEach((attr, modifierSupplier) -> {
EntityAttributeInstance instance = entity.getAttributeInstance(attr); EntityAttributeInstance instance = user.asEntity().getAttributeInstance(attr);
EntityAttributeModifier modifier = modifierSupplier.get(user, level); EntityAttributeModifier modifier = modifierSupplier.get(user, level);
@ -48,9 +46,8 @@ public class AttributedEnchantment extends SimpleEnchantment {
@Override @Override
public void onUnequipped(Living<?> user) { public void onUnequipped(Living<?> user) {
LivingEntity entity = user.getMaster();
modifiers.forEach((attr, modifierSupplier) -> { modifiers.forEach((attr, modifierSupplier) -> {
EntityAttributeInstance instance = entity.getAttributeInstance(attr); EntityAttributeInstance instance = user.asEntity().getAttributeInstance(attr);
instance.tryRemoveModifier(modifierSupplier.get(user, 1).getId()); instance.tryRemoveModifier(modifierSupplier.get(user, 1).getId());
}); });

View file

@ -46,8 +46,8 @@ public class ClientNetworkHandlerImpl implements ClientNetworkHandler {
entity.setId(packet.getId()); entity.setId(packet.getId());
entity.setUuid(packet.getUuid()); entity.setUuid(packet.getUuid());
if (entity instanceof Owned) { if (entity instanceof Owned.Mutable) {
((Owned<Entity>) entity).setMaster(world.getEntityById(packet.getEntityData())); ((Owned.Mutable<Entity>) entity).setMaster(world.getEntityById(packet.getEntityData()));
} }
if (entity.getType() == UEntities.MAGIC_BEAM) { if (entity.getType() == UEntities.MAGIC_BEAM) {

View file

@ -7,6 +7,7 @@ import java.util.function.Function;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.Owned;
import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Levelled; import com.minelittlepony.unicopia.ability.magic.Levelled;
@ -52,7 +53,7 @@ import net.minecraft.world.World;
* *
* Can also carry a spell if needed. * Can also carry a spell if needed.
*/ */
public class MagicProjectileEntity extends ThrownItemEntity implements Caster<MagicProjectileEntity> { public class MagicProjectileEntity extends ThrownItemEntity implements Caster<MagicProjectileEntity>, Owned.Mutable<LivingEntity> {
private static final TrackedData<Float> DAMAGE = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT); private static final TrackedData<Float> DAMAGE = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT); private static final TrackedData<Float> GRAVITY = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN); private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN);