mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-06 11:43:38 +00:00
feat(jui): add merchant screen
This commit is contained in:
parent
32149b7ec3
commit
97c6704d82
BIN
Minecraft.Assets/Common/res/1_2_2/gui/villager.png
Normal file
BIN
Minecraft.Assets/Common/res/1_2_2/gui/villager.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
|
|
@ -46,6 +46,7 @@
|
|||
#include "../ClientConstants.h"
|
||||
#include "../../Minecraft.World/Util/SoundTypes.h"
|
||||
#include "../Textures/Packs/TexturePackRepository.h"
|
||||
#include "UI/Screens/MerchantScreen.h"
|
||||
#ifdef _XBOX
|
||||
#include "../Platform/Common/XUI/XUI_Scene_Trading.h"
|
||||
#else
|
||||
|
|
@ -3707,6 +3708,17 @@ void ClientConnection::handleCustomPayload(
|
|||
ByteArrayInputStream bais(customPayloadPacket->data);
|
||||
DataInputStream input(&bais);
|
||||
int containerId = input.readInt();
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
// 4jcraft: use the java gui getMerchant() to get trader as we don't
|
||||
// have iggy's screen anymore
|
||||
if (minecraft->screen &&
|
||||
dynamic_cast<MerchantScreen*>(minecraft->screen) &&
|
||||
containerId == minecraft->localplayers[m_userIndex]
|
||||
->containerMenu->containerId) {
|
||||
std::shared_ptr<Merchant> trader = nullptr;
|
||||
MerchantScreen* screen = (MerchantScreen*)minecraft->screen;
|
||||
trader = screen->getMerchant();
|
||||
#else
|
||||
if (ui.IsSceneInStack(m_userIndex, eUIScene_TradingMenu) &&
|
||||
containerId == minecraft->localplayers[m_userIndex]
|
||||
->containerMenu->containerId) {
|
||||
|
|
@ -3729,7 +3741,7 @@ void ClientConnection::handleCustomPayload(
|
|||
UIScene_TradingMenu* screen = (UIScene_TradingMenu*)scene;
|
||||
trader = screen->getMerchant();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
MerchantRecipeList* recipeList =
|
||||
MerchantRecipeList::createFromStream(&input);
|
||||
trader->overrideOffers(recipeList);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "UI/Screens/EnchantmentScreen.h"
|
||||
#include "UI/Screens/HopperScreen.h"
|
||||
#include "UI/Screens/HorseInventoryScreen.h"
|
||||
#include "UI/Screens/MerchantScreen.h"
|
||||
#include "UI/Screens/RepairScreen.h"
|
||||
#include "User.h"
|
||||
#include "../Input/Input.h"
|
||||
|
|
@ -714,10 +715,14 @@ bool LocalPlayer::openTrap(std::shared_ptr<DispenserTileEntity> trap) {
|
|||
|
||||
bool LocalPlayer::openTrading(std::shared_ptr<Merchant> traderTarget,
|
||||
const std::wstring& name) {
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
minecraft->setScreen(new MerchantScreen(inventory, traderTarget, level));
|
||||
bool success = true;
|
||||
#else
|
||||
bool success =
|
||||
app.LoadTradingMenu(GetXboxPad(), inventory, traderTarget, level, name);
|
||||
if (success) ui.PlayUISFX(eSFX_Press);
|
||||
// minecraft.setScreen(new MerchantScreen(inventory, traderTarget, level));
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = {
|
|||
L"gui/trap",
|
||||
L"gui/hopper",
|
||||
L"gui/enchant",
|
||||
L"gui/villager",
|
||||
L"gui/brewing_stand",
|
||||
L"title/bg/panorama",
|
||||
L"title/bg/panorama0",
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ typedef enum _TEXTURE_NAME {
|
|||
TN_GUI_TRAP,
|
||||
TN_GUI_HOPPER,
|
||||
TN_GUI_ENCHANT,
|
||||
TN_GUI_VILLAGER,
|
||||
TN_GUI_BREWING_STAND,
|
||||
TN_TITLE_BG_PANORAMA,
|
||||
TN_TITLE_BG_PANORAMA0,
|
||||
|
|
|
|||
205
Minecraft.Client/UI/Screens/MerchantScreen.cpp
Normal file
205
Minecraft.Client/UI/Screens/MerchantScreen.cpp
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
#include "../../Platform/stdafx.h"
|
||||
#include "MerchantScreen.h"
|
||||
#include <GL/gl.h>
|
||||
#include <memory>
|
||||
#include "../TradeSwitchButton.h"
|
||||
#include "../../Player/MultiPlayerLocalPlayer.h"
|
||||
#include "../../Rendering/Lighting.h"
|
||||
#include "../../Textures/Textures.h"
|
||||
#include "../../Rendering/EntityRenderers/ItemRenderer.h"
|
||||
#include "../../../Minecraft.World/Headers/net.minecraft.locale.h"
|
||||
#include "../../../Minecraft.World/Containers/MerchantMenu.h"
|
||||
#include "../../../Minecraft.World/Containers/Slot.h"
|
||||
#include "../../../Minecraft.World/Containers/MerchantContainer.h"
|
||||
#include "../../../Minecraft.World/Headers/net.minecraft.world.item.trading.h"
|
||||
#include "../../../Minecraft.Client/Minecraft.h"
|
||||
#include "../../../Minecraft.Client/Network/ClientConnection.h"
|
||||
#include "../../../Minecraft.World/IO/Streams/ByteArrayOutputStream.h"
|
||||
#include "../../../Minecraft.World/IO/Streams/DataOutputStream.h"
|
||||
#include "../../../Minecraft.World/Util/Rarity.h"
|
||||
|
||||
// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing
|
||||
// container classes (and iggy too)
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
ResourceLocation GUI_VILLAGER_LOCATION = ResourceLocation(TN_GUI_VILLAGER);
|
||||
#endif
|
||||
|
||||
MerchantScreen::MerchantScreen(std::shared_ptr<Inventory> inventory,
|
||||
std::shared_ptr<Merchant> merchant, Level* level)
|
||||
: AbstractContainerScreen(new MerchantMenu(inventory, merchant, level)) {
|
||||
this->inventory = inventory;
|
||||
this->merchantMenu = static_cast<MerchantMenu*>(menu);
|
||||
this->merchant = merchant;
|
||||
this->currentRecipeIndex = 0;
|
||||
this->nextRecipeButton = nullptr;
|
||||
this->prevRecipeButton = nullptr;
|
||||
}
|
||||
|
||||
MerchantScreen::~MerchantScreen() = default;
|
||||
|
||||
void MerchantScreen::init() {
|
||||
AbstractContainerScreen::init();
|
||||
|
||||
int xo = (width - imageWidth) / 2;
|
||||
int yo = (height - imageHeight) / 2;
|
||||
|
||||
nextRecipeButton = new TradeSwitchButton(1, xo + 120 + 27, yo + 24 - 1, true);
|
||||
prevRecipeButton = new TradeSwitchButton(2, xo + 36 - 19, yo + 24 - 1, false);
|
||||
|
||||
nextRecipeButton->active = false;
|
||||
prevRecipeButton->active = false;
|
||||
|
||||
buttons.push_back(nextRecipeButton);
|
||||
buttons.push_back(prevRecipeButton);
|
||||
}
|
||||
|
||||
void MerchantScreen::removed() { AbstractContainerScreen::removed(); }
|
||||
|
||||
void MerchantScreen::renderLabels() {
|
||||
font->draw(merchant->getDisplayName(),
|
||||
(imageWidth / 2) - (font->width(merchant->getDisplayName()) / 2),
|
||||
6, 0x404040);
|
||||
|
||||
font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040);
|
||||
}
|
||||
|
||||
void MerchantScreen::renderBg(float a) {
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
minecraft->textures->bindTexture(&GUI_VILLAGER_LOCATION);
|
||||
int xo = (width - imageWidth) / 2;
|
||||
int yo = (height - imageHeight) / 2;
|
||||
blit(xo, yo, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
MerchantRecipe* activeRecipe =
|
||||
merchantMenu->getTradeContainer()->getActiveRecipe();
|
||||
if (activeRecipe != nullptr && !activeRecipe->isDeprecated()) {
|
||||
blit(xo + 83, yo + 21, 212, 0, 28, 21);
|
||||
blit(xo + 83, yo + 51, 212, 0, 28, 21);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MerchantScreen::render(int xm, int ym, float a) {
|
||||
AbstractContainerScreen::render(xm, ym, a);
|
||||
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(
|
||||
inventory->player->shared_from_this());
|
||||
MerchantRecipeList* offers = merchant->getOffers(player);
|
||||
|
||||
if (offers != nullptr && !offers->empty()) {
|
||||
int xo = (width - imageWidth) / 2;
|
||||
int yo = (height - imageHeight) / 2;
|
||||
|
||||
MerchantRecipe* recipe = offers->at(currentRecipeIndex);
|
||||
if (recipe != nullptr && !recipe->isDeprecated()) {
|
||||
std::shared_ptr<ItemInstance> buyItem1 = recipe->getBuyAItem();
|
||||
std::shared_ptr<ItemInstance> buyItem2 = recipe->getBuyBItem();
|
||||
std::shared_ptr<ItemInstance> sellItem = recipe->getSellItem();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef((float)xo, (float)yo, 0.0f);
|
||||
|
||||
Lighting::turnOnGui();
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
if (buyItem1 != nullptr) {
|
||||
itemRenderer->renderGuiItem(font, minecraft->textures, buyItem1,
|
||||
36, 24);
|
||||
itemRenderer->renderGuiItemDecorations(
|
||||
font, minecraft->textures, buyItem1, 36, 24);
|
||||
}
|
||||
|
||||
if (buyItem2 != nullptr) {
|
||||
itemRenderer->renderGuiItem(font, minecraft->textures, buyItem2,
|
||||
62, 24);
|
||||
itemRenderer->renderGuiItemDecorations(
|
||||
font, minecraft->textures, buyItem2, 62, 24);
|
||||
}
|
||||
|
||||
if (sellItem != nullptr) {
|
||||
itemRenderer->renderGuiItem(font, minecraft->textures, sellItem,
|
||||
120, 24);
|
||||
itemRenderer->renderGuiItemDecorations(
|
||||
font, minecraft->textures, sellItem, 120, 24);
|
||||
}
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_RESCALE_NORMAL);
|
||||
Lighting::turnOff();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if (buyItem1 != nullptr && isHoveringOver(36, 24, 16, 16, xm, ym)) {
|
||||
renderTooltip(buyItem1, xm, ym);
|
||||
} else if (buyItem2 != nullptr &&
|
||||
isHoveringOver(62, 24, 16, 16, xm, ym)) {
|
||||
renderTooltip(buyItem2, xm, ym);
|
||||
} else if (sellItem != nullptr &&
|
||||
isHoveringOver(120, 24, 16, 16, xm, ym)) {
|
||||
renderTooltip(sellItem, xm, ym);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MerchantScreen::tick() {
|
||||
AbstractContainerScreen::tick();
|
||||
|
||||
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(
|
||||
inventory->player->shared_from_this());
|
||||
|
||||
MerchantRecipeList* offers = merchant->getOffers(player);
|
||||
|
||||
if (offers != nullptr) {
|
||||
int offerCount = (int)offers->size();
|
||||
|
||||
nextRecipeButton->active = (currentRecipeIndex < offerCount - 1);
|
||||
prevRecipeButton->active = (currentRecipeIndex > 0);
|
||||
|
||||
if (currentRecipeIndex >= offerCount && offerCount > 0) {
|
||||
currentRecipeIndex = offerCount - 1;
|
||||
merchantMenu->setSelectionHint(currentRecipeIndex);
|
||||
|
||||
// 4jcraft: taken from IUIScene_TradingMenu
|
||||
ByteArrayOutputStream rawOutput;
|
||||
DataOutputStream output(&rawOutput);
|
||||
output.writeInt(currentRecipeIndex);
|
||||
minecraft->player->connection->send(
|
||||
std::shared_ptr<CustomPayloadPacket>(new CustomPayloadPacket(
|
||||
CustomPayloadPacket::TRADER_SELECTION_PACKET,
|
||||
rawOutput.toByteArray())));
|
||||
}
|
||||
} else {
|
||||
nextRecipeButton->active = false;
|
||||
prevRecipeButton->active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MerchantScreen::buttonClicked(Button* button) {
|
||||
bool changed = false;
|
||||
|
||||
if (button == nextRecipeButton) {
|
||||
++currentRecipeIndex;
|
||||
changed = true;
|
||||
} else if (button == prevRecipeButton) {
|
||||
--currentRecipeIndex;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
merchantMenu->setSelectionHint(currentRecipeIndex);
|
||||
|
||||
// 4jcraft: taken from IUIScene_TradingMenu
|
||||
ByteArrayOutputStream rawOutput;
|
||||
DataOutputStream output(&rawOutput);
|
||||
output.writeInt(currentRecipeIndex);
|
||||
minecraft->player->connection->send(
|
||||
std::shared_ptr<CustomPayloadPacket>(new CustomPayloadPacket(
|
||||
CustomPayloadPacket::TRADER_SELECTION_PACKET,
|
||||
rawOutput.toByteArray())));
|
||||
}
|
||||
}
|
||||
32
Minecraft.Client/UI/Screens/MerchantScreen.h
Normal file
32
Minecraft.Client/UI/Screens/MerchantScreen.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "AbstractContainerScreen.h"
|
||||
#include "../../../Minecraft.World/Containers/MerchantMenu.h"
|
||||
#include "../../../Minecraft.World/Headers/net.minecraft.world.item.trading.h"
|
||||
|
||||
class TradeSwitchButton;
|
||||
|
||||
class MerchantScreen : public AbstractContainerScreen {
|
||||
public:
|
||||
MerchantScreen(std::shared_ptr<Inventory> inventory,
|
||||
std::shared_ptr<Merchant> merchant, Level* level);
|
||||
virtual ~MerchantScreen();
|
||||
|
||||
void init() override;
|
||||
void removed() override;
|
||||
void renderLabels() override;
|
||||
void renderBg(float a) override;
|
||||
void render(int xm, int ym, float a) override;
|
||||
void tick() override;
|
||||
void buttonClicked(Button* button) override;
|
||||
|
||||
std::shared_ptr<Merchant> getMerchant() { return merchant; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<Inventory> inventory;
|
||||
std::shared_ptr<Merchant> merchant;
|
||||
MerchantMenu* merchantMenu;
|
||||
TradeSwitchButton* nextRecipeButton;
|
||||
TradeSwitchButton* prevRecipeButton;
|
||||
int currentRecipeIndex;
|
||||
};
|
||||
46
Minecraft.Client/UI/TradeSwitchButton.cpp
Normal file
46
Minecraft.Client/UI/TradeSwitchButton.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include "../../Platform/stdafx.h"
|
||||
#include "TradeSwitchButton.h"
|
||||
#include "../Textures/Textures.h"
|
||||
#include "../Rendering/Tesselator.h"
|
||||
#include "../../../Minecraft.Client/Minecraft.h"
|
||||
#include "../../../Minecraft.World/Headers/net.minecraft.locale.h"
|
||||
#include "../../../Minecraft.World/Containers/MerchantMenu.h"
|
||||
|
||||
// 4jcraft: referenced from MCP 8.11 (JE 1.6.4)
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
// ResourceLocation GUI_VILLAGER_LOCATION = ResourceLocation(TN_GUI_VILLAGER);
|
||||
extern ResourceLocation GUI_VILLAGER_LOCATION;
|
||||
#endif
|
||||
|
||||
TradeSwitchButton::TradeSwitchButton(int id, int x, int y, bool mirrored)
|
||||
: Button(id, x, y, 12, 19, L"") {
|
||||
this->mirrored = mirrored;
|
||||
}
|
||||
|
||||
int TradeSwitchButton::getYImage(bool hovered) { return 0; }
|
||||
|
||||
void TradeSwitchButton::renderBg(Minecraft* minecraft, int xm, int ym) {
|
||||
#ifdef ENABLE_JAVA_GUIS
|
||||
if (!visible) return;
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
minecraft->textures->bindTexture(&GUI_VILLAGER_LOCATION);
|
||||
|
||||
bool hovered = (xm >= x && ym >= y && xm < x + w && ym < y + h);
|
||||
|
||||
int textureX = 176;
|
||||
int textureY = 0;
|
||||
|
||||
if (!active) {
|
||||
textureX += w * 2;
|
||||
} else if (hovered) {
|
||||
textureX += w;
|
||||
}
|
||||
|
||||
if (!mirrored) {
|
||||
textureY += h;
|
||||
}
|
||||
|
||||
blit(x, y, textureX, textureY, w, h);
|
||||
#endif
|
||||
}
|
||||
14
Minecraft.Client/UI/TradeSwitchButton.h
Normal file
14
Minecraft.Client/UI/TradeSwitchButton.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "Button.h"
|
||||
|
||||
class TradeSwitchButton : public Button {
|
||||
private:
|
||||
bool mirrored;
|
||||
|
||||
public:
|
||||
TradeSwitchButton(int id, int x, int y, bool mirrored);
|
||||
|
||||
protected:
|
||||
int getYImage(bool hovered) override;
|
||||
void renderBg(Minecraft* minecraft, int xm, int ym) override;
|
||||
};
|
||||
Loading…
Reference in a new issue