mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-04-01 08:45:28 +02:00
98 lines
No EOL
3.8 KiB
Java
98 lines
No EOL
3.8 KiB
Java
package com.minelittlepony.unicopia.item;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.function.Predicate;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity;
|
|
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
|
import com.minelittlepony.unicopia.util.Dispensable;
|
|
|
|
import net.minecraft.block.DispenserBlock;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
import net.minecraft.item.BoatItem;
|
|
import net.minecraft.item.Item;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.predicate.entity.EntityPredicates;
|
|
import net.minecraft.stat.Stats;
|
|
import net.minecraft.util.Hand;
|
|
import net.minecraft.util.TypedActionResult;
|
|
import net.minecraft.util.hit.BlockHitResult;
|
|
import net.minecraft.util.hit.HitResult;
|
|
import net.minecraft.util.math.BlockPointer;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.Direction;
|
|
import net.minecraft.util.math.Vec3d;
|
|
import net.minecraft.world.RaycastContext;
|
|
import net.minecraft.world.World;
|
|
|
|
public class BasketItem extends Item implements Dispensable {
|
|
private static final Predicate<Entity> RIDERS = EntityPredicates.EXCEPT_SPECTATOR.and(Entity::canHit);
|
|
private static final double REACH = 5;
|
|
|
|
private final AirBalloonEntity.BasketType type;
|
|
|
|
public static final Map<AirBalloonEntity.BasketType, BasketItem> REGISTRY = new HashMap<>();
|
|
|
|
public BasketItem(AirBalloonEntity.BasketType type, Item.Settings settings) {
|
|
super(settings);
|
|
this.type = type;
|
|
DispenserBlock.registerBehavior(this, createDispenserBehaviour());
|
|
REGISTRY.put(type, this);
|
|
}
|
|
|
|
@Override
|
|
public TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack) {
|
|
Direction facing = source.state().get(DispenserBlock.FACING);
|
|
BlockPos pos = source.pos().offset(facing);
|
|
float yaw = facing.getOpposite().asRotation();
|
|
return placeEntity(stack, source.world(), pos.getX(), pos.getY(), pos.getZ(), yaw, null);
|
|
}
|
|
|
|
@Override
|
|
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
|
ItemStack stack = user.getStackInHand(hand);
|
|
BlockHitResult hit = BoatItem.raycast(world, user, RaycastContext.FluidHandling.ANY);
|
|
|
|
if (hit.getType() == HitResult.Type.MISS) {
|
|
return TypedActionResult.pass(stack);
|
|
}
|
|
|
|
Vec3d eyePos = user.getEyePos();
|
|
if (world.getOtherEntities(user, user.getBoundingBox().stretch(user.getRotationVec(1).multiply(REACH)).expand(1), RIDERS).stream()
|
|
.anyMatch(entity -> entity.getBoundingBox().expand(entity.getTargetingMargin()).contains(eyePos))) {
|
|
return TypedActionResult.pass(stack);
|
|
}
|
|
|
|
if (hit.getType() == HitResult.Type.BLOCK) {
|
|
return placeEntity(stack, world, hit.getPos().x, hit.getPos().y, hit.getPos().z, user.getYaw() + 180, user);
|
|
}
|
|
|
|
return TypedActionResult.pass(stack);
|
|
}
|
|
|
|
private TypedActionResult<ItemStack> placeEntity(ItemStack stack, World world, double x, double y, double z, float yaw, @Nullable PlayerEntity user) {
|
|
AirBalloonEntity entity = UEntities.AIR_BALLOON.create(world);
|
|
entity.updatePositionAndAngles(x, y, z, 0, 0);
|
|
entity.setHeadYaw(yaw);
|
|
entity.setBodyYaw(yaw);
|
|
entity.setBasketType(type);
|
|
if (!world.isSpaceEmpty(entity, entity.getBoundingBox())) {
|
|
return TypedActionResult.fail(stack);
|
|
}
|
|
if (!world.isClient) {
|
|
world.spawnEntity(entity);
|
|
if (user != null) {
|
|
user.incrementStat(Stats.USED.getOrCreateStat(this));
|
|
}
|
|
if (user == null || !user.getAbilities().creativeMode) {
|
|
stack.decrement(1);
|
|
}
|
|
}
|
|
|
|
return TypedActionResult.success(stack, world.isClient());
|
|
}
|
|
} |