Code/net/minecraft/world/item/SpawnEggItem.java

191 lines
8.0 KiB
Java

package net.minecraft.world.item;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.Spawner;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
public class SpawnEggItem extends Item {
private static final Map<EntityType<? extends Mob>, SpawnEggItem> BY_ID = Maps.newIdentityHashMap();
private final EntityType<?> defaultType;
public SpawnEggItem(EntityType<? extends Mob> p_43207_, Item.Properties p_43210_) {
super(p_43210_);
this.defaultType = p_43207_;
BY_ID.put(p_43207_, this);
}
@Override
public InteractionResult useOn(UseOnContext p_43223_) {
Level level = p_43223_.getLevel();
if (level.isClientSide) {
return InteractionResult.SUCCESS;
} else {
ItemStack itemstack = p_43223_.getItemInHand();
BlockPos blockpos = p_43223_.getClickedPos();
Direction direction = p_43223_.getClickedFace();
BlockState blockstate = level.getBlockState(blockpos);
if (level.getBlockEntity(blockpos) instanceof Spawner spawner) {
EntityType<?> entitytype1 = this.getType(level.registryAccess(), itemstack);
spawner.setEntityId(entitytype1, level.getRandom());
level.sendBlockUpdated(blockpos, blockstate, blockstate, 3);
level.gameEvent(p_43223_.getPlayer(), GameEvent.BLOCK_CHANGE, blockpos);
itemstack.shrink(1);
return InteractionResult.SUCCESS;
} else {
BlockPos blockpos1;
if (blockstate.getCollisionShape(level, blockpos).isEmpty()) {
blockpos1 = blockpos;
} else {
blockpos1 = blockpos.relative(direction);
}
EntityType<?> entitytype = this.getType(level.registryAccess(), itemstack);
if (entitytype.spawn(
(ServerLevel)level,
itemstack,
p_43223_.getPlayer(),
blockpos1,
EntitySpawnReason.SPAWN_ITEM_USE,
true,
!Objects.equals(blockpos, blockpos1) && direction == Direction.UP
)
!= null) {
itemstack.shrink(1);
level.gameEvent(p_43223_.getPlayer(), GameEvent.ENTITY_PLACE, blockpos);
}
return InteractionResult.SUCCESS;
}
}
}
@Override
public InteractionResult use(Level p_43225_, Player p_43226_, InteractionHand p_43227_) {
ItemStack itemstack = p_43226_.getItemInHand(p_43227_);
BlockHitResult blockhitresult = getPlayerPOVHitResult(p_43225_, p_43226_, ClipContext.Fluid.SOURCE_ONLY);
if (blockhitresult.getType() != HitResult.Type.BLOCK) {
return InteractionResult.PASS;
} else if (p_43225_ instanceof ServerLevel serverlevel) {
BlockPos $$8 = blockhitresult.getBlockPos();
if (!(p_43225_.getBlockState($$8).getBlock() instanceof LiquidBlock)) {
return InteractionResult.PASS;
} else if (p_43225_.mayInteract(p_43226_, $$8) && p_43226_.mayUseItemAt($$8, blockhitresult.getDirection(), itemstack)) {
EntityType<?> entitytype = this.getType(serverlevel.registryAccess(), itemstack);
Entity entity = entitytype.spawn(serverlevel, itemstack, p_43226_, $$8, EntitySpawnReason.SPAWN_ITEM_USE, false, false);
if (entity == null) {
return InteractionResult.PASS;
} else {
itemstack.consume(1, p_43226_);
p_43226_.awardStat(Stats.ITEM_USED.get(this));
p_43225_.gameEvent(p_43226_, GameEvent.ENTITY_PLACE, entity.position());
return InteractionResult.SUCCESS;
}
} else {
return InteractionResult.FAIL;
}
} else {
return InteractionResult.SUCCESS;
}
}
public boolean spawnsEntity(HolderLookup.Provider p_376104_, ItemStack p_331553_, EntityType<?> p_43232_) {
return Objects.equals(this.getType(p_376104_, p_331553_), p_43232_);
}
@Nullable
public static SpawnEggItem byId(@Nullable EntityType<?> p_43214_) {
return BY_ID.get(p_43214_);
}
public static Iterable<SpawnEggItem> eggs() {
return Iterables.unmodifiableIterable(BY_ID.values());
}
public EntityType<?> getType(HolderLookup.Provider p_377295_, ItemStack p_334231_) {
CustomData customdata = p_334231_.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
if (!customdata.isEmpty()) {
EntityType<?> entitytype = customdata.parseEntityType(p_377295_, Registries.ENTITY_TYPE);
if (entitytype != null) {
return entitytype;
}
}
return this.defaultType;
}
@Override
public FeatureFlagSet requiredFeatures() {
return this.defaultType.requiredFeatures();
}
public Optional<Mob> spawnOffspringFromSpawnEgg(Player p_43216_, Mob p_43217_, EntityType<? extends Mob> p_43218_, ServerLevel p_43219_, Vec3 p_43220_, ItemStack p_43221_) {
if (!this.spawnsEntity(p_43219_.registryAccess(), p_43221_, p_43218_)) {
return Optional.empty();
} else {
Mob mob;
if (p_43217_ instanceof AgeableMob) {
mob = ((AgeableMob)p_43217_).getBreedOffspring(p_43219_, (AgeableMob)p_43217_);
} else {
mob = p_43218_.create(p_43219_, EntitySpawnReason.SPAWN_ITEM_USE);
}
if (mob == null) {
return Optional.empty();
} else {
mob.setBaby(true);
if (!mob.isBaby()) {
return Optional.empty();
} else {
mob.snapTo(p_43220_.x(), p_43220_.y(), p_43220_.z(), 0.0F, 0.0F);
mob.applyComponentsFromItemStack(p_43221_);
p_43219_.addFreshEntityWithPassengers(mob);
p_43221_.consume(1, p_43216_);
return Optional.of(mob);
}
}
}
}
@Override
public boolean shouldPrintOpWarning(ItemStack p_378492_, @Nullable Player p_377094_) {
if (p_377094_ != null && p_377094_.getPermissionLevel() >= 2) {
CustomData customdata = p_378492_.get(DataComponents.ENTITY_DATA);
if (customdata != null) {
EntityType<?> entitytype = customdata.parseEntityType(p_377094_.level().registryAccess(), Registries.ENTITY_TYPE);
return entitytype != null && entitytype.onlyOpCanSetNbt();
}
}
return false;
}
}