From fbbf086f71d4e0e81b3d91f4082e7b5b80b77172 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 16:51:20 +0300 Subject: [PATCH] feat(jui): add anvil screen --- .../Common/res/1_2_2/gui/anvil.png | Bin 0 -> 1900 bytes Minecraft.Assets/Common/res/lang/en_US.lang | 3 + Minecraft.Client/Player/LocalPlayer.cpp | 4 +- Minecraft.Client/Textures/Textures.cpp | 3 +- Minecraft.Client/Textures/Textures.h | 3 +- Minecraft.Client/UI/Screens/RepairScreen.cpp | 191 ++++++++++++++++++ Minecraft.Client/UI/Screens/RepairScreen.h | 39 ++++ 7 files changed, 239 insertions(+), 4 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/anvil.png create mode 100644 Minecraft.Client/UI/Screens/RepairScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/RepairScreen.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/anvil.png b/Minecraft.Assets/Common/res/1_2_2/gui/anvil.png new file mode 100644 index 0000000000000000000000000000000000000000..34e8f9f9f018814ce05dbe56d186f49e866f77df GIT binary patch literal 1900 zcma)52~d+q6y84u5~83~v4{vtG1vhGkI~3sLW{zWHJ}Ixh=~_sQ4%O4ks}G9)wYV7 z7->NTMT=r25mAvVKgEiO<2!B?_wC!ayWe}?d*1|7 zea#6r1OR|J?B}x$00dXuo`^R31$VHcde80GTVJ6mwYK>>!sRmOu)`dz>6 zy?skj&oSs}xV_#AH|@dfVwbmVG~>BechP$5&EZf5lgaG7A#UE3zcp4~CKzO;yb@`Z z@?AWoj32LN@#`EtJUk9ec(s>c+_Y`}p(|)fD{sD;vMAbF_2Ov+kh-^CKEFO?bW-3j zFwtH9FkZXOBG-%Y>#sBror>*sHg?^8qwO87`GPnX+98n3<^5{4dr;VBY?PC6cr^rZ zmuDg{Uvk*;cVXYtTt}Tw2lH~)F^I5QA<-P_>7ZUJd0_u~z&JMXmS`Mip=d&Y*u1Jt zKk&0Z{iTvo?@zz(%x!b#sG9SAVV*~#+7YhOHjWLiGxN#eOCPVxVi&> zNJq%)E}=(UTpL!9rALvw8nx$9t&$c7sAWT~MY}4K5`LB>y23-9)ftX;8n%|oQ&!Sa zI{RODL^*MI4=tl>lw-5FAyk8GxO|3)T-9DyCn>g~=o2Jt8BOuFHPj$Gy>MM-q}gQu zrF_L$&g{`k%`W?g0(|L7OFQ}8CSDyahn?6NEb*Y5h!Ouhwv5xVI*lKKVa`9GJ;bT} zD0-m=BNj9ipBHJg?e`~X5ujIqoDoURIcjU3y9Pv>J!4Z5C(~*|=d-fP%b^u%7EfEe zr9T4Cacuz4kvvhI$a7S1-nPR$Ns2+Vmy@cGP19Hm+`GYOBVM}oIueL6J5&PWFB-Np zJk)+h;x{y;*B{ND%k059gFF}wX0l-_p4S@9N{2G6K+`oVq$1hCf5uKk1olF}B?`f= zk;@#rP_`HYvc(vZ#*0ih0c+w+#KL4YLIBY%1jLJ6LIPX5l6#mCbYo1#X&l5hPSq6_ z%mI|Y1p4xjQ5dPFiwCUrY|d??X7up*g2{`*rCpvv3{~2)2vf@_3aOk)$MzgdQ=F6SPBTQBXC1H zFt&+T18DkeH_HZ{g4GiIQdvtt9l|0?9OS081Sb$>L8UwKSgsXR%G9&THC^In+$}S5 z%_^dCZAC~$wgVg-9L$p5+oi4A9Dxb@Avv!%p z4eRv%D%FBo(i^*4VnGanqQ|)GA=yST7>%UI>&Hl=g$XkO9xMi205BgAFr9PIljRA$ zY%mR!*+qUtdc1qJ6?9K!Q2k*9_H4*aI(EQ!C z3%gz1GZ&?K&Ul}XcUY$dh>52F?)>6U&c>}}+pa+EPu(5tmRd${apq2#>^QcFaq8~x zq$Aj&S^wnp{Wq`xi!4ED4}X$LdE7Q0S4t{S8=V%zY2Dvx= zV8zU)KzVGd|Gx|8&mf22=G&&uMh-l?avVZ)azl{C@?dEo^xw3;SAqX#>qCi4`9OmI c=RK}q!v1>Q*D;u|wqk%bcq7%P=relyA2O*3s{jB1 literal 0 HcmV?d00001 diff --git a/Minecraft.Assets/Common/res/lang/en_US.lang b/Minecraft.Assets/Common/res/lang/en_US.lang index 752a60f39..cc56540f8 100644 --- a/Minecraft.Assets/Common/res/lang/en_US.lang +++ b/Minecraft.Assets/Common/res/lang/en_US.lang @@ -595,6 +595,9 @@ container.crafting=Crafting container.dispenser=Dispenser container.furnace=Furnace container.enchant=Enchant +container.repair=Repair & Name +container.repair.cost=Enchantment Cost: %d +container.repair.expensive=Too Expensive! container.creative=Item Selection container.brewing=Brewing Stand container.chest=Chest diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index 1e029e8ca..d04c5f1f5 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "LocalPlayer.h" #include "UI/Screens/HorseInventoryScreen.h" +#include "UI/Screens/RepairScreen.h" #include "User.h" #include "../Input/Input.h" #include "../GameState/StatsCounter.h" @@ -644,8 +645,7 @@ bool LocalPlayer::startEnchanting(int x, int y, int z, bool LocalPlayer::startRepairing(int x, int y, int z) { #ifdef ENABLE_JAVA_GUIS - // minecraft.setScreen(new RepairScreen(inventory, level, x, y, z)); - // FUCK YOU 4J FIRST AND FOREMOST + minecraft->setScreen(new RepairScreen(inventory, level, x, y, z)); bool success = true; #else bool success = diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index f1e08232c..39e8cb4c7 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -163,7 +163,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"item/trapped", L"item/trapped_double", - // 4jcraft: java UI specific +// 4jcraft: java UI specific #ifdef ENABLE_JAVA_GUIS L"%blur%/misc/vignette", L"/achievement/bg", @@ -178,6 +178,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/creative_inventory/tab_item_search", L"title/mclogo", L"gui/horse", + L"gui/anvil", L"title/bg/panorama", #endif // L"item/christmas", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index ddf2ecf47..48a392444 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -145,7 +145,7 @@ typedef enum _TEXTURE_NAME { TN_TILE_TRAP_CHEST, TN_TILE_LARGE_TRAP_CHEST, - // 4jcraft: java UI specific +// 4jcraft: java UI specific #ifdef ENABLE_JAVA_GUIS TN__BLUR__MISC_VIGNETTE, TN_ACHIEVEMENT_BG, @@ -160,6 +160,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_CREATIVE_TAB_ITEM_SEARCH, TN_TITLE_MCLOGO, TN_GUI_HORSE, + TN_GUI_ANVIL, TN_TITLE_BG_PANORAMA, #endif // TN_TILE_XMAS_CHEST, diff --git a/Minecraft.Client/UI/Screens/RepairScreen.cpp b/Minecraft.Client/UI/Screens/RepairScreen.cpp new file mode 100644 index 000000000..6fc1e8697 --- /dev/null +++ b/Minecraft.Client/UI/Screens/RepairScreen.cpp @@ -0,0 +1,191 @@ +#include "../../Platform/stdafx.h" +#include "RepairScreen.h" +#include +#include +#include +#include "../EditBox.h" +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/AnvilMenu.h" +#include "../../../Minecraft.World/Containers/Slot.h" +#include "../../../Minecraft.Client/Network/ClientConnection.h" +#include "../../../Minecraft.Client/Minecraft.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// IUIScene_AnvilMenu (from iggy UI) +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_ANVIL_LOCATION = ResourceLocation(TN_GUI_ANVIL); +#endif + +RepairScreen::RepairScreen(std::shared_ptr inventory, Level* level, + int x, int y, int z) + : AbstractContainerScreen( + new AnvilMenu(inventory, level, x, y, z, + Minecraft::GetInstance()->localplayers[0])) { + this->inventory = inventory; + this->level = level; + this->repairMenu = static_cast(menu); + this->passEvents = false; +} + +RepairScreen::~RepairScreen() = default; + +void RepairScreen::init() { + AbstractContainerScreen::init(); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + editName = new EditBox(this, font, xo + 62, yo + 24, 103, 12, L""); + editName->setMaxLength(40); + editName->setEnableBackgroundDrawing(false); + editName->inFocus = true; + + repairMenu->removeSlotListener(this); + repairMenu->addSlotListener(this); +} + +void RepairScreen::removed() { + AbstractContainerScreen::removed(); + repairMenu->removeSlotListener(this); +} + +void RepairScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); + glDisable(GL_LIGHTING); + if (editName) { + editName->render(); + } +} + +void RepairScreen::renderLabels() { + std::wstring title = + Language::getInstance()->getElement(L"container.repair"); + font->draw(title, 60, 6, 0x404040); + + if (repairMenu->cost > 0) { + int textColor = 0x80ff20; + bool showCost = true; + std::wstring costString; + + if (repairMenu->cost >= 40 && + !Minecraft::GetInstance()->localplayers[0]->abilities.instabuild) { + costString = Language::getInstance()->getElement( + L"container.repair.expensive"); + textColor = 0xff6060; + } else if (!repairMenu->getSlot(AnvilMenu::RESULT_SLOT)->hasItem()) { + showCost = false; + } else if (!repairMenu->getSlot(AnvilMenu::RESULT_SLOT) + ->mayPickup( + Minecraft::GetInstance()->localplayers[0])) { + textColor = 0xff6060; + } + + if (showCost) { + if (costString.empty()) { + costString = Language::getInstance()->getElement( + L"container.repair.cost", repairMenu->cost); + } + + int shadowColor = -0x00ffffff | ((textColor & 0xfcfcfc) >> 2) | + (textColor & -0x00ffffff); + int costX = imageWidth - 8 - font->width(costString); + int costY = 67; + + // if (this.fontRenderer.getUnicodeFlag()) + // { + // drawRect(i1 - 3, b0 - 2, this.xSize - 7, b0 + 10, -16777216); + // drawRect(i1 - 2, b0 - 1, this.xSize - 8, b0 + 9, -12895429); + // } + // else + // { + font->draw(costString, costX, costY + 1, shadowColor); + font->draw(costString, costX + 1, costY, shadowColor); + font->draw(costString, costX + 1, costY + 1, shadowColor); + font->draw(costString, costX, costY, textColor); + // } + } + } +} + +void RepairScreen::renderBg(float a) { +#ifdef ENABLE_JAVA_GUIS + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + Minecraft::GetInstance()->textures->bindTexture(&GUI_ANVIL_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + int texV = imageHeight + (repairMenu->getSlot(0)->hasItem() ? 0 : 16); + blit(xo + 59, yo + 20, 0, texV, 110, 16); + + if ((repairMenu->getSlot(AnvilMenu::INPUT_SLOT)->hasItem() || + repairMenu->getSlot(AnvilMenu::ADDITIONAL_SLOT)->hasItem()) && + !repairMenu->getSlot(AnvilMenu::RESULT_SLOT)->hasItem()) { + blit(xo + 99, yo + 45, imageWidth, 0, 28, 21); + } +#endif +} + +void RepairScreen::keyPressed(char ch, int eventKey) { + if (editName) { + editName->keyPressed(ch, eventKey); + updateItemName(); + } else { + AbstractContainerScreen::keyPressed(ch, eventKey); + } +} + +void RepairScreen::mouseClicked(int mouseX, int mouseY, int buttonNum) { + AbstractContainerScreen::mouseClicked(mouseX, mouseY, buttonNum); + if (editName) { + editName->mouseClicked(mouseX, mouseY, buttonNum); + } +} + +void RepairScreen::updateItemName() { + std::wstring itemName; + Slot* slot = repairMenu->getSlot(0); + if (slot != NULL && slot->hasItem()) { + if (!slot->getItem()->hasCustomHoverName() && + itemName == slot->getItem()->getHoverName()) { + itemName = L""; + } + } + + repairMenu->setItemName(itemName); + + ByteArrayOutputStream baos; + DataOutputStream dos(&baos); + dos.writeUTF(itemName); + Minecraft::GetInstance()->player->connection->send( + std::shared_ptr(new CustomPayloadPacket( + CustomPayloadPacket::SET_ITEM_NAME_PACKET, baos.toByteArray()))); +} + +// 4jcraft: these 3 are to implement Containerlistener (see IUIScene_AnvilMenu +// and net.minecraft.world.inventory.ContainerListener) +void RepairScreen::refreshContainer( + AbstractContainerMenu* container, + std::vector >* items) { + slotChanged(container, AnvilMenu::INPUT_SLOT, + container->getSlot(0)->getItem()); +} + +void RepairScreen::slotChanged(AbstractContainerMenu* container, int slotIndex, + std::shared_ptr item) { + if (slotIndex == AnvilMenu::INPUT_SLOT) { + std::wstring itemName = item == NULL ? L"" : item->getHoverName(); + editName->setValue(itemName); + if (item != NULL) { + editName->focus(true); + updateItemName(); + } else { + editName->focus(false); + } + } +} + +void RepairScreen::setContainerData(AbstractContainerMenu* container, int id, + int value) {} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/RepairScreen.h b/Minecraft.Client/UI/Screens/RepairScreen.h new file mode 100644 index 000000000..b5352a939 --- /dev/null +++ b/Minecraft.Client/UI/Screens/RepairScreen.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../../Platform/stdafx.h" +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Containers/AnvilMenu.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.inventory.ContainerListener.h" + +class EditBox; + +class RepairScreen : public AbstractContainerScreen, public ContainerListener { +public: + RepairScreen(std::shared_ptr inventory, Level* level, int x, + int y, int z); + virtual ~RepairScreen(); + + void init(); + void removed(); + void render(int xm, int ym, float a); + void renderLabels(); + void renderBg(float a); + void keyPressed(char ch, int eventKey); + void mouseClicked(int mouseX, int mouseY, int buttonNum); + + // 4jcraft: these 3 are to implement Containerlistener (see + // IUIScene_AnvilMenu and net.minecraft.world.inventory.ContainerListener) + void refreshContainer(AbstractContainerMenu* container, + std::vector >* items); + void slotChanged(AbstractContainerMenu* container, int slotIndex, + std::shared_ptr item); + void setContainerData(AbstractContainerMenu* container, int id, int value); + +private: + void updateItemName(); + + std::shared_ptr inventory; + Level* level; + AnvilMenu* repairMenu; + EditBox* editName; +}; \ No newline at end of file