Unicorns can now shoot a spell as a projectile

This commit is contained in:
Sollace 2020-10-08 19:22:20 +02:00
parent 3f95f72d6c
commit 301acdf1d2
59 changed files with 297 additions and 269 deletions

View file

@ -10,10 +10,10 @@ public interface Owned<E> {
/** /**
* Updates the owner of this object. * Updates the owner of this object.
*/ */
void setOwner(E owner); void setMaster(E owner);
/** /**
* Gets the owner that holds this object. * Gets the owner that holds this object.
*/ */
E getOwner(); E getMaster();
} }

View file

@ -17,6 +17,7 @@ public interface Abilities {
// unicorn / alicorn // unicorn / alicorn
Ability<?> CAST = register(new UnicornCastingAbility(), "cast", AbilitySlot.PRIMARY); Ability<?> CAST = register(new UnicornCastingAbility(), "cast", AbilitySlot.PRIMARY);
Ability<?> TELEPORT = register(new UnicornTeleportAbility(), "teleport", AbilitySlot.SECONDARY); Ability<?> TELEPORT = register(new UnicornTeleportAbility(), "teleport", AbilitySlot.SECONDARY);
Ability<?> SHOOT = register(new UnicornProjectileAbility(), "shoot", AbilitySlot.TERTIARY);
// earth / alicorn // earth / alicorn
Ability<?> GROW = register(new EarthPonyGrowAbility(), "grow", AbilitySlot.SECONDARY); Ability<?> GROW = register(new EarthPonyGrowAbility(), "grow", AbilitySlot.SECONDARY);

View file

@ -73,13 +73,13 @@ public class BatEeeeAbility implements Ability<Hit> {
Vec3d origin = player.getOriginVector(); Vec3d origin = player.getOriginVector();
if (rng.nextInt(20000) == 0) { if (rng.nextInt(20000) == 0) {
player.getOwner().damage(MagicalDamageSource.create("eeee", player.getOwner()), 0.1F); player.getMaster().damage(MagicalDamageSource.create("eeee", player.getMaster()), 0.1F);
} }
player.findAllEntitiesInRange(5).forEach(e -> { player.findAllEntitiesInRange(5).forEach(e -> {
if (e instanceof LivingEntity && !HAS_SHIELD.test(e)) { if (e instanceof LivingEntity && !HAS_SHIELD.test(e)) {
boolean isEarthPony = EquinePredicates.PLAYER_EARTH.test(e); boolean isEarthPony = EquinePredicates.PLAYER_EARTH.test(e);
e.damage(MagicalDamageSource.create("eeee", player.getOwner()), isEarthPony ? 0.1F : 0.3F); e.damage(MagicalDamageSource.create("eeee", player.getMaster()), isEarthPony ? 0.1F : 0.3F);
Vec3d knockVec = origin.subtract(e.getPos()); Vec3d knockVec = origin.subtract(e.getPos());
((LivingEntity) e).takeKnockback(isEarthPony ? 0.3F : 0.5F, knockVec.getX(), knockVec.getZ()); ((LivingEntity) e).takeKnockback(isEarthPony ? 0.3F : 0.5F, knockVec.getX(), knockVec.getZ());

View file

@ -39,7 +39,7 @@ public class BatPonyHangAbility implements Ability<Multi> {
return new Multi(BlockPos.ZERO, 0); return new Multi(BlockPos.ZERO, 0);
} }
BlockPos poss = RayTraceHelper.doTrace(player.getOwner(), 3, 1, EntityPredicates.EXCEPT_SPECTATOR).getBlockPos().orElse(null); BlockPos poss = RayTraceHelper.doTrace(player.getMaster(), 3, 1, EntityPredicates.EXCEPT_SPECTATOR).getBlockPos().orElse(null);
if (poss != null) { if (poss != null) {
boolean air = player.getWorld().isAir(poss.down()) && player.getWorld().isAir(poss.down(2)); boolean air = player.getWorld().isAir(poss.down()) && player.getWorld().isAir(poss.down(2));
@ -48,7 +48,7 @@ public class BatPonyHangAbility implements Ability<Multi> {
} }
} }
return RayTraceHelper.doTrace(player.getOwner(), 5, 1, EntityPredicates.EXCEPT_SPECTATOR).getBlockPos() return RayTraceHelper.doTrace(player.getMaster(), 5, 1, EntityPredicates.EXCEPT_SPECTATOR).getBlockPos()
.map(BlockPos::down) .map(BlockPos::down)
.filter(pos -> player.getWorld().isAir(pos) && player.getWorld().isAir(pos.down()) && player.canHangAt(pos)) .filter(pos -> player.getWorld().isAir(pos) && player.getWorld().isAir(pos.down()) && player.canHangAt(pos))
.map(pos -> new Multi(pos, 1)) .map(pos -> new Multi(pos, 1))
@ -62,7 +62,7 @@ public class BatPonyHangAbility implements Ability<Multi> {
@Override @Override
public void apply(Pony player, Multi data) { public void apply(Pony player, Multi data) {
EntityAttributeInstance attr = player.getOwner().getAttributeInstance(PlayerAttributes.ENTITY_GRAVTY_MODIFIER); EntityAttributeInstance attr = player.getMaster().getAttributeInstance(PlayerAttributes.ENTITY_GRAVTY_MODIFIER);
if (data.hitType == 0 && attr.hasModifier(PlayerAttributes.BAT_HANGING)) { if (data.hitType == 0 && attr.hasModifier(PlayerAttributes.BAT_HANGING)) {
attr.removeModifier(PlayerAttributes.BAT_HANGING); attr.removeModifier(PlayerAttributes.BAT_HANGING);
@ -70,8 +70,8 @@ public class BatPonyHangAbility implements Ability<Multi> {
} }
if (data.hitType == 1 && player.canHangAt(data.pos())) { if (data.hitType == 1 && player.canHangAt(data.pos())) {
player.getOwner().teleport(data.x + 0.5, data.y - 2, data.z + 0.5); player.getMaster().teleport(data.x + 0.5, data.y - 2, data.z + 0.5);
player.getOwner().setVelocity(Vec3d.ZERO); player.getMaster().setVelocity(Vec3d.ZERO);
if (!attr.hasModifier(PlayerAttributes.BAT_HANGING)) { if (!attr.hasModifier(PlayerAttributes.BAT_HANGING)) {
attr.addPersistentModifier(PlayerAttributes.BAT_HANGING); attr.addPersistentModifier(PlayerAttributes.BAT_HANGING);

View file

@ -48,7 +48,7 @@ public class CarryAbility implements Ability<Hit> {
@Override @Override
public void apply(Pony iplayer, Hit data) { public void apply(Pony iplayer, Hit data) {
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getMaster();
LivingEntity rider = findRider(player, iplayer.getWorld()); LivingEntity rider = findRider(player, iplayer.getWorld());
if (rider != null) { if (rider != null) {

View file

@ -33,7 +33,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
@Override @Override
public void apply(Pony iplayer, Hit data) { public void apply(Pony iplayer, Hit data) {
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getMaster();
if (iplayer.getMagicalReserves().getMana().getPercentFill() < 0.9F) { if (iplayer.getMagicalReserves().getMana().getPercentFill() < 0.9F) {
return; return;

View file

@ -60,7 +60,7 @@ public class ChangelingFeedAbility implements Ability<Hit> {
} }
private boolean canFeed(Pony player) { private boolean canFeed(Pony player) {
return player.getOwner().getHealth() < player.getOwner().getMaxHealth() || player.getOwner().canConsume(false); return player.getMaster().getHealth() < player.getMaster().getMaxHealth() || player.getMaster().canConsume(false);
} }
private boolean canDrain(Entity e) { private boolean canDrain(Entity e) {
@ -79,9 +79,9 @@ public class ChangelingFeedAbility implements Ability<Hit> {
} }
protected List<LivingEntity> getTargets(Pony player) { protected List<LivingEntity> getTargets(Pony player) {
List<Entity> list = VecHelper.findInReach(player.getOwner(), 3, this::canDrain); List<Entity> list = VecHelper.findInReach(player.getMaster(), 3, this::canDrain);
RayTraceHelper.<LivingEntity>findEntity(player.getOwner(), 17, 1, RayTraceHelper.<LivingEntity>findEntity(player.getMaster(), 17, 1,
looked -> looked instanceof LivingEntity && !list.contains(looked) && canDrain(looked)) looked -> looked instanceof LivingEntity && !list.contains(looked) && canDrain(looked))
.ifPresent(list::add); .ifPresent(list::add);
@ -90,7 +90,7 @@ public class ChangelingFeedAbility implements Ability<Hit> {
@Override @Override
public void apply(Pony iplayer, Hit data) { public void apply(Pony iplayer, Hit data) {
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getMaster();
float maximumHealthGain = player.getMaxHealth() - player.getHealth(); float maximumHealthGain = player.getMaxHealth() - player.getHealth();
int maximumFoodGain = player.canConsume(false) ? (20 - player.getHungerManager().getFoodLevel()) : 0; int maximumFoodGain = player.canConsume(false) ? (20 - player.getHungerManager().getFoodLevel()) : 0;

View file

@ -36,7 +36,7 @@ public class EarthPonyGrowAbility implements Ability<Pos> {
@Override @Override
public Pos tryActivate(Pony player) { public Pos tryActivate(Pony player) {
return RayTraceHelper.doTrace(player.getOwner(), 3, 1).getBlockPos().map(Pos::new).orElse(null); return RayTraceHelper.doTrace(player.getMaster(), 3, 1).getBlockPos().map(Pos::new).orElse(null);
} }
@Override @Override

View file

@ -69,7 +69,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
@Nullable @Nullable
@Override @Override
public Multi tryActivate(Pony player) { public Multi tryActivate(Pony player) {
Optional<BlockPos> p = RayTraceHelper.doTrace(player.getOwner(), 6, 1).getBlockPos(); Optional<BlockPos> p = RayTraceHelper.doTrace(player.getMaster(), 6, 1).getBlockPos();
if (p.isPresent()) { if (p.isPresent()) {
BlockPos pos = p.get(); BlockPos pos = p.get();
@ -83,8 +83,8 @@ public class EarthPonyStompAbility implements Ability<Multi> {
} }
} }
if (!player.getOwner().isOnGround() && !player.getOwner().abilities.flying) { if (!player.getMaster().isOnGround() && !player.getMaster().abilities.flying) {
player.getOwner().addVelocity(0, -6, 0); player.getMaster().addVelocity(0, -6, 0);
return new Multi(Vec3i.ZERO, 0); return new Multi(Vec3i.ZERO, 0);
} }
@ -100,7 +100,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
@Override @Override
public void apply(Pony iplayer, Multi data) { public void apply(Pony iplayer, Multi data) {
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getMaster();
if (data.hitType == 0) { if (data.hitType == 0) {
BlockPos ppos = player.getBlockPos(); BlockPos ppos = player.getBlockPos();
@ -191,8 +191,8 @@ public class EarthPonyStompAbility implements Ability<Multi> {
public void postApply(Pony player, AbilitySlot slot) { public void postApply(Pony player, AbilitySlot slot) {
int timeDiff = getCooldownTime(player) - player.getAbilities().getStat(slot).getRemainingCooldown(); int timeDiff = getCooldownTime(player) - player.getAbilities().getStat(slot).getRemainingCooldown();
if (player.getOwner().getEntityWorld().getTime() % 1 == 0 || timeDiff == 0) { if (player.getMaster().getEntityWorld().getTime() % 1 == 0 || timeDiff == 0) {
spawnParticleRing(player.getOwner(), timeDiff, 1); spawnParticleRing(player.getMaster(), timeDiff, 1);
} }
} }

View file

@ -44,7 +44,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
if (player.hasSpell()) { if (player.hasSpell()) {
String current = player.getSpell(true).getName(); String current = player.getSpell(true).getName();
player.setSpell(Streams.stream(player.getOwner().getItemsHand()) player.setSpell(Streams.stream(player.getMaster().getItemsHand())
.map(SpellRegistry::getKeyFromStack) .map(SpellRegistry::getKeyFromStack)
.filter(i -> i != null && !current.equals(i)) .filter(i -> i != null && !current.equals(i))
.map(SpellRegistry.instance()::getSpellFromName) .map(SpellRegistry.instance()::getSpellFromName)
@ -52,7 +52,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
.findFirst() .findFirst()
.orElse(null)); .orElse(null));
} else { } else {
player.setSpell(Streams.stream(player.getOwner().getItemsHand()) player.setSpell(Streams.stream(player.getMaster().getItemsHand())
.map(SpellRegistry.instance()::getSpellFrom) .map(SpellRegistry.instance()::getSpellFrom)
.filter(i -> i != null) .filter(i -> i != null)
.findFirst() .findFirst()

View file

@ -0,0 +1,68 @@
package com.minelittlepony.unicopia.ability;
import java.util.Optional;
import com.google.common.collect.Streams;
import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.data.Hit;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.ability.magic.spell.AttractiveSpell;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
/**
* A magic casting ability for unicorns.
* (only shields for now)
*/
public class UnicornProjectileAbility implements Ability<Hit> {
@Override
public int getWarmupTime(Pony player) {
return 4;
}
@Override
public int getCooldownTime(Pony player) {
return 0;
}
@Override
public boolean canUse(Race race) {
return race.canCast();
}
@Override
public Hit tryActivate(Pony player) {
return Hit.INSTANCE;
}
@Override
public Hit.Serializer<Hit> getSerializer() {
return Hit.SERIALIZER;
}
@Override
public void apply(Pony player, Hit data) {
getThrown(player).orElseGet(AttractiveSpell::new).toss(player);
}
private Optional<Thrown> getThrown(Pony player) {
return Streams.stream(player.getMaster().getItemsHand())
.map(SpellRegistry.instance()::getSpellFrom)
.filter(i -> i != null && i instanceof Thrown)
.map(Thrown.class::cast)
.findFirst();
}
@Override
public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().getEnergy().multiply(3.3F);
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
}
@Override
public void postApply(Pony player, AbilitySlot slot) {
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
}
}

View file

@ -45,8 +45,8 @@ public class UnicornTeleportAbility implements Ability<Pos> {
@Override @Override
public Pos tryActivate(Pony player) { public Pos tryActivate(Pony player) {
int maxDistance = player.getOwner().isCreative() ? 1000 : 100; int maxDistance = player.getMaster().isCreative() ? 1000 : 100;
HitResult ray = RayTraceHelper.doTrace(player.getOwner(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR).getResult(); HitResult ray = RayTraceHelper.doTrace(player.getMaster(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR).getResult();
World w = player.getWorld(); World w = player.getWorld();
@ -64,10 +64,10 @@ public class UnicornTeleportAbility implements Ability<Pos> {
boolean airAbove = enterable(w, pos.up()) && enterable(w, pos.up(2)); boolean airAbove = enterable(w, pos.up()) && enterable(w, pos.up(2));
if (exception(w, pos, player.getOwner())) { if (exception(w, pos, player.getMaster())) {
Direction sideHit = ((BlockHitResult)ray).getSide(); Direction sideHit = ((BlockHitResult)ray).getSide();
if (player.getOwner().isSneaking()) { if (player.getMaster().isSneaking()) {
sideHit = sideHit.getOpposite(); sideHit = sideHit.getOpposite();
} }
@ -89,8 +89,8 @@ public class UnicornTeleportAbility implements Ability<Pos> {
} }
} }
if ((!enterable(w, pos) && exception(w, pos, player.getOwner())) if ((!enterable(w, pos) && exception(w, pos, player.getMaster()))
|| (!enterable(w, pos.up()) && exception(w, pos.up(), player.getOwner()))) { || (!enterable(w, pos.up()) && exception(w, pos.up(), player.getMaster()))) {
return null; return null;
} }
@ -106,7 +106,7 @@ public class UnicornTeleportAbility implements Ability<Pos> {
public void apply(Pony iplayer, Pos data) { public void apply(Pony iplayer, Pos data) {
iplayer.getWorld().playSound(null, iplayer.getOrigin(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1); iplayer.getWorld().playSound(null, iplayer.getOrigin(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1);
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getMaster();
double distance = Math.sqrt(player.squaredDistanceTo(data.x, data.y, data.z)) / 10; double distance = Math.sqrt(player.squaredDistanceTo(data.x, data.y, data.z)) / 10;
if (player.hasVehicle()) { if (player.hasVehicle()) {

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.ability.magic;
/** /**
* A magic effect that does something when attached to an entity. * A magic effect that does something when attached to an entity.
*/ */
public interface AttachableSpell extends Spell { public interface Attached extends Spell {
/** /**
* Called every tick when attached to a player. * Called every tick when attached to a player.
* *

View file

@ -70,7 +70,7 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
*/ */
@Override @Override
default Entity getEntity() { default Entity getEntity() {
return getOwner(); return getMaster();
} }
/** /**
@ -96,8 +96,8 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
} }
default boolean subtractEnergyCost(double amount) { default boolean subtractEnergyCost(double amount) {
getOwner().damage(DamageSource.MAGIC, (int)amount/2); getMaster().damage(DamageSource.MAGIC, (int)amount/2);
return getOwner().getHealth() > 0; return getMaster().getHealth() > 0;
} }
default Stream<Caster<?>> findAllSpellsInRange(double radius) { default Stream<Caster<?>> findAllSpellsInRange(double radius) {

View file

@ -6,8 +6,6 @@ import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.UEntities; import com.minelittlepony.unicopia.UEntities;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.projectile.Projectile;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -17,17 +15,22 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
/** /**
* Magic effects that can be thrown. * Magic effects that can be thrown.
*/ */
public interface ThrowableSpell extends Spell { public interface Thrown extends Spell {
/** /**
* Called once the projectile lands either hitting the ground or an entity. * Called once the projectile lands either hitting the ground or an entity.
*/ */
void onImpact(Caster<?> caster, BlockPos pos, BlockState state); default void onImpact(Caster<?> caster, BlockPos pos, BlockState state) {
if (!caster.isClient()) {
update(caster);
}
}
/** /**
* The amount of damage to be dealt when the projectile collides with an entity. * The amount of damage to be dealt when the projectile collides with an entity.
@ -58,24 +61,29 @@ public interface ThrowableSpell extends Spell {
* Returns the resulting projectile entity for customization (or null if on the client). * Returns the resulting projectile entity for customization (or null if on the client).
*/ */
@Nullable @Nullable
default Projectile toss(Caster<?> caster) { default MagicProjectileEntity toss(Caster<?> caster) {
World world = caster.getWorld(); World world = caster.getWorld();
Entity entity = caster.getOwner(); Entity entity = caster.getMaster();
world.playSound(null, entity.getX(), entity.getY(), entity.getZ(), getThrowSound(caster), SoundCategory.NEUTRAL, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); world.playSound(null, entity.getX(), entity.getY(), entity.getZ(), getThrowSound(caster), SoundCategory.NEUTRAL, 0.7F, 0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
if (!caster.isClient()) { if (!caster.isClient()) {
Projectile projectile = new MagicProjectileEntity(UEntities.THROWN_ITEM, world, caster.getOwner()); Vec3d rot = entity.getRotationVec(1);
MagicProjectileEntity projectile = new MagicProjectileEntity(UEntities.THROWN_ITEM, world, caster.getMaster(), entity.getRotationVec(1));
projectile.setItem(getCastAppearance(caster)); projectile.setItem(getCastAppearance(caster));
projectile.setThrowDamage(getThrowDamage(caster)); projectile.setThrowDamage(getThrowDamage(caster));
projectile.setOwner(caster.getOwner()); projectile.setSpell(this);
projectile.setEffect(this);
projectile.setHydrophobic(); projectile.setHydrophobic();
projectile.launch(entity, entity.pitch, entity.yaw, 0, 1.5F, 1); projectile.updatePosition(
entity.getX() + rot.x * 4,
entity.getBodyY(0.5D) + 0.5,
projectile.getZ() + rot.z * 4
);
projectile.spawn(world); world.spawnEntity(projectile);
return projectile; return projectile;
} }

View file

@ -1,9 +1,9 @@
package com.minelittlepony.unicopia.ability.magic.spell; package com.minelittlepony.unicopia.ability.magic.spell;
import com.minelittlepony.unicopia.ability.magic.AttachableSpell; import com.minelittlepony.unicopia.ability.magic.Attached;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
public abstract class AbstractRangedAreaSpell extends AbstractSpell implements AttachableSpell { public abstract class AbstractRangedAreaSpell extends AbstractSpell implements Attached {
@Override @Override
public int getMaxLevelCutOff(Caster<?> source) { public int getMaxLevelCutOff(Caster<?> source) {

View file

@ -5,6 +5,7 @@ import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
@ -20,7 +21,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class AttractiveSpell extends ShieldSpell { public class AttractiveSpell extends ShieldSpell implements Thrown {
@Nullable @Nullable
private BlockPos homingPos; private BlockPos homingPos;

View file

@ -5,22 +5,20 @@ import java.util.List;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.ThrowableSpell; import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
import com.mojang.brigadier.StringReader; import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.BlockState;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleType; import net.minecraft.particle.ParticleType;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
public class AwkwardSpell extends AbstractSpell implements ThrowableSpell { public class AwkwardSpell extends AbstractSpell implements Thrown {
@Override @Override
public String getName() { public String getName() {
@ -70,10 +68,4 @@ public class AwkwardSpell extends AbstractSpell implements ThrowableSpell {
&& type != ParticleTypes.EXPLOSION_EMITTER && type != ParticleTypes.EXPLOSION_EMITTER
&& type != ParticleTypes.AMBIENT_ENTITY_EFFECT; && type != ParticleTypes.AMBIENT_ENTITY_EFFECT;
} }
@Override
public void onImpact(Caster<?> caster, BlockPos pos, BlockState state) {
// noop
}
} }

View file

@ -9,7 +9,7 @@ import com.minelittlepony.unicopia.FlightType;
import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.Owned;
import com.minelittlepony.unicopia.ability.FlightPredicate; import com.minelittlepony.unicopia.ability.FlightPredicate;
import com.minelittlepony.unicopia.ability.DimensionsPredicate; import com.minelittlepony.unicopia.ability.DimensionsPredicate;
import com.minelittlepony.unicopia.ability.magic.AttachableSpell; import com.minelittlepony.unicopia.ability.magic.Attached;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.Suppressable; import com.minelittlepony.unicopia.ability.magic.Suppressable;
@ -27,7 +27,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Suppressable, FlightPredicate, DimensionsPredicate { public class DisguiseSpell extends AbstractSpell implements Attached, Suppressable, FlightPredicate, DimensionsPredicate {
private final Disguise disguise = new Disguise(); private final Disguise disguise = new Disguise();
@ -101,7 +101,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public boolean update(Caster<?> source, boolean tick) { public boolean update(Caster<?> source, boolean tick) {
LivingEntity owner = source.getOwner(); LivingEntity owner = source.getMaster();
Entity entity = disguise.getAppearance(); Entity entity = disguise.getAppearance();
@ -159,11 +159,11 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
if (source instanceof Pony) { if (source instanceof Pony) {
Pony player = (Pony)source; Pony player = (Pony)source;
source.getOwner().setInvisible(true); source.getMaster().setInvisible(true);
player.setInvisible(true); player.setInvisible(true);
if (entity instanceof Owned) { if (entity instanceof Owned) {
((Owned<LivingEntity>)entity).setOwner(player.getOwner()); ((Owned<LivingEntity>)entity).setMaster(player.getMaster());
} }
if (entity instanceof PlayerEntity) { if (entity instanceof PlayerEntity) {
@ -171,7 +171,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
} }
} }
return !source.getOwner().isDead(); return !source.getMaster().isDead();
} }
@Override @Override

View file

@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Magical; 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.block.state.StateMaps;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.PosHelper; import com.minelittlepony.unicopia.util.PosHelper;
@ -28,11 +29,12 @@ import net.minecraft.tag.BlockTags;
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;
import net.minecraft.world.explosion.Explosion.DestructionType;
/** /**
* Simple fire spell that triggers an effect when used on a block. * Simple fire spell that triggers an effect when used on a block.
*/ */
public class FireSpell extends AbstractRangedAreaSpell { public class FireSpell extends AbstractRangedAreaSpell implements Thrown {
private static final Shape VISUAL_EFFECT_RANGE = new Sphere(false, 0.5); private static final Shape VISUAL_EFFECT_RANGE = new Sphere(false, 0.5);
private static final Shape EFFECT_RANGE = new Sphere(false, 4); private static final Shape EFFECT_RANGE = new Sphere(false, 4);
@ -52,6 +54,13 @@ public class FireSpell extends AbstractRangedAreaSpell {
return 0xFF5D00; return 0xFF5D00;
} }
@Override
public void onImpact(Caster<?> caster, BlockPos pos, BlockState state) {
if (!caster.isClient()) {
caster.getWorld().createExplosion(caster.getMaster(), pos.getX(), pos.getY(), pos.getZ(), 2, DestructionType.DESTROY);
}
}
@Override @Override
public boolean update(Caster<?> source) { public boolean update(Caster<?> source) {
return PosHelper.getAllInRegionMutable(source.getOrigin(), EFFECT_RANGE).reduce(false, return PosHelper.getAllInRegionMutable(source.getOrigin(), EFFECT_RANGE).reduce(false,

View file

@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.ability.magic.spell;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.block.state.StateMaps; import com.minelittlepony.unicopia.block.state.StateMaps;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.PosHelper; import com.minelittlepony.unicopia.util.PosHelper;
@ -22,7 +23,7 @@ import net.minecraft.tag.BlockTags;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
public class IceSpell extends AbstractRangedAreaSpell { public class IceSpell extends AbstractRangedAreaSpell implements Thrown {
private final int rad = 3; private final int rad = 3;
private final Shape effect_range = new Sphere(false, rad); private final Shape effect_range = new Sphere(false, rad);
@ -44,12 +45,12 @@ public class IceSpell extends AbstractRangedAreaSpell {
@Override @Override
public boolean update(Caster<?> source) { public boolean update(Caster<?> source) {
LivingEntity owner = source.getOwner(); LivingEntity owner = source.getMaster();
PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range) PosHelper.getAllInRegionMutable(source.getOrigin(), effect_range)
.forEach(i -> applyBlockSingle(owner, source.getWorld(), i)); .forEach(i -> applyBlockSingle(owner, source.getWorld(), i));
return applyEntities(source.getOwner(), source.getWorld(), source.getOrigin()); return applyEntities(source.getMaster(), source.getWorld(), source.getOrigin());
} }
@Override @Override

View file

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

View file

@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Suppressable; import com.minelittlepony.unicopia.ability.magic.Suppressable;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
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;
@ -14,7 +15,7 @@ import net.minecraft.util.math.Vec3d;
/** /**
* A spell for revealing changelings. * A spell for revealing changelings.
*/ */
public class RevealingSpell extends AbstractSpell { public class RevealingSpell extends AbstractSpell implements Thrown {
@Override @Override
public String getName() { public String getName() {

View file

@ -4,10 +4,9 @@ import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.ThrowableSpell;
import com.minelittlepony.unicopia.block.state.StateMaps; import com.minelittlepony.unicopia.block.state.StateMaps;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
import com.minelittlepony.unicopia.projectile.Projectile; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
import com.minelittlepony.unicopia.util.PosHelper; import com.minelittlepony.unicopia.util.PosHelper;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
@ -15,9 +14,8 @@ import net.minecraft.block.BlockState;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
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.explosion.Explosion.DestructionType;
public class ScorchSpell extends FireSpell implements ThrowableSpell { public class ScorchSpell extends FireSpell {
@Override @Override
public String getName() { public String getName() {
@ -62,20 +60,13 @@ public class ScorchSpell extends FireSpell implements ThrowableSpell {
@Override @Override
@Nullable @Nullable
public Projectile toss(Caster<?> caster) { public MagicProjectileEntity toss(Caster<?> caster) {
Projectile projectile = ThrowableSpell.super.toss(caster); MagicProjectileEntity projectile = super.toss(caster);
if (projectile != null) { if (projectile != null) {
projectile.setGravity(false); projectile.setNoGravity(true);
} }
return projectile; return projectile;
} }
@Override
public void onImpact(Caster<?> caster, BlockPos pos, BlockState state) {
if (!caster.isClient()) {
caster.getWorld().createExplosion(caster.getOwner(), pos.getX(), pos.getY(), pos.getZ(), 2, DestructionType.DESTROY);
}
}
} }

View file

@ -5,7 +5,7 @@ import java.util.stream.Collectors;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.EquinePredicates;
import com.minelittlepony.unicopia.ability.magic.AttachableSpell; import com.minelittlepony.unicopia.ability.magic.Attached;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.MagicParticleEffect;
@ -20,7 +20,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSpell { public class ShieldSpell extends AbstractRangedAreaSpell implements Attached {
private final ParticleHandle particlEffect = new ParticleHandle(); private final ParticleHandle particlEffect = new ParticleHandle();
@ -60,7 +60,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
public boolean updateOnPerson(Caster<?> source) { public boolean updateOnPerson(Caster<?> source) {
int costMultiplier = applyEntities(source); int costMultiplier = applyEntities(source);
if (costMultiplier > 0) { if (costMultiplier > 0) {
if (source.getOwner().age % 20 == 0) { if (source.getMaster().age % 20 == 0) {
double cost = 4 + (source.getLevel().get() * 2); double cost = 4 + (source.getLevel().get() * 2);
cost *= costMultiplier / 5F; cost *= costMultiplier / 5F;
@ -75,7 +75,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
} }
public double getDrawDropOffRange(Caster<?> source) { public double getDrawDropOffRange(Caster<?> source) {
float multiplier = (source.getOwner().isSneaking() ? 1 : 2); float multiplier = (source.getMaster().isSneaking() ? 1 : 2);
return (4 + (source.getLevel().get() * 2)) / multiplier; return (4 + (source.getLevel().get() * 2)) / multiplier;
} }
@ -87,14 +87,26 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
protected List<Entity> getTargets(Caster<?> source, double radius) { protected List<Entity> getTargets(Caster<?> source, double radius) {
Entity owner = source.getOwner(); Entity owner = source.getMaster();
boolean ownerIsValid = source.getAffinity() != Affinity.BAD && EquinePredicates.PLAYER_UNICORN.test(owner); boolean ownerIsValid = source.getAffinity() != Affinity.BAD && EquinePredicates.PLAYER_UNICORN.test(owner);
return source.findAllEntitiesInRange(radius) return source.findAllEntitiesInRange(radius)
.filter(entity -> !(ownerIsValid && ( .filter(entity -> {
entity.equals(owner) if (!ownerIsValid) {
|| (entity instanceof PlayerEntity && owner instanceof PlayerEntity && Pony.equal((PlayerEntity)entity, (PlayerEntity)owner))))) return true;
}
boolean ownerEquals = (
entity.equals(owner)
|| (entity instanceof PlayerEntity && owner instanceof PlayerEntity && Pony.equal((PlayerEntity)entity, (PlayerEntity)owner)));
if (!owner.isSneaking()) {
return ownerEquals;
}
return !ownerEquals;
})
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@ -121,7 +133,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
Vec3d pos = source.getOriginVector(); Vec3d pos = source.getOriginVector();
if (ProjectileUtil.isProjectile(target)) { if (ProjectileUtil.isProjectile(target)) {
if (!ProjectileUtil.isProjectileThrownBy(target, source.getOwner())) { if (!ProjectileUtil.isProjectileThrownBy(target, source.getMaster())) {
if (distance < 1) { if (distance < 1) {
target.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1); target.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1);
target.remove(); target.remove();
@ -164,7 +176,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
if (player.getSpecies().canUseEarth()) { if (player.getSpecies().canUseEarth()) {
force /= 2; force /= 2;
if (player.getOwner().isSneaking()) { if (player.getMaster().isSneaking()) {
force /= 6; force /= 6;
} }
} else if (player.getSpecies().canFly()) { } else if (player.getSpecies().canFly()) {

View file

@ -6,6 +6,7 @@ import java.util.stream.Collectors;
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;
import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.util.MagicalDamageSource; import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.unicopia.util.shape.Sphere; import com.minelittlepony.unicopia.util.shape.Sphere;
@ -20,7 +21,7 @@ import net.minecraft.util.math.Vec3d;
/** /**
* A spell that pulls health from other entities and delivers it to the caster. * A spell that pulls health from other entities and delivers it to the caster.
*/ */
public class SiphoningSpell extends AbstractRangedAreaSpell { public class SiphoningSpell extends AbstractRangedAreaSpell implements Thrown {
@Override @Override
public String getName() { public String getName() {
@ -37,7 +38,7 @@ public class SiphoningSpell extends AbstractRangedAreaSpell {
int radius = 4 + source.getLevel().get(); int radius = 4 + source.getLevel().get();
LivingEntity owner = source.getOwner(); LivingEntity owner = source.getMaster();
List<LivingEntity> target = source.findAllEntitiesInRange(radius) List<LivingEntity> target = source.findAllEntitiesInRange(radius)
.filter(e -> e instanceof LivingEntity) .filter(e -> e instanceof LivingEntity)
@ -130,5 +131,4 @@ public class SiphoningSpell extends AbstractRangedAreaSpell {
public Affinity getAffinity() { public Affinity getAffinity() {
return Affinity.NEUTRAL; return Affinity.NEUTRAL;
} }
} }

View file

@ -35,7 +35,7 @@ public class WorldRenderDelegate {
matrices.push(); matrices.push();
Entity owner = pony.getOwner(); Entity owner = pony.getMaster();
boolean negative = pony.getPhysics().isGravityNegative(); boolean negative = pony.getPhysics().isGravityNegative();
@ -54,7 +54,7 @@ public class WorldRenderDelegate {
matrices.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll)); matrices.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll));
} }
int fireTicks = pony.getOwner().doesRenderOnFire() ? 1 : 0; int fireTicks = pony.getMaster().doesRenderOnFire() ? 1 : 0;
return pony.getSpellOrEmpty(DisguiseSpell.class, true).map(effect -> { return pony.getSpellOrEmpty(DisguiseSpell.class, true).map(effect -> {
effect.update(pony, false); effect.update(pony, false);
@ -81,7 +81,7 @@ public class WorldRenderDelegate {
matrices.pop(); matrices.pop();
if (pony.getPhysics().isGravityNegative()) { if (pony.getPhysics().isGravityNegative()) {
flipAngles(pony.getOwner()); flipAngles(pony.getMaster());
} }
} }

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.entity;
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.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.ability.magic.AttachableSpell; import com.minelittlepony.unicopia.ability.magic.Attached;
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;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
@ -58,7 +58,7 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
@Override @Override
public void tick() { public void tick() {
if (hasSpell()) { if (hasSpell()) {
AttachableSpell effect = getSpell(AttachableSpell.class, true); Attached effect = getSpell(Attached.class, true);
if (effect != null) { if (effect != null) {
if (entity.getEntityWorld().isClient()) { if (entity.getEntityWorld().isClient()) {
@ -73,12 +73,12 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
} }
@Override @Override
public void setOwner(LivingEntity owner) { public void setMaster(LivingEntity owner) {
} }
@Override @Override
public LivingEntity getOwner() { public LivingEntity getMaster() {
return entity; return entity;
} }
@ -89,8 +89,8 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
@Override @Override
public Affinity getAffinity() { public Affinity getAffinity() {
if (getOwner() instanceof Affine) { if (getMaster() instanceof Affine) {
return ((Affine)getOwner()).getAffinity(); return ((Affine)getMaster()).getAffinity();
} }
return Affinity.NEUTRAL; return Affinity.NEUTRAL;
} }

View file

@ -39,7 +39,7 @@ public class EntityPhysics<T extends Equine<?> & Owned<? extends Entity>> implem
@Override @Override
public BlockPos getHeadPosition() { public BlockPos getHeadPosition() {
Entity entity = pony.getOwner(); Entity entity = pony.getMaster();
entity.setOnGround(false); entity.setOnGround(false);
@ -57,7 +57,7 @@ public class EntityPhysics<T extends Equine<?> & Owned<? extends Entity>> implem
return below; return below;
} }
} else { } else {
pony.getOwner().setOnGround(true); pony.getMaster().setOnGround(true);
} }
return pos; return pos;
@ -65,7 +65,7 @@ public class EntityPhysics<T extends Equine<?> & Owned<? extends Entity>> implem
@Override @Override
public void spawnSprintingParticles() { public void spawnSprintingParticles() {
Entity entity = pony.getOwner(); Entity entity = pony.getMaster();
BlockState state = entity.world.getBlockState(getHeadPosition()); BlockState state = entity.world.getBlockState(getHeadPosition());
if (state.getRenderType() != BlockRenderType.INVISIBLE) { if (state.getRenderType() != BlockRenderType.INVISIBLE) {
Vec3d vel = entity.getVelocity(); Vec3d vel = entity.getVelocity();

View file

@ -56,12 +56,12 @@ public class ItemImpl implements Equine<ItemEntity>, Owned<ItemEntity> {
@Override @Override
public Race getSpecies() { public Race getSpecies() {
return Race.fromId(getOwner().getDataTracker().get(ITEM_RACE)); return Race.fromId(getMaster().getDataTracker().get(ITEM_RACE));
} }
@Override @Override
public void setSpecies(Race race) { public void setSpecies(Race race) {
getOwner().getDataTracker().set(ITEM_RACE, race.ordinal()); getMaster().getDataTracker().set(ITEM_RACE, race.ordinal());
} }
@Override @Override
@ -78,12 +78,12 @@ public class ItemImpl implements Equine<ItemEntity>, Owned<ItemEntity> {
} }
@Override @Override
public void setOwner(ItemEntity owner) { public void setMaster(ItemEntity owner) {
} }
@Override @Override
public ItemEntity getOwner() { public ItemEntity getMaster() {
return owner; return owner;
} }

View file

@ -23,7 +23,7 @@ public class BeeBehaviour extends EntityBehaviour<BeeEntity> {
@Override @Override
public void update(Caster<?> source, BeeEntity entity, DisguiseSpell spell) { public void update(Caster<?> source, BeeEntity entity, DisguiseSpell spell) {
if (source.getOwner().isSneaking()) { if (source.getMaster().isSneaking()) {
entity.setAngerTime(10); entity.setAngerTime(10);
} else { } else {
entity.setAngerTime(0); entity.setAngerTime(0);

View file

@ -31,13 +31,13 @@ public class ChickenBehaviour extends EntityBehaviour<ChickenEntity> {
if (player.sneakingChanged()) { if (player.sneakingChanged()) {
ItemStack egg = entity.getEquippedStack(EquipmentSlot.OFFHAND); ItemStack egg = entity.getEquippedStack(EquipmentSlot.OFFHAND);
if (player.getOwner().isSneaking()) { if (player.getMaster().isSneaking()) {
if (egg.isEmpty()) { if (egg.isEmpty()) {
egg = new ItemStack(Items.EGG); egg = new ItemStack(Items.EGG);
int slot = player.getOwner().inventory.method_7371(egg); int slot = player.getMaster().inventory.method_7371(egg);
if (slot > -1) { if (slot > -1) {
player.getOwner().inventory.removeStack(slot, 1); player.getMaster().inventory.removeStack(slot, 1);
entity.playSound(SoundEvents.ENTITY_CHICKEN_EGG, entity.playSound(SoundEvents.ENTITY_CHICKEN_EGG,
1, 1,
(entity.world.random.nextFloat() - entity.world.random.nextFloat()) * 0.2F + 4 (entity.world.random.nextFloat() - entity.world.random.nextFloat()) * 0.2F + 4

View file

@ -103,7 +103,7 @@ public class Disguise implements NbtSerialisable {
remove(); remove();
entity = InteractionManager.instance().createPlayer(source.getEntity(), profile); entity = InteractionManager.instance().createPlayer(source.getEntity(), profile);
entity.setCustomName(source.getOwner().getName()); entity.setCustomName(source.getMaster().getName());
((PlayerEntity)entity).fromTag(nbt.getCompound("playerNbt")); ((PlayerEntity)entity).fromTag(nbt.getCompound("playerNbt"));
entity.setUuid(UUID.randomUUID()); entity.setUuid(UUID.randomUUID());
entity.extinguish(); entity.extinguish();
@ -171,7 +171,7 @@ public class Disguise implements NbtSerialisable {
if (entity instanceof Owned) { if (entity instanceof Owned) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Pony iplayer = Pony.of(((Owned<PlayerEntity>)entity).getOwner()); Pony iplayer = Pony.of(((Owned<PlayerEntity>)entity).getMaster());
return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType(); return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType();
} }

View file

@ -11,13 +11,13 @@ import net.minecraft.util.Hand;
public class EndermanBehaviour extends EntityBehaviour<EndermanEntity> { public class EndermanBehaviour extends EntityBehaviour<EndermanEntity> {
@Override @Override
public void update(Caster<?> source, EndermanEntity entity, DisguiseSpell spell) { public void update(Caster<?> source, EndermanEntity entity, DisguiseSpell spell) {
if (source.getOwner().isSneaking() || source.getOwner().isSprinting()) { if (source.getMaster().isSneaking() || source.getMaster().isSprinting()) {
entity.setTarget(entity); entity.setTarget(entity);
} else { } else {
entity.setTarget(null); entity.setTarget(null);
} }
ItemStack stack = source.getOwner().getStackInHand(Hand.MAIN_HAND); ItemStack stack = source.getMaster().getStackInHand(Hand.MAIN_HAND);
if (stack.getItem() instanceof BlockItem) { if (stack.getItem() instanceof BlockItem) {
entity.setCarriedBlock(((BlockItem)stack.getItem()).getBlock().getDefaultState()); entity.setCarriedBlock(((BlockItem)stack.getItem()).getBlock().getDefaultState());
} else { } else {

View file

@ -92,7 +92,7 @@ public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
Disguise disguise = spell.getDisguise(); Disguise disguise = spell.getDisguise();
List<Entity> attachments = disguise.getAttachments(); List<Entity> attachments = disguise.getAttachments();
if (attachments.size() > 0) { if (attachments.size() > 0) {
copyBaseAttributes(source.getOwner(), attachments.get(0), UP); copyBaseAttributes(source.getMaster(), attachments.get(0), UP);
} }
BlockEntity be = disguise.getBlockEntity(); BlockEntity be = disguise.getBlockEntity();

View file

@ -13,7 +13,7 @@ public class GhastBehaviour extends MobBehaviour<GhastEntity> {
public void update(Pony player, GhastEntity entity, DisguiseSpell spell) { public void update(Pony player, GhastEntity entity, DisguiseSpell spell) {
if (player.sneakingChanged()) { if (player.sneakingChanged()) {
boolean sneaking = player.getOwner().isSneaking(); boolean sneaking = player.getMaster().isSneaking();
entity.setShooting(sneaking); entity.setShooting(sneaking);
entity.setTarget(sneaking ? findTarget(player, entity) : null); entity.setTarget(sneaking ? findTarget(player, entity) : null);
@ -30,7 +30,7 @@ public class GhastBehaviour extends MobBehaviour<GhastEntity> {
FireballEntity proj = new FireballEntity(entity.world, entity, rot.getX(), rot.getY(), rot.getZ()); FireballEntity proj = new FireballEntity(entity.world, entity, rot.getX(), rot.getY(), rot.getZ());
proj.explosionPower = entity.getFireballStrength() * (player.getLevel().get() + 1); proj.explosionPower = entity.getFireballStrength() * (player.getLevel().get() + 1);
proj.setOwner(player.getOwner()); proj.setOwner(player.getMaster());
proj.updatePosition( proj.updatePosition(
entity.getX() + rot.x * 4, entity.getX() + rot.x * 4,
entity.getBodyY(0.5D) + 0.5, entity.getBodyY(0.5D) + 0.5,

View file

@ -13,7 +13,7 @@ public class HoppingBehaviour extends EntityBehaviour<LivingEntity> {
if (player.getEntity().isOnGround()) { if (player.getEntity().isOnGround()) {
if (Entity.squaredHorizontalLength(player.getEntity().getVelocity()) > 0.01) { if (Entity.squaredHorizontalLength(player.getEntity().getVelocity()) > 0.01) {
player.getOwner().jump(); player.getMaster().jump();
if (entity instanceof RabbitEntity) { if (entity instanceof RabbitEntity) {
((RabbitEntity)entity).startJump(); ((RabbitEntity)entity).startJump();
} }

View file

@ -22,13 +22,13 @@ public class MobBehaviour<T extends MobEntity> extends EntityBehaviour<T> {
if (player.sneakingChanged() && isSneakingOnGround(player)) { if (player.sneakingChanged() && isSneakingOnGround(player)) {
LivingEntity target = findTarget(player, entity); LivingEntity target = findTarget(player, entity);
entity.tryAttack(target); entity.tryAttack(target);
target.setAttacker(player.getOwner()); target.setAttacker(player.getMaster());
} }
} }
protected LivingEntity findTarget(Pony player, T entity) { protected LivingEntity findTarget(Pony player, T entity) {
return RayTraceHelper.<LivingEntity>findEntity(player.getEntity(), 6, 1, return RayTraceHelper.<LivingEntity>findEntity(player.getEntity(), 6, 1,
e -> e instanceof LivingEntity && e != entity && e != player.getOwner()) e -> e instanceof LivingEntity && e != entity && e != player.getMaster())
.orElseGet(() -> getDummy(entity)); .orElseGet(() -> getDummy(entity));
} }

View file

@ -32,7 +32,7 @@ public class RangedAttackBehaviour<T extends Entity & RangedAttackMob> extends E
Vec3d rot = player.getEntity().getRotationVec(1); Vec3d rot = player.getEntity().getRotationVec(1);
spit.setVelocity(rot.getX(), rot.getY(), rot.getZ(), 1.5F, 3); spit.setVelocity(rot.getX(), rot.getY(), rot.getZ(), 1.5F, 3);
spit.setOwner(player.getOwner()); spit.setOwner(player.getMaster());
if (!entity.isSilent()) { if (!entity.isSilent()) {
entity.world.playSound(null, entity.getX(), entity.getY(), entity.getZ(), entity.world.playSound(null, entity.getX(), entity.getY(), entity.getZ(),

View file

@ -27,7 +27,7 @@ public class SheepBehaviour extends EntityBehaviour<SheepEntity> {
BlockState state = entity.world.getBlockState(pos); BlockState state = entity.world.getBlockState(pos);
boolean grass = state.isOf(Blocks.GRASS_BLOCK); boolean grass = state.isOf(Blocks.GRASS_BLOCK);
if (player.getOwner().isSneaking()) { if (player.getMaster().isSneaking()) {
if (grass && entity.world.isClient && entity.isSheared()) { if (grass && entity.world.isClient && entity.isSheared()) {
entity.handleStatus((byte)10); entity.handleStatus((byte)10);
} }
@ -40,11 +40,11 @@ public class SheepBehaviour extends EntityBehaviour<SheepEntity> {
} else if (!entity.isSheared()) { } else if (!entity.isSheared()) {
ItemStack dropType = new ItemStack(MixinSheepEntity.getDrops().get(entity.getColor()).asItem()); ItemStack dropType = new ItemStack(MixinSheepEntity.getDrops().get(entity.getColor()).asItem());
player.getOwner().playSound(SoundEvents.ENTITY_SHEEP_SHEAR, SoundCategory.PLAYERS, 1, 1); player.getMaster().playSound(SoundEvents.ENTITY_SHEEP_SHEAR, SoundCategory.PLAYERS, 1, 1);
entity.setSheared(true); entity.setSheared(true);
Random rng = entity.world.random; Random rng = entity.world.random;
PlayerInventory inv = player.getOwner().inventory; PlayerInventory inv = player.getMaster().inventory;
int dropAmount = rng.nextInt(3); int dropAmount = rng.nextInt(3);
int slot; int slot;

View file

@ -12,7 +12,7 @@ import net.minecraft.util.math.BlockPos;
public class SilverfishBehaviour extends EntityBehaviour<SilverfishEntity> { public class SilverfishBehaviour extends EntityBehaviour<SilverfishEntity> {
@Override @Override
public void update(Pony player, SilverfishEntity entity, DisguiseSpell spell) { public void update(Pony player, SilverfishEntity entity, DisguiseSpell spell) {
if (!player.isClient() && player.sneakingChanged() && player.getOwner().isSneaking()) { if (!player.isClient() && player.sneakingChanged() && player.getMaster().isSneaking()) {
BlockPos pos = entity.getBlockPos().down(); BlockPos pos = entity.getBlockPos().down();
BlockState state = entity.world.getBlockState(pos); BlockState state = entity.world.getBlockState(pos);

View file

@ -9,7 +9,7 @@ public class SpellcastingIllagerBehaviour extends EntityBehaviour<SpellcastingIl
@Override @Override
public void update(Pony player, SpellcastingIllagerEntity entity, DisguiseSpell s) { public void update(Pony player, SpellcastingIllagerEntity entity, DisguiseSpell s) {
if (player.sneakingChanged()) { if (player.sneakingChanged()) {
if (player.getOwner().isSneaking()) { if (player.getMaster().isSneaking()) {
SpellcastingIllagerEntity.Spell[] spells = SpellcastingIllagerEntity.Spell.values(); SpellcastingIllagerEntity.Spell[] spells = SpellcastingIllagerEntity.Spell.values();
SpellcastingIllagerEntity.Spell spell = spells[entity.world.random.nextInt(spells.length - 1) + 1]; SpellcastingIllagerEntity.Spell spell = spells[entity.world.random.nextInt(spells.length - 1) + 1];

View file

@ -14,7 +14,7 @@ public class SteedBehaviour<T extends LivingEntity & JumpingMount> extends Entit
HorseBaseEntity horse = ((HorseBaseEntity)entity); HorseBaseEntity horse = ((HorseBaseEntity)entity);
boolean angry = !player.getEntity().isOnGround() && player.getOwner().isSprinting(); boolean angry = !player.getEntity().isOnGround() && player.getMaster().isSprinting();
boolean sneaking = isSneakingOnGround(player); boolean sneaking = isSneakingOnGround(player);
angry |= sneaking; angry |= sneaking;

View file

@ -9,7 +9,7 @@ import net.minecraft.sound.SoundEvents;
public class TraderBehaviour extends EntityBehaviour<AbstractTraderEntity> { public class TraderBehaviour extends EntityBehaviour<AbstractTraderEntity> {
@Override @Override
public void update(Pony pony, AbstractTraderEntity entity, DisguiseSpell spell) { public void update(Pony pony, AbstractTraderEntity entity, DisguiseSpell spell) {
if (pony.sneakingChanged() && pony.getOwner().isSneaking()) { if (pony.sneakingChanged() && pony.getMaster().isSneaking()) {
entity.setHeadRollingTimeLeft(40); entity.setHeadRollingTimeLeft(40);
if (!entity.world.isClient()) { if (!entity.world.isClient()) {

View file

@ -71,17 +71,17 @@ public class ManaContainer implements MagicReserves {
BarInst(TrackedData<Float> marker, float max) { BarInst(TrackedData<Float> marker, float max) {
this.marker = marker; this.marker = marker;
this.max = max; this.max = max;
pony.getOwner().getDataTracker().startTracking(marker, 0F); pony.getMaster().getDataTracker().startTracking(marker, 0F);
} }
@Override @Override
public float get() { public float get() {
return pony.getOwner().getDataTracker().get(marker); return pony.getMaster().getDataTracker().get(marker);
} }
@Override @Override
public void set(float value) { public void set(float value) {
pony.getOwner().getDataTracker().set(marker, MathHelper.clamp(value, 0, getMax())); pony.getMaster().getDataTracker().set(marker, MathHelper.clamp(value, 0, getMax()));
} }
@Override @Override

View file

@ -29,7 +29,7 @@ public class PlayerAttributes {
new EntityAttributeModifier(UUID.fromString("a54f2595-521e-480b-b9d5-6e750577a564"), "Bat Pony Hanging", -2, Operation.MULTIPLY_TOTAL); new EntityAttributeModifier(UUID.fromString("a54f2595-521e-480b-b9d5-6e750577a564"), "Bat Pony Hanging", -2, Operation.MULTIPLY_TOTAL);
public void applyAttributes(Pony pony) { public void applyAttributes(Pony pony) {
PlayerEntity entity = pony.getOwner(); PlayerEntity entity = pony.getMaster();
Race race = pony.getSpecies(); Race race = pony.getSpecies();
toggleAttribute(entity, EntityAttributes.GENERIC_ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth()); toggleAttribute(entity, EntityAttributes.GENERIC_ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());

View file

@ -19,9 +19,9 @@ public class PlayerCamera extends MotionCompositor {
double roll = 0; double roll = 0;
if (player.getMotion().isFlying()) { if (player.getMotion().isFlying()) {
Vec3d vel = player.getOwner().getVelocity(); Vec3d vel = player.getMaster().getVelocity();
roll -= calculateRoll(player.getOwner(), vel.x, vel.y, vel.z); roll -= calculateRoll(player.getMaster(), vel.x, vel.y, vel.z);
} }
if (player.getPhysics().isGravityNegative()) { if (player.getPhysics().isGravityNegative()) {

View file

@ -33,7 +33,7 @@ public final class PlayerDimensions {
float height = calculateTargetEyeHeight(); float height = calculateTargetEyeHeight();
if (physics.isGravityNegative()) { if (physics.isGravityNegative()) {
if (pony.getOwner().isSneaking()) { if (pony.getMaster().isSneaking()) {
height += 0.2F; height += 0.2F;
} }

View file

@ -46,12 +46,12 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
@Override @Override
public float getGravityModifier() { public float getGravityModifier() {
if (pony.getOwner().getAttributes() == null) { if (pony.getMaster().getAttributes() == null) {
// may be null due to order of execution in the contructor. // may be null due to order of execution in the contructor.
// Will have the default (1) here in any case, so it's safe to ignore the attribute a this point. // Will have the default (1) here in any case, so it's safe to ignore the attribute a this point.
return super.getGravityModifier(); return super.getGravityModifier();
} }
return super.getGravityModifier() * (float)pony.getOwner().getAttributeValue(PlayerAttributes.ENTITY_GRAVTY_MODIFIER); return super.getGravityModifier() * (float)pony.getMaster().getAttributeValue(PlayerAttributes.ENTITY_GRAVTY_MODIFIER);
} }
@Override @Override
@ -61,12 +61,12 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
@Override @Override
public boolean isFlying() { public boolean isFlying() {
return isFlyingSurvival && !pony.getOwner().isFallFlying() && !pony.getOwner().hasVehicle(); return isFlyingSurvival && !pony.getMaster().isFallFlying() && !pony.getMaster().hasVehicle();
} }
@Override @Override
public void tick() { public void tick() {
PlayerEntity entity = pony.getOwner(); PlayerEntity entity = pony.getMaster();
if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) { if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) {
float currentHeight = entity.getDimensions(entity.getPose()).height; float currentHeight = entity.getDimensions(entity.getPose()).height;
@ -78,7 +78,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
final MutableVector velocity = new MutableVector(entity.getVelocity()); final MutableVector velocity = new MutableVector(entity.getVelocity());
boolean creative = entity.abilities.creativeMode || pony.getOwner().isSpectator(); boolean creative = entity.abilities.creativeMode || pony.getMaster().isSpectator();
FlightType type = getFlightType(); FlightType type = getFlightType();
@ -296,7 +296,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
} }
private FlightType getFlightType() { private FlightType getFlightType() {
if (pony.getOwner().isCreative() || pony.getOwner().isSpectator()) { if (pony.getMaster().isCreative() || pony.getMaster().isSpectator()) {
return FlightType.CREATIVE; return FlightType.CREATIVE;
} }
@ -311,7 +311,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
} }
public void updateFlightStat(boolean flying) { public void updateFlightStat(boolean flying) {
PlayerEntity entity = pony.getOwner(); PlayerEntity entity = pony.getMaster();
FlightType type = getFlightType(); FlightType type = getFlightType();
@ -341,6 +341,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
isFlyingEither = compound.getBoolean("isFlyingEither"); isFlyingEither = compound.getBoolean("isFlyingEither");
ticksInAir = compound.getInt("ticksInAir"); ticksInAir = compound.getInt("ticksInAir");
pony.getOwner().calculateDimensions(); pony.getMaster().calculateDimensions();
} }
} }

View file

@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.InteractionManager;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.WorldTribeManager; import com.minelittlepony.unicopia.WorldTribeManager;
import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ability.AbilityDispatcher;
import com.minelittlepony.unicopia.ability.magic.AttachableSpell; import com.minelittlepony.unicopia.ability.magic.Attached;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
@ -107,11 +107,11 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
@Override @Override
public Race getSpecies() { public Race getSpecies() {
if (getOwner() == null) { if (getMaster() == null) {
return Race.HUMAN; return Race.HUMAN;
} }
return Race.fromId(getOwner().getDataTracker().get(RACE)); return Race.fromId(getMaster().getDataTracker().get(RACE));
} }
public boolean sneakingChanged() { public boolean sneakingChanged() {
@ -283,7 +283,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
gravity.tick(); gravity.tick();
if (hasSpell()) { if (hasSpell()) {
AttachableSpell effect = getSpell(AttachableSpell.class, true); Attached effect = getSpell(Attached.class, true);
if (effect != null) { if (effect != null) {
if (entity.getEntityWorld().isClient()) { if (entity.getEntityWorld().isClient()) {
@ -392,7 +392,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
public void onEat(ItemStack stack) { public void onEat(ItemStack stack) {
if (getSpecies() == Race.CHANGELING) { if (getSpecies() == Race.CHANGELING) {
Toxin.POISON.afflict(getOwner(), FoodType.RAW_MEAT, Toxicity.SAFE, stack); Toxin.POISON.afflict(getMaster(), FoodType.RAW_MEAT, Toxicity.SAFE, stack);
} }
} }
@ -443,16 +443,16 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
} }
@Override @Override
public void setOwner(PlayerEntity owner) { public void setMaster(PlayerEntity owner) {
} }
@Override @Override
public PlayerEntity getOwner() { public PlayerEntity getMaster() {
return entity; return entity;
} }
public boolean isClientPlayer() { public boolean isClientPlayer() {
return InteractionManager.instance().isClientPlayer(getOwner()); return InteractionManager.instance().isClientPlayer(getMaster());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View file

@ -60,16 +60,16 @@ public class DummyClientPlayerEntity extends AbstractClientPlayerEntity implemen
@Override @Override
public boolean shouldRenderName() { public boolean shouldRenderName() {
return !InteractionManager.instance().isClientPlayer(getOwner()); return !InteractionManager.instance().isClientPlayer(getMaster());
} }
@Override @Override
public PlayerEntity getOwner() { public PlayerEntity getMaster() {
return owner; return owner;
} }
@Override @Override
public void setOwner(PlayerEntity owner) { public void setMaster(PlayerEntity owner) {
this.owner = owner; this.owner = owner;
} }

View file

@ -23,18 +23,18 @@ public class DummyPlayerEntity extends PlayerEntity implements Owned<PlayerEntit
} }
@Override @Override
public PlayerEntity getOwner() { public PlayerEntity getMaster() {
return owner; return owner;
} }
@Override @Override
public void setOwner(PlayerEntity owner) { public void setMaster(PlayerEntity owner) {
this.owner = owner; this.owner = owner;
} }
@Override @Override
public boolean shouldRenderName() { public boolean shouldRenderName() {
return !InteractionManager.instance().isClientPlayer(getOwner()); return !InteractionManager.instance().isClientPlayer(getMaster());
} }
@Override @Override

View file

@ -24,17 +24,17 @@ public class DummyServerPlayerEntity extends ServerPlayerEntity implements Owned
} }
@Override @Override
public PlayerEntity getOwner() { public PlayerEntity getMaster() {
return owner; return owner;
} }
@Override @Override
public void setOwner(PlayerEntity owner) { public void setMaster(PlayerEntity owner) {
this.owner = owner; this.owner = owner;
} }
@Override @Override
public boolean shouldRenderName() { public boolean shouldRenderName() {
return !InteractionManager.instance().isClientPlayer(getOwner()); return !InteractionManager.instance().isClientPlayer(getMaster());
} }
} }

View file

@ -26,7 +26,7 @@ public class AppleItem extends Item implements ItemImpl.TickableItem {
@Override @Override
public ActionResult onGroundTick(IItemEntity item) { public ActionResult onGroundTick(IItemEntity item) {
ItemEntity entity = item.get().getOwner(); ItemEntity entity = item.get().getMaster();
if (!entity.removed && item.getPickupDelay() == 0 && item.getAge() > 200230 && entity.world.random.nextInt(200) < 10) { if (!entity.removed && item.getPickupDelay() == 0 && item.getAge() > 200230 && entity.world.random.nextInt(200) < 10) {

View file

@ -25,7 +25,7 @@ abstract class MixinKeyboardInput extends Input {
movementSideways = -movementSideways; movementSideways = -movementSideways;
if (player.getOwner().abilities.flying) { if (player.getMaster().abilities.flying) {
tmp = jumping; tmp = jumping;
jumping = sneaking; jumping = sneaking;
sneaking = tmp; sneaking = tmp;

View file

@ -35,7 +35,7 @@ public class MsgPlayerCapabilities implements Channel.Packet {
} }
public MsgPlayerCapabilities(boolean full, Pony player) { public MsgPlayerCapabilities(boolean full, Pony player) {
playerId = player.getOwner().getUuid(); playerId = player.getMaster().getUuid();
newRace = player.getSpecies(); newRace = player.getSpecies();
compoundTag = full ? player.toNBT() : new CompoundTag(); compoundTag = full ? player.toNBT() : new CompoundTag();
} }

View file

@ -1,6 +1,9 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
import com.minelittlepony.unicopia.Owned;
import net.fabricmc.fabric.api.network.PacketContext; import net.fabricmc.fabric.api.network.PacketContext;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
@ -17,8 +20,9 @@ public class MsgSpawnProjectile extends EntitySpawnS2CPacket implements Channel.
} catch (IOException e) { } } catch (IOException e) { }
} }
@SuppressWarnings("unchecked")
public MsgSpawnProjectile(Entity e) { public MsgSpawnProjectile(Entity e) {
super(e); super(e, Optional.of(e instanceof Owned ? ((Owned<Entity>)e).getMaster() : null).map(Entity::getEntityId).orElse(0));
} }
@Override @Override
@ -29,16 +33,24 @@ public class MsgSpawnProjectile extends EntitySpawnS2CPacket implements Channel.
} }
} }
@SuppressWarnings("unchecked")
@Override @Override
public void handle(PacketContext context) { public void handle(PacketContext context) {
World world = context.getPlayer().world; World world = context.getPlayer().world;
Entity entity = getEntityTypeId().create(world); Entity entity = getEntityTypeId().create(world);
entity.updateTrackedPosition(getX(), getY(), getZ()); entity.updateTrackedPosition(getX(), getY(), getZ());
entity.pitch = getPitch() * 360 / 256.0F; entity.refreshPositionAfterTeleport(getX(), getY(), getZ());
entity.yaw = getYaw() * 360 / 256.0F; entity.setVelocity(getVelocityX(), getVelocityY(), getVelocityZ());
entity.pitch = getPitch() * 360 / 256F;
entity.yaw = getYaw() * 360 / 256F;
entity.setEntityId(getId()); entity.setEntityId(getId());
entity.setUuid(getUuid()); entity.setUuid(getUuid());
if (entity instanceof Owned) {
((Owned<Entity>) entity).setMaster(world.getEntityById(this.getEntityData()));
}
((ClientWorld)world).addEntity(getId(), entity); ((ClientWorld)world).addEntity(getId(), entity);
} }
} }

View file

@ -1,13 +1,11 @@
package com.minelittlepony.unicopia.projectile; package com.minelittlepony.unicopia.projectile;
import java.util.UUID;
import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Affinity;
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;
import com.minelittlepony.unicopia.ability.magic.Magical; import com.minelittlepony.unicopia.ability.magic.Magical;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.ThrowableSpell; import com.minelittlepony.unicopia.ability.magic.Thrown;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.Channel;
import com.minelittlepony.unicopia.network.EffectSync; import com.minelittlepony.unicopia.network.EffectSync;
@ -20,6 +18,7 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.entity.projectile.thrown.ThrownItemEntity; import net.minecraft.entity.projectile.thrown.ThrownItemEntity;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -29,7 +28,6 @@ import net.minecraft.network.Packet;
import net.minecraft.particle.ItemStackParticleEffect; import net.minecraft.particle.ItemStackParticleEffect;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;
@ -42,7 +40,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 Magical, Projectile, Caster<LivingEntity> { public class MagicProjectileEntity extends ThrownItemEntity implements Magical, Caster<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<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN); private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
@ -51,23 +49,18 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
private final EffectSync effectDelegate = new EffectSync(this, EFFECT); private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
private UUID ownerUuid;
private BlockPos lastBlockPos; private BlockPos lastBlockPos;
public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world) { public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world) {
super(type, world); super(type, world);
} }
public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world, LivingEntity thrower) { public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world, LivingEntity thrower, Vec3d velocity) {
this(type, world, thrower.getX(), thrower.getY() + thrower.getStandingEyeHeight(), thrower.getZ());
setOwner(thrower);
}
public MagicProjectileEntity(EntityType<MagicProjectileEntity> type, World world, double x, double y, double z) {
super(type, world); super(type, world);
refreshPositionAndAngles(thrower.getX(), thrower.getY(), thrower.getZ(), thrower.yaw, thrower.pitch);
setPos(x, y, z); refreshPosition();
setVelocity(velocity);
setOwner(thrower);
} }
@Override @Override
@ -80,7 +73,8 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
@Override @Override
protected Item getDefaultItem() { protected Item getDefaultItem() {
return Items.AIR; Spell spell = this.getSpell(false);
return spell == null ? Items.AIR : spell.getAffinity() == Affinity.BAD ? Items.MAGMA_CREAM : Items.SNOWBALL;
} }
@Override @Override
@ -89,17 +83,13 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
} }
@Override @Override
public void setOwner(LivingEntity owner) { public void setMaster(LivingEntity owner) {
ownerUuid = owner == null ? null : owner.getUuid(); setOwner(owner);
} }
@Override @Override
public LivingEntity getOwner() { public LivingEntity getMaster() {
if (ownerUuid == null || !(world instanceof ServerWorld)) { return (LivingEntity)getOwner();
return null;
}
return (LivingEntity) ((ServerWorld)world).getEntity(ownerUuid);
} }
@Override @Override
@ -112,16 +102,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
return hasSpell() ? Affinity.NEUTRAL : getSpell(true).getAffinity(); return hasSpell() ? Affinity.NEUTRAL : getSpell(true).getAffinity();
} }
@Override
public void setGravity(boolean gravity) {
setNoGravity(gravity);
}
@Override
public void setEffect(ThrowableSpell effect) {
setSpell(effect);
}
@Override @Override
public EffectSync getPrimarySpellSlot() { public EffectSync getPrimarySpellSlot() {
return effectDelegate; return effectDelegate;
@ -136,22 +116,18 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
} }
} }
@Override
public void setThrowDamage(float damage) { public void setThrowDamage(float damage) {
getDataTracker().set(DAMAGE, Math.max(0, damage)); getDataTracker().set(DAMAGE, Math.max(0, damage));
} }
@Override
public float getThrowDamage() { public float getThrowDamage() {
return getDataTracker().get(DAMAGE); return getDataTracker().get(DAMAGE);
} }
@Override
public void setHydrophobic() { public void setHydrophobic() {
getDataTracker().set(HYDROPHOBIC, true); getDataTracker().set(HYDROPHOBIC, true);
} }
@Override
public boolean getHydrophobic() { public boolean getHydrophobic() {
return getDataTracker().get(HYDROPHOBIC); return getDataTracker().get(HYDROPHOBIC);
} }
@ -159,6 +135,8 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
@Override @Override
public void tick() { public void tick() {
System.out.println(this.getPos() + " " + this.getVelocity());
if (!world.isClient()) { if (!world.isClient()) {
if (Math.abs(getVelocity().x) < 0.01 && Math.abs(getVelocity().x) < 0.01 && Math.abs(getVelocity().y) < 0.01) { if (Math.abs(getVelocity().x) < 0.01 && Math.abs(getVelocity().x) < 0.01 && Math.abs(getVelocity().y) < 0.01) {
remove(); remove();
@ -206,11 +184,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
} }
} }
@Override
public void launch(Entity entityThrower, float pitch, float yaw, float wobble, float velocity, float inaccuracy) {
setProperties(entityThrower, pitch, yaw, wobble, velocity, inaccuracy);
}
private ParticleEffect getParticleParameters() { private ParticleEffect getParticleParameters() {
ItemStack stack = getItem(); ItemStack stack = getItem();
@ -255,40 +228,37 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
protected void onCollision(HitResult result) { protected void onCollision(HitResult result) {
if (!removed) { if (!removed) {
remove(); remove();
super.onCollision(result);
if (result.getType() == HitResult.Type.BLOCK) { if (!world.isClient()) {
onHitBlock((BlockHitResult)result); world.sendEntityStatus(this, (byte)3);
} else if (result.getType() == HitResult.Type.ENTITY) { remove();
onHitEntity((EntityHitResult)result);
} }
} }
} }
protected void onHitBlock(BlockHitResult hit) { @Override
protected void onBlockHit(BlockHitResult hit) {
if (hasSpell()) { if (hasSpell()) {
Spell effect = getSpell(true); Spell effect = getSpell(true);
if (effect instanceof ThrowableSpell) { if (effect instanceof Thrown) {
((ThrowableSpell)effect).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos())); ((Thrown)effect).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()));
} }
} }
} }
protected void onHitEntity(EntityHitResult hit) { @Override
protected void onEntityHit(EntityHitResult hit) {
Entity entity = hit.getEntity(); Entity entity = hit.getEntity();
if (entity instanceof Projectile) { if (entity instanceof ProjectileEntity) {
return; return;
} }
if (entity != null) { if (entity != null) {
entity.damage(DamageSource.thrownProjectile(this, getOwner()), getThrowDamage()); entity.damage(DamageSource.thrownProjectile(this, getOwner()), getThrowDamage());
} }
if (!world.isClient()) {
world.sendEntityStatus(this, (byte)3);
remove();
}
} }
@Override @Override

View file

@ -1,38 +0,0 @@
package com.minelittlepony.unicopia.projectile;
import com.minelittlepony.unicopia.ability.magic.ThrowableSpell;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public interface Projectile {
void setGravity(boolean gravity);
void setItem(ItemStack stack);
void setOwner(LivingEntity owner);
void setEffect(ThrowableSpell effect);
void setThrowDamage(float damage);
float getThrowDamage();
void setHydrophobic();
boolean getHydrophobic();
void launch(Entity entityThrower, float pitch, float yaw, float offset, float velocity, float inaccuracy);
default void spawn(World world) {
world.spawnEntity((Entity)this);
}
default void launch(double x, double y, double z, float velocity, float inaccuracy) {
((ProjectileEntity)this).setVelocity(x, y, z, velocity, inaccuracy);
}
}