mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 11:36:43 +01:00
Disguised changelings will now have the appropriate collission boxes for whatever block/boat/minecraft they disguise themselves as
This commit is contained in:
parent
f14ab56d54
commit
d29cc60d01
4 changed files with 92 additions and 1 deletions
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -13,11 +15,13 @@ import com.minelittlepony.unicopia.InteractionManager;
|
||||||
import com.minelittlepony.unicopia.Owned;
|
import com.minelittlepony.unicopia.Owned;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.CasterUtils;
|
import com.minelittlepony.unicopia.ability.magic.CasterUtils;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.SkullBlockEntity;
|
import net.minecraft.block.entity.SkullBlockEntity;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
@ -35,6 +39,12 @@ import net.minecraft.entity.mob.VexEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.projectile.ShulkerBulletEntity;
|
import net.minecraft.entity.projectile.ShulkerBulletEntity;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.util.function.BooleanBiFunction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Box;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
|
|
||||||
public class Disguise implements NbtSerialisable {
|
public class Disguise implements NbtSerialisable {
|
||||||
|
|
||||||
|
@ -298,4 +308,40 @@ public class Disguise implements NbtSerialisable {
|
||||||
|
|
||||||
return entityNbt;
|
return entityNbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getCollissionShapes(ShapeContext context, Consumer<VoxelShape> output) {
|
||||||
|
getCollissionShapes(getAppearance(), context, output);
|
||||||
|
getAttachments().forEach(e -> getCollissionShapes(e, context, output));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getCollissionShapes(Entity entity, ShapeContext context, Consumer<VoxelShape> output) {
|
||||||
|
if (entity.method_30948()) {
|
||||||
|
output.accept(VoxelShapes.cuboid(entity.getBoundingBox()));
|
||||||
|
} else if (entity instanceof FallingBlockEntity) {
|
||||||
|
BlockPos pos = entity.getBlockPos();
|
||||||
|
output.accept(((FallingBlockEntity) entity).getBlockState()
|
||||||
|
.getCollisionShape(entity.world, entity.getBlockPos(), context)
|
||||||
|
.offset(pos.getX(), pos.getY(), pos.getZ())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<VoxelShape> getColissonShapes(@Nullable Entity entity, WorldAccess world, Box box, Predicate<Entity> predicate) {
|
||||||
|
List<VoxelShape> shapes = new ArrayList<>();
|
||||||
|
ShapeContext ctx = entity == null ? ShapeContext.absent() : ShapeContext.of(entity);
|
||||||
|
VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D));
|
||||||
|
|
||||||
|
world.getOtherEntities(entity, box.expand(0.5), predicate.and(e -> {
|
||||||
|
CasterUtils.toCaster(e).flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false)).ifPresent(p -> {
|
||||||
|
p.getDisguise().getCollissionShapes(ctx, shape -> {
|
||||||
|
if (!shape.isEmpty() && VoxelShapes.matchesAnywhere(shape, entityShape, BooleanBiFunction.AND)) {
|
||||||
|
shapes.add(shape);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.CasterUtils;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
import com.minelittlepony.unicopia.entity.Creature;
|
import com.minelittlepony.unicopia.entity.Creature;
|
||||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||||
|
@ -69,6 +70,18 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "isPushable()Z", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onIsPushable(CallbackInfoReturnable<Boolean> info) {
|
||||||
|
CasterUtils.toCaster(this)
|
||||||
|
.flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false))
|
||||||
|
.map(DisguiseSpell::getDisguise)
|
||||||
|
.map(Disguise::getAppearance)
|
||||||
|
.filter(Entity::isPushable)
|
||||||
|
.ifPresent(v -> {
|
||||||
|
info.setReturnValue(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "canSee(Lnet/minecraft/entity/Entity;)Z", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "canSee(Lnet/minecraft/entity/Entity;)Z", at = @At("HEAD"), cancellable = true)
|
||||||
private void onCanSee(Entity other, CallbackInfoReturnable<Boolean> info) {
|
private void onCanSee(Entity other, CallbackInfoReturnable<Boolean> info) {
|
||||||
if (get().isInvisible()) {
|
if (get().isInvisible()) {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.minelittlepony.unicopia.mixin;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.Box;
|
||||||
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldAccess;
|
||||||
|
|
||||||
|
@Mixin(World.class)
|
||||||
|
abstract class MixinWorld implements WorldAccess {
|
||||||
|
@Override
|
||||||
|
public Stream<VoxelShape> getEntityCollisions(@Nullable Entity entity, Box box, Predicate<Entity> predicate) {
|
||||||
|
if (box.getAverageSideLength() >= 1.0E-7D) {
|
||||||
|
List<VoxelShape> shapes = Disguise.getColissonShapes(entity, this, box, predicate);
|
||||||
|
if (!shapes.isEmpty()) {
|
||||||
|
return Stream.concat(shapes.stream(), WorldAccess.super.getEntityCollisions(entity, box, predicate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WorldAccess.super.getEntityCollisions(entity, box, predicate);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,8 @@
|
||||||
"MixinServerPlayerEntity",
|
"MixinServerPlayerEntity",
|
||||||
"MixinSheepEntity",
|
"MixinSheepEntity",
|
||||||
"MixinShulkerEntity",
|
"MixinShulkerEntity",
|
||||||
"MixinTargetPredicate"
|
"MixinTargetPredicate",
|
||||||
|
"MixinWorld"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinCamera",
|
"client.MixinCamera",
|
||||||
|
|
Loading…
Reference in a new issue