minecraft-source/src/net/minecraft/world/item/MapItem.java

399 lines
20 KiB
Java

package net.minecraft.world.item;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.InteractionResult;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.chat.Component;
import java.util.List;
import net.minecraft.network.protocol.Packet;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.LevelChunk;
import com.google.common.collect.Multiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multisets;
import net.minecraft.core.Vec3i;
import net.minecraft.world.level.material.MaterialColor;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.core.BlockPos;
import com.google.common.collect.LinkedHashMultiset;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.nbt.CompoundTag;
import javax.annotation.Nullable;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
public class MapItem extends ComplexItem {
public MapItem(final Properties a) {
super(a);
}
public static ItemStack create(final Level bjt, final int integer2, final int integer3, final byte byte4, final boolean boolean5, final boolean boolean6) {
final ItemStack bek7 = new ItemStack(Items.FILLED_MAP);
createAndStoreSavedData(bek7, bjt, integer2, integer3, byte4, boolean5, boolean6, bjt.dimension.getType());
return bek7;
}
@Nullable
public static MapItemSavedData getSavedData(final ItemStack bek, final Level bjt) {
return bjt.getMapData(makeKey(getMapId(bek)));
}
@Nullable
public static MapItemSavedData getOrCreateSavedData(final ItemStack bek, final Level bjt) {
MapItemSavedData crd3 = getSavedData(bek, bjt);
if (crd3 == null && !bjt.isClientSide) {
crd3 = createAndStoreSavedData(bek, bjt, bjt.getLevelData().getXSpawn(), bjt.getLevelData().getZSpawn(), 3, false, false, bjt.dimension.getType());
}
return crd3;
}
public static int getMapId(final ItemStack bek) {
final CompoundTag jt2 = bek.getTag();
return (jt2 != null && jt2.contains("map", 99)) ? jt2.getInt("map") : 0;
}
private static MapItemSavedData createAndStoreSavedData(final ItemStack bek, final Level bjt, final int integer3, final int integer4, final int integer5, final boolean boolean6, final boolean boolean7, final DimensionType cbf) {
final int integer6 = bjt.getFreeMapId();
final MapItemSavedData crd10 = new MapItemSavedData(makeKey(integer6));
crd10.setProperties(integer3, integer4, integer5, boolean6, boolean7, cbf);
bjt.setMapData(crd10);
bek.getOrCreateTag().putInt("map", integer6);
return crd10;
}
public static String makeKey(final int integer) {
return "map_" + integer;
}
public void update(final Level bjt, final Entity akn, final MapItemSavedData crd) {
if (bjt.dimension.getType() != crd.dimension || !(akn instanceof Player)) {
return;
}
final int integer5 = 1 << crd.scale;
final int integer6 = crd.x;
final int integer7 = crd.z;
final int integer8 = Mth.floor(akn.getX() - integer6) / integer5 + 64;
final int integer9 = Mth.floor(akn.getZ() - integer7) / integer5 + 64;
int integer10 = 128 / integer5;
if (bjt.dimension.isHasCeiling()) {
integer10 /= 2;
}
final MapItemSavedData.HoldingPlayer holdingPlayer;
final MapItemSavedData.HoldingPlayer a11 = holdingPlayer = crd.getHoldingPlayer((Player)akn);
++holdingPlayer.step;
boolean boolean12 = false;
for (int integer11 = integer8 - integer10 + 1; integer11 < integer8 + integer10; ++integer11) {
if ((integer11 & 0xF) == (a11.step & 0xF) || boolean12) {
boolean12 = false;
double double14 = 0.0;
for (int integer12 = integer9 - integer10 - 1; integer12 < integer9 + integer10; ++integer12) {
if (integer11 >= 0 && integer12 >= -1 && integer11 < 128) {
if (integer12 < 128) {
final int integer13 = integer11 - integer8;
final int integer14 = integer12 - integer9;
final boolean boolean13 = integer13 * integer13 + integer14 * integer14 > (integer10 - 2) * (integer10 - 2);
final int integer15 = (integer6 / integer5 + integer11 - 64) * integer5;
final int integer16 = (integer7 / integer5 + integer12 - 64) * integer5;
final Multiset<MaterialColor> multiset22 = LinkedHashMultiset.create();
final LevelChunk cai23 = bjt.getChunkAt(new BlockPos(integer15, 0, integer16));
if (!cai23.isEmpty()) {
final ChunkPos bje24 = cai23.getPos();
final int integer17 = integer15 & 0xF;
final int integer18 = integer16 & 0xF;
int integer19 = 0;
double double15 = 0.0;
if (bjt.dimension.isHasCeiling()) {
int integer20 = integer15 + integer16 * 231871;
integer20 = integer20 * integer20 * 31287121 + integer20 * 11;
if ((integer20 >> 20 & 0x1) == 0x0) {
multiset22.add(Blocks.DIRT.defaultBlockState().getMapColor(bjt, BlockPos.ZERO), 10);
}
else {
multiset22.add(Blocks.STONE.defaultBlockState().getMapColor(bjt, BlockPos.ZERO), 100);
}
double15 = 100.0;
}
else {
final BlockPos.MutableBlockPos a12 = new BlockPos.MutableBlockPos();
final BlockPos.MutableBlockPos a13 = new BlockPos.MutableBlockPos();
for (int integer21 = 0; integer21 < integer5; ++integer21) {
for (int integer22 = 0; integer22 < integer5; ++integer22) {
int integer23 = cai23.getHeight(Heightmap.Types.WORLD_SURFACE, integer21 + integer17, integer22 + integer18) + 1;
BlockState byg35;
if (integer23 > 1) {
do {
--integer23;
a12.set(bje24.getMinBlockX() + integer21 + integer17, integer23, bje24.getMinBlockZ() + integer22 + integer18);
byg35 = cai23.getBlockState(a12);
} while (byg35.getMapColor(bjt, a12) == MaterialColor.NONE && integer23 > 0);
if (integer23 > 0 && !byg35.getFluidState().isEmpty()) {
int integer24 = integer23 - 1;
a13.set(a12);
BlockState byg36;
do {
a13.setY(integer24--);
byg36 = cai23.getBlockState(a13);
++integer19;
} while (integer24 > 0 && !byg36.getFluidState().isEmpty());
byg35 = this.getCorrectStateForFluidBlock(bjt, byg35, a12);
}
}
else {
byg35 = Blocks.BEDROCK.defaultBlockState();
}
crd.checkBanners(bjt, bje24.getMinBlockX() + integer21 + integer17, bje24.getMinBlockZ() + integer22 + integer18);
double15 += integer23 / (double)(integer5 * integer5);
multiset22.add(byg35.getMapColor(bjt, a12));
}
}
}
integer19 /= integer5 * integer5;
double double16 = (double15 - double14) * 4.0 / (integer5 + 4) + ((integer11 + integer12 & 0x1) - 0.5) * 0.4;
int integer21 = 1;
if (double16 > 0.6) {
integer21 = 2;
}
if (double16 < -0.6) {
integer21 = 0;
}
final MaterialColor col33 = Iterables.<MaterialColor>getFirst(Multisets.<MaterialColor>copyHighestCountFirst(multiset22), MaterialColor.NONE);
if (col33 == MaterialColor.WATER) {
double16 = integer19 * 0.1 + (integer11 + integer12 & 0x1) * 0.2;
integer21 = 1;
if (double16 < 0.5) {
integer21 = 2;
}
if (double16 > 0.9) {
integer21 = 0;
}
}
double14 = double15;
if (integer12 >= 0) {
if (integer13 * integer13 + integer14 * integer14 < integer10 * integer10) {
if (!boolean13 || (integer11 + integer12 & 0x1) != 0x0) {
final byte byte34 = crd.colors[integer11 + integer12 * 128];
final byte byte35 = (byte)(col33.id * 4 + integer21);
if (byte34 != byte35) {
crd.colors[integer11 + integer12 * 128] = byte35;
crd.setDirty(integer11, integer12);
boolean12 = true;
}
}
}
}
}
}
}
}
}
}
}
private BlockState getCorrectStateForFluidBlock(final Level bjt, final BlockState byg, final BlockPos fk) {
final FluidState cog5 = byg.getFluidState();
if (!cog5.isEmpty() && !byg.isFaceSturdy(bjt, fk, Direction.UP)) {
return cog5.createLegacyBlock();
}
return byg;
}
private static boolean isLand(final Biome[] arr, final int integer2, final int integer3, final int integer4) {
return arr[integer3 * integer2 + integer4 * integer2 * 128 * integer2].getDepth() >= 0.0f;
}
public static void renderBiomePreviewMap(final ServerLevel xd, final ItemStack bek) {
final MapItemSavedData crd3 = getOrCreateSavedData(bek, xd);
if (crd3 == null) {
return;
}
if (xd.dimension.getType() != crd3.dimension) {
return;
}
final int integer4 = 1 << crd3.scale;
final int integer5 = crd3.x;
final int integer6 = crd3.z;
final Biome[] arr7 = new Biome[128 * integer4 * 128 * integer4];
for (int integer7 = 0; integer7 < 128 * integer4; ++integer7) {
for (int integer8 = 0; integer8 < 128 * integer4; ++integer8) {
arr7[integer7 * 128 * integer4 + integer8] = xd.getBiome(new BlockPos((integer5 / integer4 - 64) * integer4 + integer8, 0, (integer6 / integer4 - 64) * integer4 + integer7));
}
}
for (int integer7 = 0; integer7 < 128; ++integer7) {
for (int integer8 = 0; integer8 < 128; ++integer8) {
if (integer7 > 0 && integer8 > 0 && integer7 < 127 && integer8 < 127) {
final Biome bkq10 = arr7[integer7 * integer4 + integer8 * integer4 * 128 * integer4];
int integer9 = 8;
if (isLand(arr7, integer4, integer7 - 1, integer8 - 1)) {
--integer9;
}
if (isLand(arr7, integer4, integer7 - 1, integer8 + 1)) {
--integer9;
}
if (isLand(arr7, integer4, integer7 - 1, integer8)) {
--integer9;
}
if (isLand(arr7, integer4, integer7 + 1, integer8 - 1)) {
--integer9;
}
if (isLand(arr7, integer4, integer7 + 1, integer8 + 1)) {
--integer9;
}
if (isLand(arr7, integer4, integer7 + 1, integer8)) {
--integer9;
}
if (isLand(arr7, integer4, integer7, integer8 - 1)) {
--integer9;
}
if (isLand(arr7, integer4, integer7, integer8 + 1)) {
--integer9;
}
int integer10 = 3;
MaterialColor col13 = MaterialColor.NONE;
if (bkq10.getDepth() < 0.0f) {
col13 = MaterialColor.COLOR_ORANGE;
if (integer9 > 7 && integer8 % 2 == 0) {
integer10 = (integer7 + (int)(Mth.sin(integer8 + 0.0f) * 7.0f)) / 8 % 5;
if (integer10 == 3) {
integer10 = 1;
}
else if (integer10 == 4) {
integer10 = 0;
}
}
else if (integer9 > 7) {
col13 = MaterialColor.NONE;
}
else if (integer9 > 5) {
integer10 = 1;
}
else if (integer9 > 3) {
integer10 = 0;
}
else if (integer9 > 1) {
integer10 = 0;
}
}
else if (integer9 > 0) {
col13 = MaterialColor.COLOR_BROWN;
if (integer9 > 3) {
integer10 = 1;
}
else {
integer10 = 3;
}
}
if (col13 != MaterialColor.NONE) {
crd3.colors[integer7 + integer8 * 128] = (byte)(col13.id * 4 + integer10);
crd3.setDirty(integer7, integer8);
}
}
}
}
}
@Override
public void inventoryTick(final ItemStack bek, final Level bjt, final Entity akn, final int integer, final boolean boolean5) {
if (bjt.isClientSide) {
return;
}
final MapItemSavedData crd7 = getOrCreateSavedData(bek, bjt);
if (crd7 == null) {
return;
}
if (akn instanceof Player) {
final Player ayg8 = (Player)akn;
crd7.tickCarriedBy(ayg8, bek);
}
if (!crd7.locked && (boolean5 || (akn instanceof Player && ((Player)akn).getOffhandItem() == bek))) {
this.update(bjt, akn, crd7);
}
}
@Nullable
@Override
public Packet<?> getUpdatePacket(final ItemStack bek, final Level bjt, final Player ayg) {
return getOrCreateSavedData(bek, bjt).getUpdatePacket(bek, bjt, ayg);
}
@Override
public void onCraftedBy(final ItemStack bek, final Level bjt, final Player ayg) {
final CompoundTag jt5 = bek.getTag();
if (jt5 != null && jt5.contains("map_scale_direction", 99)) {
scaleMap(bek, bjt, jt5.getInt("map_scale_direction"));
jt5.remove("map_scale_direction");
}
}
protected static void scaleMap(final ItemStack bek, final Level bjt, final int integer) {
final MapItemSavedData crd4 = getOrCreateSavedData(bek, bjt);
if (crd4 != null) {
createAndStoreSavedData(bek, bjt, crd4.x, crd4.z, Mth.clamp(crd4.scale + integer, 0, 4), crd4.trackingPosition, crd4.unlimitedTracking, crd4.dimension);
}
}
@Nullable
public static ItemStack lockMap(final Level bjt, final ItemStack bek) {
final MapItemSavedData crd3 = getOrCreateSavedData(bek, bjt);
if (crd3 != null) {
final ItemStack bek2 = bek.copy();
final MapItemSavedData crd4 = createAndStoreSavedData(bek2, bjt, 0, 0, crd3.scale, crd3.trackingPosition, crd3.unlimitedTracking, crd3.dimension);
crd4.lockData(crd3);
return bek2;
}
return null;
}
@Override
public void appendHoverText(final ItemStack bek, @Nullable final Level bjt, final List<Component> list, final TooltipFlag bft) {
final MapItemSavedData crd6 = (bjt == null) ? null : getOrCreateSavedData(bek, bjt);
if (crd6 != null && crd6.locked) {
list.add(new TranslatableComponent("filled_map.locked", new Object[] { getMapId(bek) }).withStyle(ChatFormatting.GRAY));
}
if (bft.isAdvanced()) {
if (crd6 != null) {
list.add(new TranslatableComponent("filled_map.id", new Object[] { getMapId(bek) }).withStyle(ChatFormatting.GRAY));
list.add(new TranslatableComponent("filled_map.scale", new Object[] { 1 << crd6.scale }).withStyle(ChatFormatting.GRAY));
list.add(new TranslatableComponent("filled_map.level", new Object[] { crd6.scale, 4 }).withStyle(ChatFormatting.GRAY));
}
else {
list.add(new TranslatableComponent("filled_map.unknown", new Object[0]).withStyle(ChatFormatting.GRAY));
}
}
}
public static int getColor(final ItemStack bek) {
final CompoundTag jt2 = bek.getTagElement("display");
if (jt2 != null && jt2.contains("MapColor", 99)) {
final int integer3 = jt2.getInt("MapColor");
return 0xFF000000 | (integer3 & 0xFFFFFF);
}
return -12173266;
}
@Override
public InteractionResult useOn(final UseOnContext bfw) {
final BlockState byg3 = bfw.getLevel().getBlockState(bfw.getClickedPos());
if (byg3.is(BlockTags.BANNERS)) {
if (!bfw.level.isClientSide) {
final MapItemSavedData crd4 = getOrCreateSavedData(bfw.getItemInHand(), bfw.getLevel());
crd4.toggleBanner(bfw.getLevel(), bfw.getClickedPos());
}
return InteractionResult.SUCCESS;
}
return super.useOn(bfw);
}
}