diff --git a/src/main/java/net/mcreator/superbwarfare/client/ClientRenderHandler.java b/src/main/java/net/mcreator/superbwarfare/client/ClientRenderHandler.java new file mode 100644 index 000000000..8377d3171 --- /dev/null +++ b/src/main/java/net/mcreator/superbwarfare/client/ClientRenderHandler.java @@ -0,0 +1,18 @@ +package net.mcreator.superbwarfare.client; + +import net.mcreator.superbwarfare.client.tooltip.ClientImageTooltip; +import net.mcreator.superbwarfare.client.tooltip.ImageTooltip; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.RegisterClientTooltipComponentFactoriesEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +public class ClientRenderHandler { + + @SubscribeEvent + public static void registerTooltip(RegisterClientTooltipComponentFactoriesEvent event) { + event.register(ImageTooltip.class, ClientImageTooltip::new); + } + +} diff --git a/src/main/java/net/mcreator/superbwarfare/client/tooltip/ClientImageTooltip.java b/src/main/java/net/mcreator/superbwarfare/client/tooltip/ClientImageTooltip.java new file mode 100644 index 000000000..fc0228296 --- /dev/null +++ b/src/main/java/net/mcreator/superbwarfare/client/tooltip/ClientImageTooltip.java @@ -0,0 +1,194 @@ +package net.mcreator.superbwarfare.client.tooltip; + +import net.mcreator.superbwarfare.init.ModKeyMappings; +import net.mcreator.superbwarfare.init.ModPerks; +import net.mcreator.superbwarfare.init.ModTags; +import net.mcreator.superbwarfare.perk.AmmoPerk; +import net.mcreator.superbwarfare.perk.Perk; +import net.mcreator.superbwarfare.perk.PerkHelper; +import net.mcreator.superbwarfare.tools.ItemNBTTool; +import net.mcreator.superbwarfare.tools.TooltipTool; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.network.chat.Component; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.text.DecimalFormat; + +public class ClientImageTooltip implements ClientTooltipComponent { + + private final int width; + private final int height; + private final ItemStack stack; + + public ClientImageTooltip(ImageTooltip tooltip) { + this.width = tooltip.width(); + this.height = tooltip.height(); + this.stack = tooltip.stack(); + } + + @Override + public void renderImage(@NotNull Font font, int x, int y, GuiGraphics guiGraphics) { + guiGraphics.pose().pushPose(); + + int yo = 0; + if (renderWeaponDamageTooltip(font, guiGraphics, x, y + yo)) yo += 10; + if (renderWeaponLevelTooltip(font, guiGraphics, x, y + yo)) yo += 10; + if (renderWeaponBypassTooltip(font, guiGraphics, x, y + yo)) yo += 10; + if (renderWeaponEditTooltip(font, guiGraphics, x, y + yo)) yo += 20; + + if (!Screen.hasShiftDown()) { + renderPerksShortcut(guiGraphics, x, y + yo); + yo += 20; + } + + guiGraphics.pose().popPose(); + } + + // TODO 等nbt重置后,修改nbt位置 + private boolean renderWeaponDamageTooltip(Font font, GuiGraphics guiGraphics, int x, int y) { + double damage = ItemNBTTool.getDouble(stack, "damage", 0) * TooltipTool.perkDamage(stack); + var damageComponent = Component.translatable("des.superbwarfare.tips.damage").withStyle(ChatFormatting.GRAY) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(new DecimalFormat("##.#").format(damage) + (TooltipTool.heBullet(stack) ? " + " + + new DecimalFormat("##.#").format(0.8 * damage * (1 + 0.1 * TooltipTool.heBulletLevel(stack))) : "")).withStyle(ChatFormatting.GREEN)); + + guiGraphics.drawString(font, damageComponent, x, y, 0xFFFFFF); + + if (stack.is(ModTags.Items.IS_AUTO_WEAPON)) { + var rpmComponent = Component.translatable("des.superbwarfare.tips.rpm").withStyle(ChatFormatting.GRAY) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(new DecimalFormat("##").format(ItemNBTTool.getDouble(stack, "rpm", 0) + ItemNBTTool.getDouble(stack, "customRpm", 0))).withStyle(ChatFormatting.GREEN)); + + int xo = font.width(damageComponent.getVisualOrderText()); + guiGraphics.drawString(font, rpmComponent, x + xo + 16, y, 0xFFFFFF); + } + + return true; + } + + private boolean renderWeaponLevelTooltip(Font font, GuiGraphics guiGraphics, int x, int y) { + int level = ItemNBTTool.getInt(stack, "Level", 0); + double rate = ItemNBTTool.getDouble(stack, "Exp", 0) / (20 * Math.pow(level, 2) + 160 * level + 20); + + ChatFormatting formatting; + if (level < 10) { + formatting = ChatFormatting.WHITE; + } else if (level < 20) { + formatting = ChatFormatting.AQUA; + } else if (level < 30) { + formatting = ChatFormatting.LIGHT_PURPLE; + } else if (level < 40) { + formatting = ChatFormatting.GOLD; + } else { + formatting = ChatFormatting.RED; + } + + var levelComponent = Component.translatable("des.superbwarfare.tips.level").withStyle(ChatFormatting.GRAY) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(level + "").withStyle(formatting).withStyle(ChatFormatting.BOLD)) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(" (" + new DecimalFormat("#0.00").format(rate * 100) + "%)").withStyle(ChatFormatting.GRAY)); + + guiGraphics.drawString(font, levelComponent, x, y, 0xFFFFFF); + + int upgradePoint = Mth.floor(ItemNBTTool.getDouble(stack, "UpgradePoint", 0)); + var upgradeComponent = Component.translatable("des.superbwarfare.tips.upgrade_point").withStyle(ChatFormatting.GRAY) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(String.valueOf(upgradePoint)).withStyle(ChatFormatting.GRAY).withStyle(ChatFormatting.BOLD)); + + int xo = font.width(levelComponent.getVisualOrderText()); + guiGraphics.drawString(font, upgradeComponent, x + xo + 16, y, 0xFFFFFF); + + return true; + } + + private boolean renderWeaponBypassTooltip(Font font, GuiGraphics guiGraphics, int x, int y) { + double perkBypassArmorRate = 0; + var perk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); + + if (perk instanceof AmmoPerk ammoPerk) { + int level = PerkHelper.getItemPerkLevel(perk, stack); + perkBypassArmorRate = ammoPerk.bypassArmorRate + (perk == ModPerks.AP_BULLET.get() ? 0.05f * (level - 1) : 0); + } + double bypassRate = Math.max(ItemNBTTool.getDouble(stack, "BypassesArmor", 0) + perkBypassArmorRate, 0); + var bypassComponent = Component.translatable("des.superbwarfare.tips.bypass").withStyle(ChatFormatting.GRAY) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(new DecimalFormat("##.##").format(bypassRate * 100) + "%").withStyle(ChatFormatting.GOLD)); + + if (bypassRate > 0) { + guiGraphics.drawString(font, bypassComponent, x, y, 0xFFFFFF); + } + + double headshot = ItemNBTTool.getDouble(stack, "headshot", 0); + var headshotComponent = Component.translatable("des.superbwarfare.tips.headshot").withStyle(ChatFormatting.GRAY) + .append(Component.literal("").withStyle(ChatFormatting.RESET)) + .append(Component.literal(new DecimalFormat("##.#").format(headshot) + "x").withStyle(ChatFormatting.AQUA)); + + int xo = bypassRate > 0 ? font.width(bypassComponent.getVisualOrderText()) : 0; + if (headshot > 0) { + guiGraphics.drawString(font, headshotComponent, x + xo + 16, y, 0xFFFFFF); + } + + return bypassRate > 0 || headshot > 0; + } + + private boolean renderWeaponEditTooltip(Font font, GuiGraphics guiGraphics, int x, int y) { + if (stack.is(ModTags.Items.CAN_CUSTOM_GUN)) { + var editComponent = Component.translatable("des.superbwarfare.tips.edit", + "[" + ModKeyMappings.EDIT_MODE.getKey().getDisplayName().getString() + "]").withStyle(ChatFormatting.LIGHT_PURPLE); + guiGraphics.drawString(font, editComponent, x, y + 10, 0xFFFFFF); + + return true; + } + return false; + } + + private void renderPerksShortcut(GuiGraphics guiGraphics, int x, int y) { + guiGraphics.pose().pushPose(); + + int xOffset = -20; + + Perk ammoPerk = PerkHelper.getPerkByType(stack, Perk.Type.AMMO); + if (ammoPerk != null && PerkHelper.getPerkItem(ammoPerk).isPresent()) { + xOffset += 20; + + var ammoItem = PerkHelper.getPerkItem(ammoPerk).get().get(); + guiGraphics.renderItem(ammoItem.getDefaultInstance(), x + xOffset, y + 2); + } + + Perk funcPerk = PerkHelper.getPerkByType(stack, Perk.Type.FUNCTIONAL); + if (funcPerk != null && PerkHelper.getPerkItem(funcPerk).isPresent()) { + xOffset += 20; + + var funcItem = PerkHelper.getPerkItem(funcPerk).get().get(); + guiGraphics.renderItem(funcItem.getDefaultInstance(), x + xOffset, y + 2); + } + + Perk damagePerk = PerkHelper.getPerkByType(stack, Perk.Type.DAMAGE); + if (damagePerk != null && PerkHelper.getPerkItem(damagePerk).isPresent()) { + xOffset += 20; + + var damageItem = PerkHelper.getPerkItem(damagePerk).get().get(); + guiGraphics.renderItem(damageItem.getDefaultInstance(), x + xOffset, y + 2); + } + + guiGraphics.pose().popPose(); + } + + @Override + public int getHeight() { + return height; + } + + @Override + public int getWidth(@NotNull Font font) { + return width; + } + +} diff --git a/src/main/java/net/mcreator/superbwarfare/client/tooltip/ImageTooltip.java b/src/main/java/net/mcreator/superbwarfare/client/tooltip/ImageTooltip.java new file mode 100644 index 000000000..e0b053ebc --- /dev/null +++ b/src/main/java/net/mcreator/superbwarfare/client/tooltip/ImageTooltip.java @@ -0,0 +1,7 @@ +package net.mcreator.superbwarfare.client.tooltip; + +import net.minecraft.world.inventory.tooltip.TooltipComponent; +import net.minecraft.world.item.ItemStack; + +public record ImageTooltip(int width, int height, ItemStack stack) implements TooltipComponent { +} \ No newline at end of file diff --git a/src/main/java/net/mcreator/superbwarfare/item/gun/rifle/AK12Item.java b/src/main/java/net/mcreator/superbwarfare/item/gun/rifle/AK12Item.java index b537d1d03..e6e13e15a 100644 --- a/src/main/java/net/mcreator/superbwarfare/item/gun/rifle/AK12Item.java +++ b/src/main/java/net/mcreator/superbwarfare/item/gun/rifle/AK12Item.java @@ -3,6 +3,7 @@ package net.mcreator.superbwarfare.item.gun.rifle; import net.mcreator.superbwarfare.ModUtils; import net.mcreator.superbwarfare.client.PoseTool; import net.mcreator.superbwarfare.client.renderer.item.AK12ItemRenderer; +import net.mcreator.superbwarfare.client.tooltip.ImageTooltip; import net.mcreator.superbwarfare.event.ClientEventHandler; import net.mcreator.superbwarfare.init.ModItems; import net.mcreator.superbwarfare.init.ModSounds; @@ -17,17 +18,21 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; +import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.Level; import net.minecraftforge.client.extensions.common.IClientItemExtensions; +import org.jetbrains.annotations.NotNull; import software.bernie.geckolib.animatable.GeoItem; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animation.AnimatableManager; @@ -37,6 +42,8 @@ import software.bernie.geckolib.core.animation.RawAnimation; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -205,4 +212,14 @@ public class AK12Item extends GunItem implements GeoItem, AnimatedItem { public boolean canApplyPerk(Perk perk) { return PerkHelper.RIFLE_PERKS.test(perk) || PerkHelper.MAGAZINE_PERKS.test(perk); } + + @Override + public void appendHoverText(ItemStack stack, Level world, List list, TooltipFlag flag) { +// super.appendHoverText(stack, world, list, flag); + } + + @Override + public @NotNull Optional getTooltipImage(@NotNull ItemStack pStack) { + return Optional.of(new ImageTooltip(128, 128, pStack)); + } } \ No newline at end of file diff --git a/src/main/resources/assets/superbwarfare/lang/en_us.json b/src/main/resources/assets/superbwarfare/lang/en_us.json index ec34322b7..87930f632 100644 --- a/src/main/resources/assets/superbwarfare/lang/en_us.json +++ b/src/main/resources/assets/superbwarfare/lang/en_us.json @@ -53,6 +53,7 @@ "des.superbwarfare.tips.distance": "Drone Distance: ", "des.superbwarfare.tips.upgrade_point": "Upgrade Point: ", "des.superbwarfare.tips.rpm": "Rpm: ", + "des.superbwarfare.tips.headshot": "Headshot: ", "item.superbwarfare.ammo_box": "Ammo Box", "des.superbwarfare.tips.rifle_ammo": "Storage Rifle Ammo: ", diff --git a/src/main/resources/assets/superbwarfare/lang/zh_cn.json b/src/main/resources/assets/superbwarfare/lang/zh_cn.json index 648e8778a..962ee5bd2 100644 --- a/src/main/resources/assets/superbwarfare/lang/zh_cn.json +++ b/src/main/resources/assets/superbwarfare/lang/zh_cn.json @@ -53,6 +53,7 @@ "des.superbwarfare.tips.bypass": "护甲穿透: ", "des.superbwarfare.tips.distance": "无人机距离你: ", "des.superbwarfare.tips.rpm": "射速: ", + "des.superbwarfare.tips.headshot": "爆头倍率:", "item.superbwarfare.ammo_box": "弹药盒", "des.superbwarfare.tips.rifle_ammo": "已存储的步枪弹药: ",