399 lines
20 KiB
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);
|
|
}
|
|
}
|