mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Cast spells are now their own entity (should fix problems with spells dissapearing/not appearing at the correct location in muliplayer)
This commit is contained in:
parent
f511e2b346
commit
3211b232cf
16 changed files with 296 additions and 100 deletions
|
@ -0,0 +1,10 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public interface EntitySupplier {
|
||||
/**
|
||||
* Gets the owner that holds this object.
|
||||
*/
|
||||
Entity getEntity();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.minelittlepony.unicopia;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.entity.FloatingArtefactEntity;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
|
||||
|
@ -20,6 +21,9 @@ public interface UEntities {
|
|||
EntityType<FloatingArtefactEntity> FLOATING_ARTEFACT = register("floating_artefact", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FloatingArtefactEntity::new)
|
||||
.trackRangeBlocks(200)
|
||||
.dimensions(EntityDimensions.fixed(1, 1)));
|
||||
EntityType<CastSpellEntity> CAST_SPELL = register("cast_spell", FabricEntityTypeBuilder.create(SpawnGroup.MISC, CastSpellEntity::new)
|
||||
.trackRangeBlocks(200)
|
||||
.dimensions(EntityDimensions.fixed(1, 1)));
|
||||
|
||||
static <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) {
|
||||
EntityType<T> type = builder.build();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.ability.magic;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
|
@ -15,6 +17,11 @@ public interface Spell extends NbtSerialisable, Affine {
|
|||
*/
|
||||
SpellType<?> getType();
|
||||
|
||||
/**
|
||||
* The unique id of this particular spell instance.
|
||||
*/
|
||||
UUID getUuid();
|
||||
|
||||
/**
|
||||
* Sets this effect as dead.
|
||||
*/
|
||||
|
|
|
@ -2,25 +2,19 @@ package com.minelittlepony.unicopia.ability.magic.spell;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.UEntities;
|
||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleHandle;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public abstract class AbstractPlacedSpell extends AbstractSpell implements Attached {
|
||||
|
||||
@Nullable
|
||||
protected Vec3d origin;
|
||||
@Nullable
|
||||
protected BlockPos placement;
|
||||
@Nullable
|
||||
private Identifier dimension;
|
||||
|
||||
|
@ -39,39 +33,45 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac
|
|||
@Override
|
||||
public boolean onBodyTick(Caster<?> source) {
|
||||
|
||||
if (origin == null) {
|
||||
origin = source.getOriginVector();
|
||||
placement = source.getOrigin();
|
||||
dimension = source.getWorld().getRegistryKey().getValue();
|
||||
if (!source.isClient()) {
|
||||
|
||||
if (dimension == null) {
|
||||
dimension = source.getWorld().getRegistryKey().getValue();
|
||||
setDirty(true);
|
||||
|
||||
if (!source.isClient()) {
|
||||
CastSpellEntity entity = UEntities.CAST_SPELL.create(source.getWorld());
|
||||
Vec3d pos = source.getOriginVector();
|
||||
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, 0, 0);
|
||||
entity.setSpell(this);
|
||||
entity.setMaster(source.getMaster());
|
||||
entity.world.spawnEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
if (!source.getWorld().getRegistryKey().getValue().equals(dimension)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!source.getWorld().getRegistryKey().getValue().equals(dimension)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source.isClient()) {
|
||||
particlEffect.ifAbsent(source, spawner -> {
|
||||
spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), origin, Vec3d.ZERO);
|
||||
}).ifPresent(p -> {
|
||||
p.attach(source);
|
||||
p.setAttribute(1, getType().getColor());
|
||||
});
|
||||
}
|
||||
|
||||
return onGroundTick(source);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract boolean onGroundTick(Caster<?> source);
|
||||
public boolean onGroundTick(Caster<?> source) {
|
||||
particlEffect.ifAbsent(source, spawner -> {
|
||||
spawner.addParticle(new OrientedBillboardParticleEffect(UParticles.MAGIC_RUNES, 90, 0), source.getOriginVector(), Vec3d.ZERO);
|
||||
}).ifPresent(p -> {
|
||||
p.attach(source);
|
||||
p.setAttribute(1, getType().getColor());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
super.toNBT(compound);
|
||||
if (placement != null) {
|
||||
compound.put("placement", NbtHelper.fromBlockPos(placement));
|
||||
}
|
||||
if (origin != null) {
|
||||
compound.put("origin", NbtSerialisable.writeVector(origin));
|
||||
}
|
||||
|
||||
if (dimension != null) {
|
||||
compound.putString("dimension", dimension.toString());
|
||||
}
|
||||
|
@ -80,12 +80,7 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac
|
|||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
super.fromNBT(compound);
|
||||
if (compound.contains("placement")) {
|
||||
placement = NbtHelper.toBlockPos(compound.getCompound("placement"));
|
||||
}
|
||||
if (compound.contains("origin")) {
|
||||
origin = NbtSerialisable.readVector(compound.getList("origin", 6));
|
||||
}
|
||||
|
||||
if (compound.contains("dimension")) {
|
||||
dimension = new Identifier(compound.getString("dimension"));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
|
||||
|
@ -12,8 +14,16 @@ public abstract class AbstractSpell implements Spell {
|
|||
|
||||
private final SpellType<?> type;
|
||||
|
||||
private UUID uuid;
|
||||
|
||||
protected AbstractSpell(SpellType<?> type) {
|
||||
this.type = type;
|
||||
uuid = UUID.randomUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,11 +59,15 @@ public abstract class AbstractSpell implements Spell {
|
|||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
compound.putBoolean("dead", isDead);
|
||||
compound.putUuid("uuid", uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
setDirty(false);
|
||||
if (compound.contains("uuid")) {
|
||||
uuid = compound.getUuid("uuid");
|
||||
}
|
||||
isDead = compound.getBoolean("dead");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,12 @@ public class NecromancySpell extends AbstractPlacedSpell {
|
|||
|
||||
@Override
|
||||
public boolean onGroundTick(Caster<?> source) {
|
||||
super.onGroundTick(source);
|
||||
|
||||
int radius = (source.getLevel().get() + 1) * 4;
|
||||
|
||||
if (source.isClient()) {
|
||||
source.spawnParticles(origin, new Sphere(false, radius), 5, pos -> {
|
||||
source.spawnParticles(new Sphere(false, radius), 5, pos -> {
|
||||
if (!source.getWorld().isAir(new BlockPos(pos).down())) {
|
||||
source.addParticle(ParticleTypes.FLAME, pos, Vec3d.ZERO);
|
||||
}
|
||||
|
@ -47,7 +48,7 @@ public class NecromancySpell extends AbstractPlacedSpell {
|
|||
return true;
|
||||
}
|
||||
|
||||
float additional = source.getWorld().getLocalDifficulty(placement).getLocalDifficulty();
|
||||
float additional = source.getWorld().getLocalDifficulty(source.getOrigin()).getLocalDifficulty();
|
||||
|
||||
Shape affectRegion = new Sphere(false, radius);
|
||||
|
||||
|
@ -60,7 +61,7 @@ public class NecromancySpell extends AbstractPlacedSpell {
|
|||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Vec3d pos = affectRegion.computePoint(source.getWorld().random).add(origin);
|
||||
Vec3d pos = affectRegion.computePoint(source.getWorld().random).add(source.getOriginVector());
|
||||
|
||||
BlockPos loc = new BlockPos(pos);
|
||||
|
||||
|
|
|
@ -32,16 +32,17 @@ public class SiphoningSpell extends AbstractPlacedSpell {
|
|||
|
||||
@Override
|
||||
public boolean onGroundTick(Caster<?> source) {
|
||||
super.onGroundTick(source);
|
||||
|
||||
if (source.isClient()) {
|
||||
int radius = 4 + source.getLevel().get();
|
||||
int direction = isFriendlyTogether(source) ? 1 : -1;
|
||||
|
||||
source.spawnParticles(origin, new Sphere(true, radius, 1, 0, 1), 1, pos -> {
|
||||
source.spawnParticles(new Sphere(true, radius, 1, 0, 1), 1, pos -> {
|
||||
if (!source.getWorld().isAir(new BlockPos(pos).down())) {
|
||||
|
||||
double dist = pos.distanceTo(origin);
|
||||
Vec3d velocity = pos.subtract(origin).normalize().multiply(direction * dist);
|
||||
double dist = pos.distanceTo(source.getOriginVector());
|
||||
Vec3d velocity = pos.subtract(source.getOriginVector()).normalize().multiply(direction * dist);
|
||||
|
||||
source.addParticle(direction == 1 ? ParticleTypes.HEART : ParticleTypes.ANGRY_VILLAGER, pos, velocity);
|
||||
}
|
||||
|
@ -62,7 +63,7 @@ public class SiphoningSpell extends AbstractPlacedSpell {
|
|||
}
|
||||
|
||||
private Stream<LivingEntity> getTargets(Caster<?> source) {
|
||||
return VecHelper.findInRange(null, source.getWorld(), origin, 4 + source.getLevel().get(), e -> e instanceof LivingEntity)
|
||||
return VecHelper.findInRange(null, source.getWorld(), source.getOriginVector(), 4 + source.getLevel().get(), e -> e instanceof LivingEntity)
|
||||
.stream()
|
||||
.map(e -> (LivingEntity)e);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
|||
import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer;
|
||||
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer;
|
||||
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
|
||||
import com.minelittlepony.unicopia.client.render.CastSpellEntityRenderer;
|
||||
import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer;
|
||||
import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer;
|
||||
import com.minelittlepony.unicopia.item.ChameleonItem;
|
||||
|
@ -61,6 +62,7 @@ public interface URenderers {
|
|||
|
||||
EntityRendererRegistry.INSTANCE.register(UEntities.THROWN_ITEM, (manager, context) -> new FlyingItemEntityRenderer<>(manager, context.getItemRenderer()));
|
||||
EntityRendererRegistry.INSTANCE.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new);
|
||||
EntityRendererRegistry.INSTANCE.register(UEntities.CAST_SPELL, CastSpellEntityRenderer::new);
|
||||
|
||||
ColorProviderRegistry.ITEM.register((stack, i) -> i > 0 ? -1 : ((DyeableItem)stack.getItem()).getColor(stack), UItems.FRIENDSHIP_BRACELET);
|
||||
BuiltinItemRendererRegistry.INSTANCE.register(UItems.FILLED_JAR, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.minelittlepony.unicopia.client.render;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
|
||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class CastSpellEntityRenderer extends EntityRenderer<CastSpellEntity> {
|
||||
|
||||
public CastSpellEntityRenderer(EntityRenderDispatcher dispatcher, EntityRendererRegistry.Context context) {
|
||||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(CastSpellEntity entity) {
|
||||
return SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.AbstractPlacedSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import com.minelittlepony.unicopia.network.EffectSync;
|
||||
import com.minelittlepony.unicopia.network.MsgSpawnProjectile;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.data.DataTracker;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CastSpellEntity extends Entity implements Caster<LivingEntity> {
|
||||
|
||||
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
|
||||
private static final TrackedData<Optional<UUID>> SPELL = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID);
|
||||
|
||||
private static final SpellPredicate<AbstractPlacedSpell> SPELL_TYPE = s -> s instanceof AbstractPlacedSpell;
|
||||
|
||||
private static final LevelStore LEVELS = Levelled.fixed(0);
|
||||
|
||||
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this, GRAVITY);
|
||||
|
||||
private UUID ownerUuid;
|
||||
private int ownerEntityId;
|
||||
|
||||
public CastSpellEntity(EntityType<?> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initDataTracker() {
|
||||
getDataTracker().startTracking(SPELL, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
|
||||
LivingEntity master = getMaster();
|
||||
|
||||
if (master == null || master.removed) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Caster.of(master).filter(c -> {
|
||||
UUID spellId = dataTracker.get(SPELL).orElse(null);
|
||||
|
||||
if (!c.getSpellSlot().get(SPELL_TYPE, true).filter(s -> s.getUuid().equals(spellId) && s.onGroundTick(this)).isPresent()) {
|
||||
c.setSpell(null);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).isPresent()) {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaster(LivingEntity owner) {
|
||||
if (owner != null) {
|
||||
ownerUuid = owner.getUuid();
|
||||
ownerEntityId = owner.getEntityId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpell(Spell spell) {
|
||||
getDataTracker().set(SPELL, Optional.ofNullable(spell).map(Spell::getUuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getEntity() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getMaster() {
|
||||
if (ownerUuid != null && world instanceof ServerWorld) {
|
||||
return (LivingEntity)((ServerWorld)world).getEntity(ownerUuid);
|
||||
}
|
||||
|
||||
if (ownerEntityId != 0) {
|
||||
return (LivingEntity)world.getEntityById(ownerEntityId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getLevel() {
|
||||
return Caster.of(getMaster()).map(Caster::getLevel).orElse(LEVELS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Affinity getAffinity() {
|
||||
return getSpellSlot().get(true).map(Spell::getAffinity).orElse(Affinity.NEUTRAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Physics getPhysics() {
|
||||
return physics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EffectSync getSpellSlot() {
|
||||
return Caster.of(getMaster()).map(Caster::getSpellSlot).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeCustomDataToTag(CompoundTag tag) {
|
||||
if (ownerUuid != null) {
|
||||
tag.putUuid("Owner", ownerUuid);
|
||||
}
|
||||
tag.putInt("OwnerId", ownerEntityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readCustomDataFromTag(CompoundTag tag) {
|
||||
if (tag.containsUuid("Owner")) {
|
||||
ownerUuid = tag.getUuid("Owner");
|
||||
}
|
||||
ownerEntityId = tag.getInt("OwnerId");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Packet<?> createSpawnPacket() {
|
||||
return Channel.SERVER_SPAWN_PROJECTILE.toPacket(new MsgSpawnProjectile(this));
|
||||
}
|
||||
|
||||
}
|
|
@ -30,10 +30,11 @@ public class Creature extends Living<LivingEntity> {
|
|||
|
||||
public static void boostrap() {}
|
||||
|
||||
private final EntityPhysics<Creature> physics = new EntityPhysics<>(this, GRAVITY);
|
||||
private final EntityPhysics<LivingEntity> physics;
|
||||
|
||||
public Creature(LivingEntity entity) {
|
||||
super(entity, EFFECT);
|
||||
physics = new EntityPhysics<>(entity, GRAVITY);
|
||||
}
|
||||
|
||||
public void initAi(GoalSelector goals, GoalSelector targets) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.entity.player.PlayerAttributes;
|
||||
import com.minelittlepony.unicopia.util.Copieable;
|
||||
|
||||
|
@ -22,31 +21,29 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics, Copieable<EntityPhysics<T>>, Tickable {
|
||||
public class EntityPhysics<T extends Entity> implements Physics, Copieable<EntityPhysics<T>>, Tickable {
|
||||
|
||||
private final TrackedData<Float> gravity;
|
||||
|
||||
protected final T pony;
|
||||
protected final T entity;
|
||||
|
||||
private float lastGravity = 1;
|
||||
|
||||
public EntityPhysics(T pony, TrackedData<Float> gravity) {
|
||||
this(pony, gravity, true);
|
||||
public EntityPhysics(T entity, TrackedData<Float> gravity) {
|
||||
this(entity, gravity, true);
|
||||
}
|
||||
|
||||
public EntityPhysics(T pony, TrackedData<Float> gravity, boolean register) {
|
||||
this.pony = pony;
|
||||
public EntityPhysics(T entity, TrackedData<Float> gravity, boolean register) {
|
||||
this.entity = entity;
|
||||
this.gravity = gravity;
|
||||
|
||||
if (register) {
|
||||
this.pony.getMaster().getDataTracker().startTracking(gravity, 1F);
|
||||
this.entity.getDataTracker().startTracking(gravity, 1F);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
Entity entity = pony.getMaster();
|
||||
|
||||
if (isGravityNegative()) {
|
||||
if (entity.getY() > entity.world.getHeight() + 64) {
|
||||
entity.damage(DamageSource.OUT_OF_WORLD, 4.0F);
|
||||
|
@ -64,8 +61,6 @@ public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics
|
|||
}
|
||||
|
||||
protected void onGravitychanged() {
|
||||
Entity entity = pony.getMaster();
|
||||
|
||||
entity.calculateDimensions();
|
||||
|
||||
if (!entity.world.isClient && entity instanceof MobEntity) {
|
||||
|
@ -81,7 +76,7 @@ public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics
|
|||
|
||||
@Override
|
||||
public Vec3d getMotionAngle() {
|
||||
return new Vec3d(pony.getMaster().getPitch(1), pony.getMaster().getYaw(1), 0);
|
||||
return new Vec3d(entity.getPitch(1), entity.getYaw(1), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,8 +87,6 @@ public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics
|
|||
@Override
|
||||
public BlockPos getHeadPosition() {
|
||||
|
||||
Entity entity = pony.getMaster();
|
||||
|
||||
entity.setOnGround(false);
|
||||
|
||||
BlockPos pos = new BlockPos(
|
||||
|
@ -118,7 +111,6 @@ public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics
|
|||
|
||||
@Override
|
||||
public void spawnSprintingParticles() {
|
||||
Entity entity = pony.getMaster();
|
||||
BlockState state = entity.world.getBlockState(getHeadPosition());
|
||||
if (state.getRenderType() != BlockRenderType.INVISIBLE) {
|
||||
Vec3d vel = entity.getVelocity();
|
||||
|
@ -132,31 +124,29 @@ public class EntityPhysics<T extends Owned<? extends Entity>> implements Physics
|
|||
|
||||
@Override
|
||||
public void setBaseGravityModifier(float constant) {
|
||||
pony.getMaster().getDataTracker().set(gravity, constant);
|
||||
entity.getDataTracker().set(gravity, constant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBaseGravityModifier() {
|
||||
return pony.getMaster().getDataTracker().get(gravity);
|
||||
return entity.getDataTracker().get(gravity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getGravityModifier() {
|
||||
Entity master = pony.getMaster();
|
||||
|
||||
|
||||
if (master instanceof LivingEntity) {
|
||||
if (((LivingEntity)master).getAttributes() == null) {
|
||||
if (entity instanceof LivingEntity) {
|
||||
if (((LivingEntity)entity).getAttributes() == null) {
|
||||
// may be null due to order of execution in the constructor.
|
||||
// Will have the default (1) here in any case, so it's safe to ignore the attribute at this point.
|
||||
return getBaseGravityModifier();
|
||||
}
|
||||
|
||||
if (((LivingEntity)master).isSleeping()) {
|
||||
if (((LivingEntity)entity).isSleeping()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return getBaseGravityModifier() * (float)((LivingEntity)master).getAttributeValue(PlayerAttributes.ENTITY_GRAVTY_MODIFIER);
|
||||
return getBaseGravityModifier() * (float)((LivingEntity)entity).getAttributeValue(PlayerAttributes.ENTITY_GRAVTY_MODIFIER);
|
||||
}
|
||||
|
||||
return getBaseGravityModifier();
|
||||
|
|
|
@ -30,12 +30,13 @@ public class ItemImpl implements Equine<ItemEntity>, Owned<ItemEntity> {
|
|||
|
||||
private final ItemEntity owner;
|
||||
|
||||
private final ItemPhysics physics = new ItemPhysics(this);
|
||||
private final ItemPhysics physics;
|
||||
|
||||
private Race serverRace;
|
||||
|
||||
public ItemImpl(ItemEntity owner) {
|
||||
this.owner = owner;
|
||||
this.physics = new ItemPhysics(owner);
|
||||
owner.getDataTracker().startTracking(ITEM_GRAVITY, 1F);
|
||||
owner.getDataTracker().startTracking(ITEM_RACE, Race.HUMAN.ordinal());
|
||||
}
|
||||
|
|
|
@ -3,43 +3,41 @@ package com.minelittlepony.unicopia.entity;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
|
||||
class ItemPhysics extends EntityPhysics<ItemImpl> {
|
||||
public ItemPhysics(ItemImpl itemImpl) {
|
||||
super(itemImpl, ItemImpl.ITEM_GRAVITY, false);
|
||||
class ItemPhysics extends EntityPhysics<ItemEntity> {
|
||||
public ItemPhysics(ItemEntity entity) {
|
||||
super(entity, ItemImpl.ITEM_GRAVITY, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
ItemEntity owner = pony.getMaster();
|
||||
|
||||
if (isGravityNegative() && !owner.getStack().isEmpty()) {
|
||||
owner.setNoGravity(true);
|
||||
owner.addVelocity(
|
||||
if (isGravityNegative() && !entity.getStack().isEmpty()) {
|
||||
entity.setNoGravity(true);
|
||||
entity.addVelocity(
|
||||
0,
|
||||
0.04
|
||||
+ calcGravity(-0.04D), // apply our own
|
||||
0
|
||||
);
|
||||
|
||||
if (!owner.isOnGround()
|
||||
|| Entity.squaredHorizontalLength(owner.getVelocity()) > 9.999999747378752E-6D) {
|
||||
if (!entity.isOnGround()
|
||||
|| Entity.squaredHorizontalLength(entity.getVelocity()) > 9.999999747378752E-6D) {
|
||||
|
||||
float above = 0.98f;
|
||||
if (owner.verticalCollision) {
|
||||
above *= owner.world.getBlockState(owner.getBlockPos().up()).getBlock().getSlipperiness();
|
||||
if (entity.verticalCollision) {
|
||||
above *= entity.world.getBlockState(entity.getBlockPos().up()).getBlock().getSlipperiness();
|
||||
//above /= 9;
|
||||
}
|
||||
|
||||
owner.setVelocity(owner.getVelocity().multiply(above, 1, above));
|
||||
entity.setVelocity(entity.getVelocity().multiply(above, 1, above));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onGravitychanged() {
|
||||
if (!pony.getMaster().world.isClient) {
|
||||
if (!entity.world.isClient) {
|
||||
float gravity = this.getBaseGravityModifier();
|
||||
setBaseGravityModifier(gravity == 0 ? 1 : gravity * 2);
|
||||
setBaseGravityModifier(gravity);
|
||||
|
|
|
@ -38,7 +38,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Motion, NbtSerialisable {
|
||||
public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickable, Motion, NbtSerialisable {
|
||||
|
||||
private int ticksInAir;
|
||||
|
||||
|
@ -55,8 +55,11 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
|
||||
private final PlayerDimensions dimensions;
|
||||
|
||||
private final Pony pony;
|
||||
|
||||
public PlayerPhysics(Pony pony) {
|
||||
super(pony, Creature.GRAVITY);
|
||||
super(pony.getMaster(), Creature.GRAVITY);
|
||||
this.pony = pony;
|
||||
dimensions = new PlayerDimensions(pony, this);
|
||||
}
|
||||
|
||||
|
@ -67,12 +70,12 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
|
||||
@Override
|
||||
public boolean isFlying() {
|
||||
return isFlyingSurvival && !pony.getMaster().isFallFlying() && !pony.getMaster().hasVehicle();
|
||||
return isFlyingSurvival && !entity.isFallFlying() && !entity.hasVehicle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGliding() {
|
||||
return isFlying() && (pony.getMaster().isSneaking() || ((Jumper)pony.getMaster()).isJumping()) && !pony.sneakingChanged();
|
||||
return isFlying() && (entity.isSneaking() || ((Jumper)entity).isJumping()) && !pony.sneakingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,8 +87,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
public float getWingAngle() {
|
||||
float spreadAmount = -0.5F;
|
||||
|
||||
PlayerEntity entity = pony.getMaster();
|
||||
|
||||
if (isFlying()) {
|
||||
//spreadAmount += Math.sin(pony.getEntity().age / 4F) * 8;
|
||||
spreadAmount += isGliding() ? 3 : thrustScale * 60;
|
||||
|
@ -109,7 +110,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
if (wallHitCooldown > 0) {
|
||||
wallHitCooldown--;
|
||||
}
|
||||
PlayerEntity entity = pony.getMaster();
|
||||
|
||||
final MutableVector velocity = new MutableVector(entity.getVelocity());
|
||||
|
||||
|
@ -121,7 +121,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
entity.setPose(EntityPose.STANDING);
|
||||
}
|
||||
|
||||
boolean creative = entity.abilities.creativeMode || pony.getMaster().isSpectator();
|
||||
boolean creative = entity.abilities.creativeMode || entity.isSpectator();
|
||||
|
||||
FlightType type = getFlightType();
|
||||
|
||||
|
@ -443,7 +443,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
|
||||
private FlightType getFlightType() {
|
||||
|
||||
if (UItems.PEGASUS_AMULET.isApplicable(pony.getMaster())) {
|
||||
if (UItems.PEGASUS_AMULET.isApplicable(entity)) {
|
||||
return FlightType.ARTIFICIAL;
|
||||
}
|
||||
|
||||
|
@ -454,8 +454,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
}
|
||||
|
||||
public void updateFlightStat(boolean flying) {
|
||||
PlayerEntity entity = pony.getMaster();
|
||||
|
||||
FlightType type = getFlightType();
|
||||
|
||||
entity.abilities.allowFlying = type.canFlyCreative(entity);
|
||||
|
@ -484,6 +482,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
|||
isFlyingEither = compound.getBoolean("isFlyingEither");
|
||||
ticksInAir = compound.getInt("ticksInAir");
|
||||
|
||||
pony.getMaster().calculateDimensions();
|
||||
entity.calculateDimensions();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import java.util.function.Consumer;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -82,7 +81,7 @@ public class ParticleHandle {
|
|||
caster = caster.filter(c -> {
|
||||
Entity e = c.getEntity();
|
||||
|
||||
return Equine.of(e) == c
|
||||
return Caster.of(e).orElse(null) == c
|
||||
&& c.getSpellSlot().get(false)
|
||||
.filter(s -> s.getType() == effect)
|
||||
.isPresent()
|
||||
|
|
Loading…
Reference in a new issue