ModernLifePatch/src-source/main/java/com/dairymoose/modernlife/items/CameraItem.java
2024-10-26 09:40:21 +08:00

181 lines
7.4 KiB
Java

package com.dairymoose.modernlife.items;
import com.dairymoose.modernlife.core.ModernLifeConfig;
import com.dairymoose.modernlife.core.ModernLifeNetwork;
import com.dairymoose.modernlife.network.play.client.ServerboundMultipartCameraPacket;
import com.dairymoose.modernlife.util.CanvasData;
import com.mojang.blaze3d.platform.NativeImage;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.Screenshot;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/* loaded from: outputsrg.jar:com/dairymoose/modernlife/items/CameraItem.class */
public class CameraItem extends Item {
private static final Logger LOGGER = LogManager.getLogger();
public static boolean usingCamera = false;
public static Map<Player, Boolean> usingCameraServer = new HashMap();
public static boolean pendingSnapshot = false;
public CameraItem(Properties p_i48530_4_) {
super(p_i48530_4_);
}
private static int toInternalRgbFormat(int nativeRgb) {
int r = nativeRgb & 255;
int g = (nativeRgb & 65280) >> 8;
int b = (nativeRgb & 16711680) >> 16;
return (r << 16) | (g << 8) | b;
}
private static int getAverageRgbAt(NativeImage img, int x, int y, float pixelSampleWidth, float pixelSampleHeight) {
int destX = (int) (x * pixelSampleWidth);
int destY = (int) (y * pixelSampleHeight);
int rSum = 0;
int gSum = 0;
int bSum = 0;
int iterations = 0;
int hStart = (int) ((-pixelSampleHeight) / 2.0f);
int hEnd = (int) (pixelSampleHeight / 2.0f);
int wStart = (int) ((-pixelSampleWidth) / 2.0f);
int wEnd = (int) (pixelSampleWidth / 2.0f);
if (hStart == hEnd) {
hStart = 0;
hEnd = 1;
wStart = 0;
wEnd = 1;
}
for (int h = hStart; h < hEnd; h++) {
for (int w = wStart; w < wEnd; w++) {
int finalX = destX + w;
int finalY = destY + h;
int rgb = toInternalRgbFormat(img.getPixelRGBA(Math.min(Math.max(finalX, 0), img.getWidth() - 1), Math.min(Math.max(finalY, 0), img.getHeight() - 1)));
rSum += CanvasData.getRValue(rgb);
gSum += CanvasData.getGValue(rgb);
bSum += CanvasData.getBValue(rgb);
iterations++;
}
}
int rAvg = rSum / iterations;
int gAvg = gSum / iterations;
int bAvg = bSum / iterations;
return (rAvg << 16) | (gAvg << 8) | bAvg;
}
public static void takePhoto() {
Minecraft.getInstance().player.playSound(SoundEvents.SLIME_SQUISH, 1.0f, 2.0f);
NativeImage img = Screenshot.takeScreenshot(Minecraft.getInstance().getMainRenderTarget());
int texW = 512;
int texH = 512;
Integer configIntW = (Integer) ModernLifeConfig.COMMON.cameraResolutionW.get();
Integer configIntH = (Integer) ModernLifeConfig.COMMON.cameraResolutionH.get();
if (configIntW != null) {
texW = configIntW.intValue();
}
if (configIntH != null) {
texH = configIntH.intValue();
}
int maxW = Minecraft.getInstance().getWindow().getScreenWidth();
int maxH = Minecraft.getInstance().getWindow().getScreenHeight();
if (texW > maxW) {
texW = maxW;
}
if (texH > maxH) {
texH = maxH;
}
float pixelsPerWidth = img.getWidth() / texW;
float pixelsPerHeight = img.getHeight() / texH;
float pixelsPerWidth2 = Math.max(pixelsPerWidth, 1.0f);
float pixelsPerHeight2 = Math.max(pixelsPerHeight, 1.0f);
CanvasData cameraData = new CanvasData();
cameraData.setTextureSize(texW, texH);
cameraData.initImage();
for (int h = 0; h < texH; h++) {
for (int w = 0; w < texW; w++) {
cameraData.setRgbPixel(w, h, getAverageRgbAt(img, w, h, pixelsPerWidth2, pixelsPerHeight2));
}
}
byte[] compressed = cameraData.toCompressedNbt();
List<byte[]> parts = new ArrayList<>();
for (int i = 0; i < Math.ceil(compressed.length / 30000); i++) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
int startIndex = i * 30000;
int bytesToWrite = Math.min(compressed.length - startIndex, 30000);
stream.write(compressed, startIndex, bytesToWrite);
byte[] part = stream.toByteArray();
parts.add(part);
}
for (int i2 = 0; i2 < parts.size(); i2++) {
int seqNo = i2 + 1;
boolean last = false;
if (seqNo == parts.size()) {
last = true;
}
ModernLifeNetwork.INSTANCE.sendToServer(new ServerboundMultipartCameraPacket(seqNo, last, parts.get(i2), texW, texH));
}
}
public boolean onDroppedByPlayer(ItemStack item, Player player) {
return true;
}
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return false;
}
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack itemStack, @Nullable Level world, List<Component> text, TooltipFlag flag) {
int photoCount = 0;
if (itemStack.getTag() != null && itemStack.getTag().contains("ImageList")) {
ListTag listTag = itemStack.getTag().get("ImageList");
if (listTag instanceof ListTag) {
ListTag imageList = listTag;
photoCount = imageList.size();
}
}
int maxPhotos = itemStack.getMaxDamage();
text.add(new TextComponent(String.valueOf(photoCount) + "/" + String.valueOf(maxPhotos) + " photos stored in memory card"));
text.add(new TextComponent(""));
text.add(new TextComponent("* Does not break when durability hits 0"));
text.add(new TextComponent("* Take to a printer to print your photos"));
}
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
ItemStack itemStack = player.getItemInHand(hand);
if (itemStack.getDamageValue() < itemStack.getMaxDamage()) {
if (world.isClientSide) {
if (usingCamera) {
pendingSnapshot = true;
}
usingCamera = !usingCamera;
} else {
Boolean result = usingCameraServer.get(player);
if (result == null) {
result = false;
}
usingCameraServer.put(player, Boolean.valueOf(!result.booleanValue()));
}
}
return InteractionResultHolder.consume(itemStack);
}
}