feat(jui): add anvil screen

This commit is contained in:
Sally Knight 2026-03-26 16:51:20 +03:00 committed by Tropical
parent 9a2062c70a
commit fbbf086f71
7 changed files with 239 additions and 4 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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

View file

@ -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 =

View file

@ -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",

View file

@ -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,

View file

@ -0,0 +1,191 @@
#include "../../Platform/stdafx.h"
#include "RepairScreen.h"
#include <GL/gl.h>
#include <memory>
#include <string>
#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> 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<AnvilMenu*>(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<CustomPayloadPacket>(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<std::shared_ptr<ItemInstance> >* items) {
slotChanged(container, AnvilMenu::INPUT_SLOT,
container->getSlot(0)->getItem());
}
void RepairScreen::slotChanged(AbstractContainerMenu* container, int slotIndex,
std::shared_ptr<ItemInstance> 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) {}

View file

@ -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> 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<std::shared_ptr<ItemInstance> >* items);
void slotChanged(AbstractContainerMenu* container, int slotIndex,
std::shared_ptr<ItemInstance> item);
void setContainerData(AbstractContainerMenu* container, int id, int value);
private:
void updateItemName();
std::shared_ptr<Inventory> inventory;
Level* level;
AnvilMenu* repairMenu;
EditBox* editName;
};