mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Improved disguise hitbox behaviour
This commit is contained in:
parent
f0681adc12
commit
80b89088ce
9 changed files with 132 additions and 62 deletions
|
@ -1,14 +1,18 @@
|
|||
package com.minelittlepony.unicopia.ability;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
|
||||
/**
|
||||
* Predicate for abilities to control what the player's physical height is.
|
||||
*
|
||||
* This overrides the default.
|
||||
*/
|
||||
public interface HeightPredicate {
|
||||
public interface DimensionsPredicate {
|
||||
float getTargetEyeHeight(Pony player);
|
||||
|
||||
float getTargetBodyHeight(Pony player);
|
||||
Optional<EntityDimensions> getTargetDimensions(Pony player);
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.ability.FlightPredicate;
|
||||
import com.minelittlepony.unicopia.ability.HeightPredicate;
|
||||
import com.minelittlepony.unicopia.ability.DimensionsPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.AttachableSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
|
@ -17,6 +19,7 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.data.TrackedData;
|
||||
import net.minecraft.entity.mob.MobEntity;
|
||||
|
@ -24,7 +27,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Suppressable, FlightPredicate, HeightPredicate {
|
||||
public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Suppressable, FlightPredicate, DimensionsPredicate {
|
||||
|
||||
private final Disguise disguise = new Disguise();
|
||||
|
||||
|
@ -55,6 +58,12 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
|||
return suppressionCounter <= otherSource.getCurrentLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(Caster<?> caster) {
|
||||
super.onDestroyed(caster);
|
||||
caster.getEntity().calculateDimensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuppressed(Caster<?> otherSource) {
|
||||
suppressionCounter = 100;
|
||||
|
@ -218,8 +227,8 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
|
|||
}
|
||||
|
||||
@Override
|
||||
public float getTargetBodyHeight(Pony player) {
|
||||
return isSuppressed() ? -1 : disguise.getHeight();
|
||||
public Optional<EntityDimensions> getTargetDimensions(Pony player) {
|
||||
return isSuppressed() ? Optional.empty() : disguise.getDimensions();
|
||||
}
|
||||
|
||||
static abstract class PlayerAccess extends PlayerEntity {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
|
||||
public interface ItemWielder {
|
||||
void updateItemUsage(Hand hand, ItemStack stack, int time);
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.entity.behaviour;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -19,6 +20,7 @@ import com.mojang.authlib.GameProfile;
|
|||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.FallingBlockEntity;
|
||||
import net.minecraft.entity.Flutterer;
|
||||
|
@ -46,6 +48,8 @@ public class Disguise implements NbtSerialisable {
|
|||
|
||||
private List<Entity> attachments = new ArrayList<>();
|
||||
|
||||
private Optional<EntityDimensions> dimensions = Optional.empty();
|
||||
|
||||
@Nullable
|
||||
private CompoundTag entityNbt;
|
||||
|
||||
|
@ -200,6 +204,10 @@ public class Disguise implements NbtSerialisable {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public Optional<EntityDimensions> getDimensions() {
|
||||
return dimensions = EntityBehaviour.forEntity(entity).getDimensions(entity, dimensions);
|
||||
}
|
||||
|
||||
public boolean skipsUpdate() {
|
||||
return entity instanceof FallingBlockEntity
|
||||
|| entity instanceof AbstractDecorationEntity
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package com.minelittlepony.unicopia.entity.behaviour;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.entity.ItemWielder;
|
||||
import com.minelittlepony.unicopia.util.Registries;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.FallingBlockEntity;
|
||||
|
@ -36,6 +39,21 @@ public class EntityBehaviour<T extends Entity> {
|
|||
return entity;
|
||||
}
|
||||
|
||||
public Optional<EntityDimensions> getDimensions(T entity, Optional<EntityDimensions> current) {
|
||||
if (entity == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
float h = entity.getHeight() - 0.1F;
|
||||
float w = entity.getWidth();
|
||||
|
||||
if (current.isPresent() && h == current.get().height && w == current.get().width) {
|
||||
return current;
|
||||
}
|
||||
|
||||
return Optional.of(EntityDimensions.changing(entity.getHeight() - 0.1F, entity.getWidth()));
|
||||
}
|
||||
|
||||
public void copyBaseAttributes(LivingEntity from, Entity to) {
|
||||
copyBaseAttributes(from, to, Vec3d.ZERO);
|
||||
}
|
||||
|
@ -102,6 +120,9 @@ public class EntityBehaviour<T extends Entity> {
|
|||
to.prevYaw = from.prevYaw;
|
||||
to.horizontalSpeed = from.horizontalSpeed;
|
||||
to.prevHorizontalSpeed = from.prevHorizontalSpeed;
|
||||
to.horizontalCollision = from.horizontalCollision;
|
||||
to.verticalCollision = from.verticalCollision;
|
||||
to.setOnGround(from.isOnGround());
|
||||
|
||||
to.distanceTraveled = from.distanceTraveled;
|
||||
|
||||
|
@ -139,6 +160,10 @@ public class EntityBehaviour<T extends Entity> {
|
|||
((AbstractSkeletonEntity)to).setAttacking(from.getItemUseTimeLeft() > 0);
|
||||
}
|
||||
|
||||
if (to instanceof ItemWielder) {
|
||||
((ItemWielder)to).updateItemUsage(from.getActiveHand(), from.getActiveItem(), from.getItemUseTimeLeft());
|
||||
}
|
||||
|
||||
if (from.age < 100 || from instanceof PlayerEntity && ((PlayerEntity)from).isCreative()) {
|
||||
to.extinguish();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.unicopia.entity.behaviour;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
|
@ -18,6 +19,7 @@ import net.minecraft.block.entity.ChestBlockEntity;
|
|||
import net.minecraft.block.entity.EnderChestBlockEntity;
|
||||
import net.minecraft.block.enums.DoubleBlockHalf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.FallingBlockEntity;
|
||||
import net.minecraft.state.property.Properties;
|
||||
import net.minecraft.tag.BlockTags;
|
||||
|
@ -29,6 +31,14 @@ public class FallingBlockBehaviour extends EntityBehaviour<FallingBlockEntity> {
|
|||
|
||||
private static final Vec3d UP = Vec3d.of(Direction.UP.getVector());
|
||||
|
||||
private static final Optional<EntityDimensions> FULL_BLOCK = Optional.of(EntityDimensions.changing(1, 0.9F));
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<EntityDimensions> getDimensions(FallingBlockEntity entity, Optional<EntityDimensions> current) {
|
||||
return FULL_BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FallingBlockEntity onCreate(FallingBlockEntity entity, Disguise context, boolean replaceOld) {
|
||||
super.onCreate(entity, context, replaceOld);
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
package com.minelittlepony.unicopia.entity.player;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.HeightPredicate;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.DimensionsPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
|
||||
public final class PlayerDimensions {
|
||||
|
||||
private float defaultEyeHeight;
|
||||
private float defaultBodyHeight;
|
||||
|
||||
private float lastTargetEyeHeight;
|
||||
private float lastTargetBodyHeight;
|
||||
@Nullable
|
||||
private EntityDimensions defaultDimensions;
|
||||
@Nullable
|
||||
private EntityDimensions flyingDimensions;
|
||||
|
||||
private final PlayerPhysics physics;
|
||||
|
||||
|
@ -23,52 +27,42 @@ public final class PlayerDimensions {
|
|||
this.physics = gravity;
|
||||
}
|
||||
|
||||
public float getActiveEyeHeight(float original) {
|
||||
public float calculateActiveEyeHeight(EntityDimensions dimensions, float original) {
|
||||
defaultEyeHeight = original;
|
||||
return calculateTargetEyeHeightWithGravity(calculateTargetBodyHeight());
|
||||
}
|
||||
|
||||
public EntityDimensions getDimensions(EntityPose pos, EntityDimensions dimensions) {
|
||||
defaultBodyHeight = dimensions.height;
|
||||
return EntityDimensions.changing(dimensions.width, calculateTargetBodyHeight());
|
||||
}
|
||||
|
||||
boolean update() {
|
||||
float targetBodyHeight = calculateTargetBodyHeight();
|
||||
float targetEyeHeight = calculateTargetEyeHeightWithGravity(targetBodyHeight);
|
||||
|
||||
if (targetEyeHeight != lastTargetEyeHeight || targetBodyHeight != lastTargetBodyHeight) {
|
||||
lastTargetBodyHeight = targetBodyHeight;
|
||||
lastTargetEyeHeight = targetEyeHeight;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private float calculateTargetEyeHeightWithGravity(float targetBodyHeight) {
|
||||
float height = calculateTargetEyeHeight();
|
||||
|
||||
if (physics.isGravityNegative() && pony.getOwner().isSneaking()) {
|
||||
height += 0.2F;
|
||||
}
|
||||
|
||||
if (physics.isGravityNegative()) {
|
||||
height = targetBodyHeight - height;
|
||||
if (pony.getOwner().isSneaking()) {
|
||||
height += 0.2F;
|
||||
}
|
||||
|
||||
height = dimensions.height - height;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
private float calculateTargetEyeHeight() {
|
||||
if (pony.hasSpell()) {
|
||||
Spell effect = pony.getSpell(true);
|
||||
if (!effect.isDead() && effect instanceof HeightPredicate) {
|
||||
float val = ((HeightPredicate)effect).getTargetEyeHeight(pony);
|
||||
if (val > 0) {
|
||||
return val;
|
||||
}
|
||||
public EntityDimensions calculateDimensions(EntityDimensions dimensions) {
|
||||
if (defaultDimensions == null || dimensions.height != defaultDimensions.height || dimensions.width != defaultDimensions.width) {
|
||||
defaultDimensions = dimensions;
|
||||
flyingDimensions = EntityDimensions.changing(dimensions.width, dimensions.height / 2);
|
||||
}
|
||||
|
||||
return getPredicate().flatMap(e -> e.getTargetDimensions(pony)).orElseGet(() -> {
|
||||
if (physics.isFlyingSurvival && physics.isRainboom()) {
|
||||
return flyingDimensions;
|
||||
}
|
||||
|
||||
return defaultDimensions;
|
||||
});
|
||||
}
|
||||
|
||||
private float calculateTargetEyeHeight() {
|
||||
float height = getPredicate().map(e -> e.getTargetEyeHeight(pony)).orElse(-1F);
|
||||
|
||||
if (height > 0) {
|
||||
return height;
|
||||
}
|
||||
|
||||
if (physics.isFlyingSurvival && physics.isRainboom()) {
|
||||
|
@ -78,22 +72,13 @@ public final class PlayerDimensions {
|
|||
return defaultEyeHeight;
|
||||
}
|
||||
|
||||
private float calculateTargetBodyHeight() {
|
||||
Optional<DimensionsPredicate> getPredicate() {
|
||||
if (pony.hasSpell()) {
|
||||
Spell effect = pony.getSpell(true);
|
||||
if (!effect.isDead() && effect instanceof HeightPredicate) {
|
||||
float val = ((HeightPredicate)effect).getTargetBodyHeight(pony);
|
||||
if (val > 0) {
|
||||
return val;
|
||||
}
|
||||
if (!effect.isDead() && effect instanceof DimensionsPredicate) {
|
||||
return Optional.of(((DimensionsPredicate)effect));
|
||||
}
|
||||
}
|
||||
|
||||
if (physics.isFlyingSurvival && physics.isRainboom()) {
|
||||
return defaultBodyHeight / 2;
|
||||
}
|
||||
|
||||
return defaultBodyHeight;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,14 +17,21 @@ import com.minelittlepony.unicopia.entity.PonyContainer;
|
|||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.entity.Equine;
|
||||
import com.minelittlepony.unicopia.entity.ItemWielder;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
@Mixin(LivingEntity.class)
|
||||
abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<?>> {
|
||||
abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<?>>, ItemWielder {
|
||||
@Shadow
|
||||
protected ItemStack activeItemStack;
|
||||
@Shadow
|
||||
protected int itemUseTimeLeft;
|
||||
|
||||
@Shadow
|
||||
private Optional<BlockPos> climbingPos;
|
||||
|
@ -33,6 +40,9 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
|||
|
||||
private MixinLivingEntity() { super(null, null); }
|
||||
|
||||
@Shadow
|
||||
protected abstract void setLivingFlag(int mask, boolean value);
|
||||
|
||||
@Override
|
||||
public Equine<?> create() {
|
||||
return new Creature((LivingEntity)(Object)this);
|
||||
|
@ -108,6 +118,17 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
|||
return get().getPhysics().calcGravity(initial);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateItemUsage(Hand hand, ItemStack stack, int time) {
|
||||
activeItemStack = stack;
|
||||
itemUseTimeLeft = time;
|
||||
|
||||
if (!world.isClient) {
|
||||
setLivingFlag(1, !stack.isEmpty());
|
||||
setLivingFlag(2, hand == Hand.OFF_HAND);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockPos getLandingPos() {
|
||||
if (get().getPhysics().isGravityNegative()) {
|
||||
|
|
|
@ -91,13 +91,13 @@ abstract class MixinPlayerEntity extends LivingEntity implements PonyContainer<P
|
|||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
private void onGetActiveEyeHeight(EntityPose pose, EntityDimensions dimensions, CallbackInfoReturnable<Float> info) {
|
||||
info.setReturnValue(get().getMotion().getDimensions().getActiveEyeHeight(info.getReturnValue()));
|
||||
info.setReturnValue(get().getMotion().getDimensions().calculateActiveEyeHeight(dimensions, info.getReturnValue()));
|
||||
}
|
||||
|
||||
@Inject(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true)
|
||||
public void onGetDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> info) {
|
||||
info.setReturnValue(get().getMotion().getDimensions().getDimensions(pose, info.getReturnValue()));
|
||||
info.setReturnValue(get().getMotion().getDimensions().calculateDimensions(info.getReturnValue()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue