the whole game

This commit is contained in:
Kolyah35
2026-03-02 22:04:18 +03:00
parent 816e9060b4
commit f0617a5d22
2069 changed files with 581500 additions and 0 deletions

View File

@@ -0,0 +1,370 @@
#include "ArmorScreen.h"
#include "../Screen.h"
#include "../components/NinePatch.h"
#include "../../Minecraft.h"
#include "../../player/LocalPlayer.h"
#include "../../renderer/Tesselator.h"
#include "../../renderer/entity/ItemRenderer.h"
#include "../../../world/item/Item.h"
#include "../../../world/item/ItemCategory.h"
#include "../../../world/entity/player/Inventory.h"
#include "../../../world/entity/item/ItemEntity.h"
#include "../../../world/level/Level.h"
#include "../../../network/RakNetInstance.h"
#include "../../renderer/entity/EntityRenderDispatcher.h"
#include "../../../world/item/ArmorItem.h"
static void setIfNotSet(bool& ref, bool condition) {
ref = (ref || condition);
}
const int descFrameWidth = 100;
const int rgbActive = 0xfff0f0f0;
const int rgbInactive = 0xc0635558;
const int rgbInactiveShadow = 0xc0aaaaaa;
#ifdef __APPLE__
static const float BorderPixels = 4;
#ifdef DEMO_MODE
static const float BlockPixels = 22;
#else
static const float BlockPixels = 22;
#endif
#else
static const float BorderPixels = 4;
static const float BlockPixels = 24;
#endif
static const int ItemSize = (int)(BlockPixels + 2*BorderPixels);
static const int Bx = 10; // Border Frame width
static const int By = 6; // Border Frame height
ArmorScreen::ArmorScreen():
inventoryPane(NULL),
btnArmor0(0),
btnArmor1(1),
btnArmor2(2),
btnArmor3(3),
btnClose(4, ""),
bHeader (5, "Armor"),
guiBackground(NULL),
guiSlot(NULL),
guiPaneFrame(NULL),
guiPlayerBg(NULL),
doRecreatePane(false),
descWidth(90)
//guiSlotItem(NULL),
//guiSlotItemSelected(NULL)
{
//LOGI("Creating ArmorScreen with %p, %d\n", furnace, furnace->runningId);
}
ArmorScreen::~ArmorScreen() {
delete inventoryPane;
delete guiBackground;
delete guiSlot;
delete guiPaneFrame;
delete guiPlayerBg;
}
void ArmorScreen::init() {
super::init();
player = minecraft->player;
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
btnClose.setImageDef(def, true);
btnClose.scaleWhenPressed = false;
buttons.push_back(&bHeader);
buttons.push_back(&btnClose);
armorButtons[0] = &btnArmor0;
armorButtons[1] = &btnArmor1;
armorButtons[2] = &btnArmor2;
armorButtons[3] = &btnArmor3;
for (int i = 0; i < NUM_ARMORBUTTONS; ++i)
buttons.push_back(armorButtons[i]);
// GUI - nine patches
NinePatchFactory builder(minecraft->textures, "gui/spritesheet.png");
guiBackground = builder.createSymmetrical(IntRectangle(0, 0, 16, 16), 4, 4);
guiSlot = builder.createSymmetrical(IntRectangle(0, 32, 8, 8), 3, 3, 20, 20);
guiPaneFrame = builder.createSymmetrical(IntRectangle(28, 42, 4, 4), 1, 1)->setExcluded(1 << 4);
guiPlayerBg = builder.createSymmetrical(IntRectangle(0, 20, 8, 8), 3, 3);
updateItems();
}
void ArmorScreen::setupPositions() {
// Left - Categories
bHeader.x = bHeader.y = 0;
bHeader.width = width;// - bDone.w;
btnClose.width = btnClose.height = 19;
btnClose.x = width - btnClose.width;
btnClose.y = 0;
// Inventory pane
const int maxWidth = (int)(width/1.8f) - Bx - Bx;
const int InventoryColumns = maxWidth / ItemSize;
const int realWidth = InventoryColumns * ItemSize;
const int paneWidth = realWidth + Bx + Bx;
const int realBx = (paneWidth - realWidth) / 2;
inventoryPaneRect = IntRectangle(realBx,
#ifdef __APPLE__
26 + By - ((width==240)?1:0), realWidth, ((width==240)?1:0) + height-By-By-28);
#else
26 + By, realWidth, height-By-By-28);
#endif
for (int i = 0; i < NUM_ARMORBUTTONS; ++i) {
Button& b = *armorButtons[i];
b.x = paneWidth;
b.y = inventoryPaneRect.y + 24 * i;
b.width = 20;
b.height = 20;
}
guiPlayerBgRect.y = inventoryPaneRect.y;
int xx = armorButtons[0]->x + armorButtons[0]->width;
int xw = width - xx;
guiPlayerBgRect.x = xx + xw / 10;
guiPlayerBgRect.w = xw - (xw / 10) * 2;
guiPlayerBgRect.h = inventoryPaneRect.h;
guiPaneFrame->setSize((float)inventoryPaneRect.w + 2, (float)inventoryPaneRect.h + 2);
guiPlayerBg->setSize((float)guiPlayerBgRect.w, (float)guiPlayerBgRect.h);
guiBackground->setSize((float)width, (float)height);
updateItems();
setupInventoryPane();
}
void ArmorScreen::tick() {
if (inventoryPane)
inventoryPane->tick();
if (doRecreatePane) {
updateItems();
setupInventoryPane();
doRecreatePane = false;
}
}
void ArmorScreen::handleRenderPane(Touch::InventoryPane* pane, Tesselator& t, int xm, int ym, float a) {
if (pane) {
pane->render(xm, ym, a);
guiPaneFrame->draw(t, (float)(pane->rect.x - 1), (float)(pane->rect.y - 1));
}
}
void ArmorScreen::render(int xm, int ym, float a) {
//renderBackground();
Tesselator& t = Tesselator::instance;
t.addOffset(0, 0, -500);
guiBackground->draw(t, 0, 0);
t.addOffset(0, 0, 500);
glEnable2(GL_ALPHA_TEST);
// Buttons (Left side + crafting)
super::render(xm, ym, a);
handleRenderPane(inventoryPane, t, xm, ym, a);
t.colorABGR(0xffffffff);
glColor4f2(1, 1, 1, 1);
t.addOffset(0, 0, -490);
guiPlayerBg->draw(t, (float)guiPlayerBgRect.x, (float)guiPlayerBgRect.y);
t.addOffset(0, 0, 490);
renderPlayer((float)(guiPlayerBgRect.x + guiPlayerBgRect.w / 2), 0.85f * height);
for (int i = 0; i < NUM_ARMORBUTTONS; ++i) {
drawSlotItemAt(t, i, player->getArmor(i), armorButtons[i]->x, armorButtons[i]->y);
}
glDisable2(GL_ALPHA_TEST);
}
void ArmorScreen::buttonClicked(Button* button) {
if (button == &btnClose) {
minecraft->setScreen(NULL);
}
if (button->id >= 0 && button->id <= 3) {
takeAndClearSlot(button->id);
}
}
bool ArmorScreen::addItem(const Touch::InventoryPane* forPane, int itemIndex) {
const ItemInstance* instance = armorItems[itemIndex];
if (!ItemInstance::isArmorItem(instance))
return false;
ArmorItem* item = (ArmorItem*) instance->getItem();
ItemInstance* old = player->getArmor(item->slot);
ItemInstance oldArmor;
if (ItemInstance::isArmorItem(old)) {
oldArmor = *old;
}
player->setArmor(item->slot, instance);
player->inventory->removeItem(instance);
//@attn: this is hugely important
armorItems[itemIndex] = NULL;
if (!oldArmor.isNull()) {
if (!player->inventory->add(&oldArmor)) {
player->drop(new ItemInstance(oldArmor), false);
}
}
doRecreatePane = true;
return true;
}
bool ArmorScreen::isAllowed( int slot ) {
return true;
}
bool ArmorScreen::renderGameBehind() {
return false;
}
std::vector<const ItemInstance*> ArmorScreen::getItems( const Touch::InventoryPane* forPane ) {
return armorItems;
}
void ArmorScreen::updateItems() {
armorItems.clear();
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
ItemInstance* item = minecraft->player->inventory->getItem(i);
if (ItemInstance::isArmorItem(item))
armorItems.push_back(item);
}
}
bool ArmorScreen::canMoveToSlot(int slot, const ItemInstance* item) {
return ItemInstance::isArmorItem(item)
&& ((ArmorItem*)item)->slot == slot;
}
void ArmorScreen::setupInventoryPane() {
// IntRectangle(0, 0, 100, 100)
if (inventoryPane) delete inventoryPane;
inventoryPane = new Touch::InventoryPane(this, minecraft, inventoryPaneRect, inventoryPaneRect.w, BorderPixels, armorItems.size(), ItemSize, (int)BorderPixels);
inventoryPane->fillMarginX = 0;
inventoryPane->fillMarginY = 0;
//LOGI("Creating new pane: %d %p\n", inventoryItems.size(), inventoryPane);
}
void ArmorScreen::drawSlotItemAt( Tesselator& t, int slot, const ItemInstance* item, int x, int y)
{
float xx = (float)x;
float yy = (float)y;
guiSlot->draw(t, xx, yy);
if (item && !item->isNull()) {
ItemRenderer::renderGuiItem(minecraft->font, minecraft->textures, item, xx + 2, yy, true);
glDisable2(GL_TEXTURE_2D);
ItemRenderer::renderGuiItemDecorations(item, xx + 2, yy + 3);
glEnable2(GL_TEXTURE_2D);
//minecraft->gui.renderSlotText(item, xx + 3, yy + 3, true, true);
} else {
minecraft->textures->loadAndBindTexture("gui/items.png");
blit(x + 2, y, 15 * 16, slot * 16, 16, 16, 16, 16);
}
}
void ArmorScreen::takeAndClearSlot( int slot ) {
ItemInstance* item = player->getArmor(slot);
if (!item)
return;
int oldSize = minecraft->player->inventory->getNumEmptySlots();
if (!minecraft->player->inventory->add(item))
minecraft->player->drop(new ItemInstance(*item), false);
player->setArmor(slot, NULL);
int newSize = minecraft->player->inventory->getNumEmptySlots();
setIfNotSet(doRecreatePane, newSize != oldSize);
}
void ArmorScreen::renderPlayer(float xo, float yo) {
// Push GL and player state
glPushMatrix();
glTranslatef(xo, yo, -200);
float ss = 45;
glScalef(-ss, ss, ss);
glRotatef(180, 0, 0, 1);
//glDisable(GL_DEPTH_TEST);
Player* player = (Player*) minecraft->player;
float oybr = player->yBodyRot;
float oyr = player->yRot;
float oxr = player->xRot;
float t = getTimeS();
float xd = 10 * Mth::sin(t);//(xo + 51) - xm;
float yd = 10 * Mth::cos(t * 0.05f);//(yo + 75 - 50) - ym;
glRotatef(45 + 90, 0, 1, 0);
glRotatef(-45 - 90, 0, 1, 0);
const float xtan = Mth::atan(xd / 40.0f) * +20;
const float ytan = Mth::atan(yd / 40.0f) * -20;
glRotatef(ytan, 1, 0, 0);
player->yBodyRot = xtan;
player->yRot = xtan + xtan;
player->xRot = ytan;
glTranslatef(0, player->heightOffset, 0);
// Push walking anim
float oldWAP = player->walkAnimPos;
float oldWAS = player->walkAnimSpeed;
float oldWASO = player->walkAnimSpeedO;
// Set new walking anim
player->walkAnimSpeedO = player->walkAnimSpeed = 0.25f;
player->walkAnimPos = getTimeS() * player->walkAnimSpeed * SharedConstants::TicksPerSecond;
EntityRenderDispatcher* rd = EntityRenderDispatcher::getInstance();
rd->playerRotY = 180;
rd->render(player, 0, 0, 0, 0, 1);
// Pop walking anim
player->walkAnimPos = oldWAP;
player->walkAnimSpeed = oldWAS;
player->walkAnimSpeedO = oldWASO;
//glEnable(GL_DEPTH_TEST);
// Pop GL and player state
player->yBodyRot = oybr;
player->yRot = oyr;
player->xRot = oxr;
glPopMatrix();
}

View File

@@ -0,0 +1,79 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ArmorScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ArmorScreen_H__
#include "BaseContainerScreen.h"
#include "../components/InventoryPane.h"
#include "../components/Button.h"
class Font;
class CItem;
class Textures;
class NinePatchLayer;
class Tesselator;
class ArmorScreen: public Screen,
public Touch::IInventoryPaneCallback
{
typedef Screen super;
typedef std::vector<CItem*> ItemList;
static const int NUM_ARMORBUTTONS = 4;
public:
ArmorScreen();
~ArmorScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
bool renderGameBehind();
void buttonClicked(Button* button);
// IInventoryPaneCallback
bool addItem(const Touch::InventoryPane* pane, int itemId);
bool isAllowed( int slot );
std::vector<const ItemInstance*> getItems( const Touch::InventoryPane* forPane );
private:
void renderPlayer(float xo, float yo);
void setupInventoryPane();
void updateItems();
void drawSlotItemAt(Tesselator& t, int slot, const ItemInstance* item, int x, int y);
ItemInstance moveOver(const ItemInstance* item, int maxCount);
void takeAndClearSlot( int slot );
void handleRenderPane(Touch::InventoryPane* pane, Tesselator& t, int xm, int ym, float a);
bool canMoveToSlot(int slot, const ItemInstance* item);
ItemList _items;
std::string currentItemDesc;
ItemInstance burnResult;
float descWidth;
ImageButton btnClose;
BlankButton btnArmor0;
BlankButton btnArmor1;
BlankButton btnArmor2;
BlankButton btnArmor3;
BlankButton* armorButtons[4];
Touch::THeader bHeader;
Touch::InventoryPane* inventoryPane;
IntRectangle inventoryPaneRect;
IntRectangle guiPlayerBgRect;
std::vector<const ItemInstance*> armorItems;
bool doRecreatePane;
// GUI elements such as 9-Patches
NinePatchLayer* guiBackground;
NinePatchLayer* guiSlot;
NinePatchLayer* guiPaneFrame;
NinePatchLayer* guiPlayerBg;
Player* player;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ArmorScreen_H__*/

View File

@@ -0,0 +1,50 @@
#ifndef NET_MINECRAFT_CLIENT_GUI__BaseContainerScreen_H__
#define NET_MINECRAFT_CLIENT_GUI__BaseContainerScreen_H__
//package net.minecraft.client.gui.screens;
#include <vector>
#include "../Screen.h"
#include "../../Minecraft.h"
#include "../../player/LocalPlayer.h"
class BaseContainerMenu;
class BaseContainerScreen: public Screen
{
typedef Screen super;
public:
BaseContainerScreen(BaseContainerMenu* menu)
: menu(menu)
{
}
virtual void init() {
super::init();
minecraft->player->containerMenu = menu;
}
virtual void tick() {
super::tick();
if (!minecraft->player->isAlive() || minecraft->player->removed)
minecraft->player->closeContainer();
}
virtual void keyPressed( int eventKey )
{
if (eventKey == Keyboard::KEY_ESCAPE) {
minecraft->player->closeContainer();
} else {
super::keyPressed(eventKey);
}
}
virtual bool closeOnPlayerHurt() {
return true;
}
protected:
BaseContainerMenu* menu;
};
#endif /*NET_MINECRAFT_CLIENT_GUI__BaseContainerScreen_H__*/

View File

@@ -0,0 +1,26 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__BuyGameScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__BuyGameScreen_H__
#include "../Screen.h"
#include "../components/Button.h"
class BuyGameScreen: public Screen
{
public:
BuyGameScreen() {}
virtual ~BuyGameScreen() {}
void init();
void render(int xm, int ym, float a);
void buttonClicked(Button* button) {
//if (button->id == bQuit.id)
}
private:
//Button bQuit;
//Button bBuyGame;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__BuyGameScreen_H__*/

View File

@@ -0,0 +1,24 @@
#include "ChatScreen.h"
#include "DialogDefinitions.h"
#include "../Gui.h"
#include "../../Minecraft.h"
#include "../../../AppPlatform.h"
#include "../../../platform/log.h"
void ChatScreen::init() {
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_NEW_CHAT_MESSAGE);
}
void ChatScreen::render(int xm, int ym, float a)
{
int status = minecraft->platform()->getUserInputStatus();
if (status > -1) {
if (status == 1) {
std::vector<std::string> v = minecraft->platform()->getUserInput();
if (v.size() && v[0].length() > 0)
minecraft->gui.addMessage(v[0]);
}
minecraft->setScreen(NULL);
}
}

View File

@@ -0,0 +1,21 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ChatScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ChatScreen_H__
#include "../Screen.h"
class ChatScreen: public Screen
{
public:
ChatScreen() {}
virtual ~ChatScreen() {}
void init();
void render(int xm, int ym, float a);
void buttonClicked(Button* button) {};
private:
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ChatScreen_H__*/

View File

@@ -0,0 +1,474 @@
#include "ChestScreen.h"
#include "touch/TouchStartMenuScreen.h"
#include "../Screen.h"
#include "../components/NinePatch.h"
#include "../../Minecraft.h"
#include "../../player/LocalPlayer.h"
#include "../../renderer/Tesselator.h"
#include "../../renderer/entity/ItemRenderer.h"
#include "../../../world/item/Item.h"
#include "../../../world/item/ItemCategory.h"
#include "../../../world/entity/player/Inventory.h"
#include "../../../world/entity/item/ItemEntity.h"
#include "../../../world/level/Level.h"
#include "../../../locale/I18n.h"
#include "../../../util/StringUtils.h"
#include "../../../network/packet/ContainerSetSlotPacket.h"
#include "../../../network/RakNetInstance.h"
#include "../../../world/level/tile/entity/TileEntity.h"
#include "../../../world/level/tile/entity/ChestTileEntity.h"
#include "../../../world/inventory/ContainerMenu.h"
#include "../../../util/Mth.h"
//static NinePatchLayer* guiPaneFrame = NULL;
static __inline void setIfNotSet(bool& ref, bool condition) {
ref = (ref || condition);
}
template<typename T,typename V>
T* upcast(V* x) { return x; }
static int heldMs = -1;
static int percent = -1;
static const float MaxHoldMs = 500.0f;
static const int MinChargeMs = 200;
class ItemDiffer {
public:
ItemDiffer(int size)
: size(size),
count(0)
{
base = new ItemInstance[size];
}
ItemDiffer(const std::vector<const ItemInstance*>& v)
: size(v.size()),
count(0)
{
base = new ItemInstance[size];
init(v);
}
~ItemDiffer() {
delete[] base;
}
void init(const std::vector<const ItemInstance*>& v) {
for (int i = 0; i < size; ++i) {
if (v[i]) base[i] = *v[i];
else base[i].setNull();
}
}
int getDiff(const std::vector<const ItemInstance*>& v, std::vector<int>& outIndices) {
int diffLen = v.size() - size;
int minLen = Mth::Max((int)v.size(), size);
for (int i = 0; i < minLen; ++i) {
//LOGI("%s, %s\n", base[i].toString().c_str(), v[i]?v[i]->toString().c_str() : "null");
if (!ItemInstance::matchesNulls(&base[i], v[i]))
outIndices.push_back(i);
}
return diffLen;
}
private:
int size;
int count;
ItemInstance* base;
};
const int descFrameWidth = 100;
const int rgbActive = 0xfff0f0f0;
const int rgbInactive = 0xc0635558;
const int rgbInactiveShadow = 0xc0aaaaaa;
#ifdef __APPLE__
static const float BorderPixels = 3;
#ifdef DEMO_MODE
static const float BlockPixels = 22;
#else
static const float BlockPixels = 22;
#endif
#else
static const float BorderPixels = 4;
static const float BlockPixels = 24;
#endif
static const int ItemSize = (int)(BlockPixels + 2*BorderPixels);
static const int Bx = 10; // Border Frame width
static const int By = 6; // Border Frame height
typedef struct FlyingItem {
ItemInstance item;
float startTime;
float sx, sy;
float dx, dy;
} FlyingItem ;
static std::vector<FlyingItem> flyingItems;
ChestScreen::ChestScreen(Player* player, ChestTileEntity* chest)
: super(new ContainerMenu(chest, chest->runningId)), //@huge @attn
inventoryPane(NULL),
chestPane(NULL),
btnClose(4, ""),
bHeader (5, "Inventory"),
bHeaderChest (6, "Chest"),
guiBackground(NULL),
guiSlot(NULL),
guiSlotMarked(NULL),
guiSlotMarker(NULL),
player(player),
chest(chest),
selectedSlot(-1),
doRecreatePane(false)
//guiSlotItem(NULL),
//guiSlotItemSelected(NULL)
{
}
ChestScreen::~ChestScreen() {
delete inventoryPane;
delete chestPane;
delete guiBackground;
delete guiSlot;
delete guiSlotMarked;
delete guiSlotMarker;
delete guiPaneFrame;
delete menu;
if (chest->clientSideOnly)
delete chest;
}
void ChestScreen::init() {
super::init();
//printf("-> %d\n", width/2);
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
btnClose.setImageDef(def, true);
btnClose.scaleWhenPressed = false;
buttons.push_back(&bHeader);
buttons.push_back(&bHeaderChest);
buttons.push_back(&btnClose);
// GUI - nine patches
NinePatchFactory builder(minecraft->textures, "gui/spritesheet.png");
guiBackground = builder.createSymmetrical(IntRectangle(0, 0, 16, 16), 4, 4);
guiSlot = builder.createSymmetrical(IntRectangle(0, 32, 8, 8), 3, 3);
guiSlotMarked = builder.createSymmetrical(IntRectangle(0, 44, 8, 8), 3, 3);
guiSlotMarker = builder.createSymmetrical(IntRectangle(10, 42, 16, 16), 5, 5);
guiPaneFrame = builder.createSymmetrical(IntRectangle(28, 42, 4, 4), 1, 1)->exclude(4);
}
void ChestScreen::setupPositions() {
// Left - Categories
bHeader.x = 0;
bHeader.y = bHeaderChest.y = 0;
bHeader.width = bHeaderChest.width = width / 2;// - bDone.w;
bHeaderChest.x = bHeader.x + bHeader.width;
// Right - Description
btnClose.width = btnClose.height = 19;
btnClose.x = width - btnClose.width;
btnClose.y = 0;
//guiPaneFrame->setSize((float)paneFuelRect.w + 2, (float)paneFuelRect.h + 4);
guiBackground->setSize((float)width, (float)height);
//guiSlotItem->setSize((float)width, 22); //@todo
//guiSlotItemSelected->setSize((float)width, 22);
setupPane();
}
void ChestScreen::tick() {
if (inventoryPane)
inventoryPane->tick();
if (chestPane)
chestPane->tick();
if (doRecreatePane) {
setupPane();
doRecreatePane = false;
}
}
void ChestScreen::handleRenderPane(Touch::InventoryPane* pane, Tesselator& t, int xm, int ym, float a) {
if (pane) {
int ms, id;
pane->markerIndex = -1;
if (pane->queryHoldTime(&id, &ms)) {
heldMs = ms;
FillingContainer* c = (pane == inventoryPane)?
upcast<FillingContainer>(minecraft->player->inventory)
: upcast<FillingContainer>(chest);
const int slotIndex = id + c->getNumLinkedSlots();
ItemInstance* item = c->getItem(slotIndex);
int count = (item && !item->isNull())? item->count : 0;
float maxHoldMs = item? 700 + 10 * item->count: MaxHoldMs;
if (count > 1) {
float share = (heldMs-MinChargeMs) / maxHoldMs;
pane->markerType = 1;//(heldMs >= MinChargeMs)? 1 : 0;
pane->markerIndex = id;
pane->markerShare = Mth::Max(share, 0.0f);
percent = (int)Mth::clamp(100.0f * share, 0.0f, 100.0f);
if (percent >= 100) {
addItem(pane, id);
}
}
}
pane->render(xm, ym, a);
guiPaneFrame->draw(t, (float)(pane->rect.x - 1), (float)(pane->rect.y - 1));
//LOGI("query-iv: %d, %d\n", gridId, heldMs);
}
}
void ChestScreen::render(int xm, int ym, float a) {
const int N = 5;
static StopwatchNLast r(N);
//renderBackground();
Tesselator& t = Tesselator::instance;
guiBackground->draw(t, 0, 0);
glEnable2(GL_ALPHA_TEST);
// Buttons (Left side + crafting)
super::render(xm, ym, a);
heldMs = -1;
handleRenderPane(inventoryPane, t, xm, ym, a);
handleRenderPane(chestPane, t, xm, ym, a);
float now = getTimeS();
float MaxTime = 0.3f;
std::vector<FlyingItem> flyingToSave;
glEnable2(GL_BLEND);
glColor4f(1, 1, 1, 0.2f);
t.beginOverride();
//t.color(1.0f, 0.0f, 0.0f, 0.2f);
//t.noColor();
glEnable2(GL_SCISSOR_TEST);
//LOGI("panesBox: %d, %d - %d, %d\n", panesBbox.x, panesBbox.y, panesBbox.w, panesBbox.h);
minecraft->gui.setScissorRect(panesBbox);
for (unsigned int i = 0; i < flyingItems.size(); ++i) {
FlyingItem& fi = flyingItems[i];
float since = (now - fi.startTime);
if (since > MaxTime) continue;
float t = since / MaxTime;
t *= t;
//float xx = fi.sx + t * 100.0f;
float xx = Mth::lerp(fi.sx, fi.dx, t);
float yy = Mth::lerp(fi.sy, fi.dy, t);
ItemRenderer::renderGuiItem(minecraft->font, minecraft->textures, &fi.item, xx + 7, yy + 8, true);
//minecraft->gui.renderSlotText(&fi.item, xx + 3, yy + 3, true, true);
flyingToSave.push_back(fi);
}
t.enableColor();
t.endOverrideAndDraw();
glDisable2(GL_SCISSOR_TEST);
flyingItems = flyingToSave;
t.colorABGR(0xffffffff);
glDisable2(GL_BLEND);
minecraft->textures->loadAndBindTexture("gui/spritesheet.png");
}
void ChestScreen::buttonClicked(Button* button) {
if (button == &btnClose) {
minecraft->player->closeContainer();
}
}
bool ChestScreen::handleAddItem(FillingContainer* from, FillingContainer* to, int itemIndex) {
const int itemOffset = from->getNumLinkedSlots();
const int slotIndex = itemIndex + itemOffset;
ItemInstance* item = from->getItem(slotIndex);
bool added = false;
bool fromChest = (from == chest);
Touch::InventoryPane* pane = fromChest? chestPane : inventoryPane;
Touch::InventoryPane* toPane = fromChest? inventoryPane : chestPane;
int wantedCount = (item && !item->isNull())? item->count * percent / 100 : 0;
if ((item && !item->isNull()) && (!wantedCount || heldMs < MinChargeMs)) {
wantedCount = 1;
}
if (wantedCount > 0) {
ItemInstance takenItem(*item);
takenItem.count = wantedCount;
ItemDiffer differ(getItems(toPane));
to->add(&takenItem);
added = (takenItem.count != wantedCount);
if (added) {
item->count -= (wantedCount - takenItem.count);
std::vector<int> changed;
std::vector<const ItemInstance*> items = getItems(toPane);
differ.getDiff(items, changed);
ScrollingPane::GridItem g, gTo;
pane->getGridItemFor_slow(itemIndex, g);
//LOGI("Changed: %d\n", changed.size());
for (unsigned int i = 0; i < changed.size(); ++i) {
FlyingItem fi;
fi.startTime = getTimeS();
fi.item = *item;
fi.sx = g.xf;
fi.sy = g.yf;
int toIndex = changed[i];
toPane->getGridItemFor_slow(toIndex, gTo);
fi.dx = gTo.xf;
fi.dy = gTo.yf;
flyingItems.push_back(fi);
if (!fromChest && minecraft->level->isClientSide) {
int j = toIndex;
ItemInstance item = items[j]? *items[j] : ItemInstance();
ContainerSetSlotPacket p(menu->containerId, j, item);
minecraft->raknetInstance->send(p);
}
}
}
// Send to server, needs a bit special handling
if (fromChest) {
ItemInstance ins(item->count <= 0? ItemInstance() : *item);
ContainerSetSlotPacket p(menu->containerId, slotIndex, ins);
minecraft->raknetInstance->send(p);
}
if (item->count <= 0)
from->clearSlot(slotIndex);
}
// Clear the marker indices
pane->markerIndex = toPane->markerIndex = -1;
return added;
}
bool ChestScreen::addItem(const Touch::InventoryPane* forPane, int itemIndex) {
//LOGI("items.size, index: %d, %d\n", inventoryItems.size(), itemIndex);
bool l2r = (forPane == inventoryPane);
return handleAddItem( l2r? upcast<FillingContainer>(minecraft->player->inventory) : upcast<FillingContainer>(chest),
l2r? upcast<FillingContainer>(chest) : upcast<FillingContainer>(minecraft->player->inventory),
itemIndex);
}
bool ChestScreen::isAllowed( int slot )
{
return true;
}
bool ChestScreen::renderGameBehind()
{
return false;
}
std::vector<const ItemInstance*> ChestScreen::getItems( const Touch::InventoryPane* forPane )
{
if (forPane == inventoryPane) {
for (int i = Inventory::MAX_SELECTION_SIZE, j = 0; i < minecraft->player->inventory->getContainerSize(); ++i, ++j)
inventoryItems[j] = minecraft->player->inventory->getItem(i);
return inventoryItems;
}
else {
for (int i = 0; i < chest->getContainerSize(); ++i)
chestItems[i] = chest->getItem(i);
return chestItems;
}
}
void ChestScreen::setupPane()
{
inventoryItems.clear();
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
ItemInstance* item = minecraft->player->inventory->getItem(i);
/*if (!item || item->isNull()) continue;*/
inventoryItems.push_back(item);
}
chestItems.clear();
for (int i = 0; i < chest->getContainerSize(); ++i) {
ItemInstance* item = chest->getItem(i);
/*if (!item || item->isNull()) continue;*/
chestItems.push_back(item);
}
int maxWidth = width/2 - Bx/2;//- Bx - Bx/*- Bx*/;
int InventoryColumns = maxWidth / ItemSize;
const int realWidth = InventoryColumns * ItemSize;
int paneWidth = realWidth;// + Bx + Bx;
const int realBx = (width/2 - realWidth) / 2;
IntRectangle rect(realBx,
#ifdef __APPLE__
24 + By - ((width==240)?1:0), realWidth, ((width==240)?1:0) + height-By-By-24);
#else
24 + By, realWidth, height-By-By-24);
#endif
// IntRectangle(0, 0, 100, 100)
if (inventoryPane) delete inventoryPane;
inventoryPane = new Touch::InventoryPane(this, minecraft, rect, paneWidth, BorderPixels, minecraft->player->inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE, ItemSize, (int)BorderPixels);
inventoryPane->fillMarginX = 0;
inventoryPane->fillMarginY = 0;
guiPaneFrame->setSize((float)rect.w + 2, (float)rect.h + 2);
panesBbox = rect;
rect.x += width/2;// - rect.w - Bx;
panesBbox.w += (rect.x - panesBbox.x);
if (chestPane) delete chestPane;
chestPane = new Touch::InventoryPane(this, minecraft, rect, paneWidth, BorderPixels, chest->getContainerSize(), ItemSize, (int)BorderPixels);
chestPane->fillMarginX = 0;
chestPane->fillMarginY = 0;
LOGI("Creating new panes\n:"
" Inventory %d %p\n"
" Chest %d %p\n", (int)inventoryItems.size(), inventoryPane, (int)chestItems.size(), chestPane);
}
void ChestScreen::drawSlotItemAt( Tesselator& t, const ItemInstance* item, int x, int y, bool selected)
{
float xx = (float)x;
float yy = (float)y;
(selected? guiSlot/*Marked*/ : guiSlot)->draw(t, xx, yy);
if (selected)
guiSlotMarker->draw(t, xx - 2, yy - 2);
if (item && !item->isNull()) {
ItemRenderer::renderGuiItem(minecraft->font, minecraft->textures, item, xx + 7, yy + 8, true);
minecraft->gui.renderSlotText(item, xx + 3, yy + 3, true, true);
}
}

View File

@@ -0,0 +1,72 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ChestScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ChestScreen_H__
#include "BaseContainerScreen.h"
#include "../components/InventoryPane.h"
#include "../components/Button.h"
class Font;
class CItem;
class Textures;
class NinePatchLayer;
class FillingContainer;
class ChestTileEntity;
class Tesselator;
class ChestScreen: public BaseContainerScreen,
public Touch::IInventoryPaneCallback
{
typedef BaseContainerScreen super;
typedef std::vector<CItem*> ItemList;
friend class ItemPane;
public:
ChestScreen(Player* player, ChestTileEntity* chest);
~ChestScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
bool renderGameBehind();
void buttonClicked(Button* button);
// IInventoryPaneCallback
bool addItem(const Touch::InventoryPane* pane, int itemId);
bool isAllowed( int slot );
std::vector<const ItemInstance*> getItems( const Touch::InventoryPane* forPane );
//const ItemList& getItems(const ItemPane* forPane);
private:
void setupPane();
void drawSlotItemAt(Tesselator& t, const ItemInstance* item, int x, int y, bool selected);
bool handleAddItem(FillingContainer* from, FillingContainer* to, int itemIndex);
void handleRenderPane(Touch::InventoryPane* pane, Tesselator& t, int xm, int ym, float a);
std::string currentItemDesc;
ImageButton btnClose;
Touch::THeader bHeader;
Touch::THeader bHeaderChest;
Touch::InventoryPane* inventoryPane;
Touch::InventoryPane* chestPane;
IntRectangle panesBbox;
std::vector<const ItemInstance*> inventoryItems;
std::vector<const ItemInstance*> chestItems;
bool doRecreatePane;
int selectedSlot;
// GUI elements such as 9-Patches
NinePatchLayer* guiBackground;
NinePatchLayer* guiSlot;
NinePatchLayer* guiSlotMarked;
NinePatchLayer* guiSlotMarker;
NinePatchLayer* guiPaneFrame;
Player* player;
ChestTileEntity* chest;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ChestScreen_H__*/

View File

@@ -0,0 +1,26 @@
#include "ChooseLevelScreen.h"
#include <algorithm>
#include <set>
#include "../../Minecraft.h"
void ChooseLevelScreen::init() {
loadLevelSource();
}
void ChooseLevelScreen::loadLevelSource()
{
LevelStorageSource* levelSource = minecraft->getLevelSource();
levelSource->getLevelList(levels);
std::sort(levels.begin(), levels.end());
}
std::string ChooseLevelScreen::getUniqueLevelName( const std::string& level ) {
std::set<std::string> Set;
for (unsigned int i = 0; i < levels.size(); ++i)
Set.insert(levels[i].id);
std::string s = level;
while ( Set.find(s) != Set.end() )
s += "-";
return s;
}

View File

@@ -0,0 +1,21 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ChooseLevelScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ChooseLevelScreen_H__
#include "../Screen.h"
#include "../../../world/level/storage/LevelStorageSource.h"
class ChooseLevelScreen: public Screen
{
public:
void init();
protected:
std::string getUniqueLevelName(const std::string& level);
private:
void loadLevelSource();
LevelSummaryList levels;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ChooseLevelScreen_H__*/

View File

@@ -0,0 +1,84 @@
#include "ConfirmScreen.h"
#include "../components/Button.h"
#include "../../Minecraft.h"
ConfirmScreen::ConfirmScreen(Screen* parent_, const std::string& title1_, const std::string& title2_, int id_)
: parent(parent_),
title1(title1_),
title2(title2_),
id(id_),
yesButtonText("Ok"),
noButtonText("Cancel"),
yesButton(0),
noButton(0)
{
}
ConfirmScreen::ConfirmScreen(Screen* parent_, const std::string& title1_, const std::string& title2_, const std::string& yesButton_, const std::string& noButton_, int id_ )
: parent(parent_),
title1(title1_),
title2(title2_),
id(id_),
yesButtonText(yesButton_),
noButtonText(noButton_)
{
}
ConfirmScreen::~ConfirmScreen() {
delete yesButton;
delete noButton;
}
void ConfirmScreen::init()
{
if (minecraft->useTouchscreen()) {
yesButton = new Touch::TButton(0, 0, 0, yesButtonText),
noButton = new Touch::TButton(1, 0, 0, noButtonText);
} else {
yesButton = new Button(0, 0, 0, yesButtonText),
noButton = new Button(1, 0, 0, noButtonText);
}
buttons.push_back(yesButton);
buttons.push_back(noButton);
tabButtons.push_back(yesButton);
tabButtons.push_back(noButton);
}
void ConfirmScreen::setupPositions() {
const int ButtonWidth = 120;
const int ButtonHeight = 24;
yesButton->x = width / 2 - ButtonWidth - 4;
yesButton->y = height / 6 + 72;
noButton->x = width / 2 + 4;
noButton->y = height / 6 + 72;
yesButton->width = noButton->width = ButtonWidth;
yesButton->height = noButton->height = ButtonHeight;
}
bool ConfirmScreen::handleBackEvent(bool isDown) {
if (!isDown)
postResult(false);
return true;
}
void ConfirmScreen::render( int xm, int ym, float a )
{
renderBackground();
drawCenteredString(font, title1, width / 2, 50, 0xffffff);
drawCenteredString(font, title2, width / 2, 70, 0xffffff);
super::render(xm, ym, a);
}
void ConfirmScreen::buttonClicked( Button* button )
{
postResult(button->id == 0);
}
void ConfirmScreen::postResult(bool isOk)
{
parent->confirmResult(isOk, id);
}

View File

@@ -0,0 +1,41 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ConfirmScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ConfirmScreen_H__
//package net.minecraft.client.gui;
#include "../Screen.h"
#include "../components/SmallButton.h"
#include <string>
class ConfirmScreen: public Screen
{
typedef Screen super;
public:
ConfirmScreen(Screen* parent_, const std::string& title1_, const std::string& title2_, int id_);
ConfirmScreen(Screen* parent_, const std::string& title1_, const std::string& title2_, const std::string& yesButton, const std::string& noButton, int id_);
~ConfirmScreen();
void init();
void setupPositions();
bool handleBackEvent(bool isDown);
void render(int xm, int ym, float a);
protected:
void buttonClicked(Button* button);
virtual void postResult(bool isOk);
Screen* parent;
int id;
private:
std::string title1;
std::string title2;
std::string yesButtonText;
std::string noButtonText;
Button* yesButton; // 0
Button* noButton; // 1
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ConfirmScreen_H__*/

View File

@@ -0,0 +1,83 @@
#include "DeathScreen.h"
#include "ScreenChooser.h"
#include "../components/Button.h"
#include "../../Minecraft.h"
#include "../../player/LocalPlayer.h"
#include "../../../platform/time.h"
static const int WAIT_TICKS = 30;
DeathScreen::DeathScreen()
: bRespawn(0),
bTitle(0),
_hasChosen(false),
_tick(0)
{
}
DeathScreen::~DeathScreen()
{
delete bRespawn;
delete bTitle;
}
void DeathScreen::init()
{
if (minecraft->useTouchscreen()) {
bRespawn = new Touch::TButton(1, "Respawn!");
bTitle = new Touch::TButton(2, "Main menu");
} else {
bRespawn = new Button(1, "Respawn!");
bTitle = new Button(2, "Main menu");
}
buttons.push_back(bRespawn);
buttons.push_back(bTitle);
tabButtons.push_back(bRespawn);
tabButtons.push_back(bTitle);
}
void DeathScreen::setupPositions()
{
bRespawn->width = bTitle->width = width / 4;
bRespawn->y = bTitle->y = height / 2;
bRespawn->x = width/2 - bRespawn->width - 10;
bTitle->x = width/2 + 10;
LOGI("xyz: %d, %d (%d, %d)\n", bTitle->x, bTitle->y, width, height);
}
void DeathScreen::tick() {
++_tick;
}
void DeathScreen::render( int xm, int ym, float a )
{
fillGradient(0, 0, width, height, 0x60500000, 0xa0803030);
glPushMatrix2();
glScalef2(2, 2, 2);
drawCenteredString(font, "You died!", width / 2 / 2, height / 8, 0xffffff);
glPopMatrix2();
if (_tick >= WAIT_TICKS)
Screen::render(xm, ym, a);
}
void DeathScreen::buttonClicked( Button* button )
{
if (_tick < WAIT_TICKS) return;
if (button == bRespawn) {
//RespawnPacket packet();
//minecraft->raknetInstance->send(packet);
minecraft->player->respawn();
//minecraft->raknetInstance->send();
minecraft->setScreen(NULL);
}
if (button == bTitle)
minecraft->leaveGame();
}

View File

@@ -0,0 +1,30 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__DeathScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__DeathScreen_H__
#include "../Screen.h"
class Button;
class DeathScreen: public Screen
{
public:
DeathScreen();
virtual ~DeathScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
private:
Button* bRespawn;
Button* bTitle;
bool _hasChosen;
int _tick;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__DeathScreen_H__*/

View File

@@ -0,0 +1,13 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__DialogDefinitions_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__DialogDefinitions_H__
class DialogDefinitions {
public:
static const int DIALOG_CREATE_NEW_WORLD = 1;
static const int DIALOG_NEW_CHAT_MESSAGE = 2;
static const int DIALOG_MAINMENU_OPTIONS = 3;
static const int DIALOG_RENAME_MP_WORLD = 4;
static const int DIALOG_DEMO_FEATURE_DISABLED = 98;
};
#endif /*#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__DialogDefinitions_H__*/

View File

@@ -0,0 +1,57 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__DisconnectionScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__DisconnectionScreen_H__
#include "../Screen.h"
#include "../Font.h"
#include "../components/Button.h"
#include "../../Minecraft.h"
#include <string>
class DisconnectionScreen: public Screen
{
typedef Screen super;
public:
DisconnectionScreen(const std::string& msg)
: _msg(msg),
_back(NULL)
{}
~DisconnectionScreen() {
delete _back;
}
void init() {
if (minecraft->useTouchscreen())
_back = new Touch::TButton(1, "Ok");
else
_back = new Button(1, "Ok");
buttons.push_back(_back);
tabButtons.push_back(_back);
_back->width = 128;
_back->x = (width - _back->width) / 2;
_back->y = height / 2;
}
void render( int xm, int ym, float a ) {
renderBackground();
super::render(xm, ym, a);
int center = (width - minecraft->font->width(_msg)) / 2;
minecraft->font->drawShadow(_msg, (float)center, (float)(height / 2 - 32), 0xffffffff);
}
void buttonClicked(Button* button) {
if (button->id == _back->id) {
minecraft->leaveGame();
}
}
bool isInGameScreen() { return false; }
private:
std::string _msg;
Button* _back;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__DisconnectionScreen_H__*/

View File

@@ -0,0 +1,555 @@
#include "FurnaceScreen.h"
#include "crafting/PaneCraftingScreen.h"
#include "../Screen.h"
#include "../components/NinePatch.h"
#include "../../Minecraft.h"
#include "../../player/LocalPlayer.h"
#include "../../renderer/Tesselator.h"
#include "../../renderer/entity/ItemRenderer.h"
#include "../../../world/item/Item.h"
#include "../../../world/item/crafting/Recipes.h"
#include "../../../world/item/ItemCategory.h"
#include "../../../world/entity/player/Inventory.h"
#include "../../../world/entity/item/ItemEntity.h"
#include "../../../world/level/Level.h"
#include "../../../world/item/DyePowderItem.h"
#include "../../../world/item/crafting/FurnaceRecipes.h"
#include "../../../world/level/tile/entity/FurnaceTileEntity.h"
#include "../../../locale/I18n.h"
#include "../../../util/StringUtils.h"
#include "../../../world/inventory/FurnaceMenu.h"
#include "../../../network/packet/ContainerSetSlotPacket.h"
#include "../../../network/RakNetInstance.h"
static int heldMs = -1;
static int percent = -1;
static const float MaxHoldMs = 500.0f;
static const int MinChargeMs = 200;
static void setIfNotSet(bool& ref, bool condition) {
ref = (ref || condition);
}
const int descFrameWidth = 100;
const int rgbActive = 0xfff0f0f0;
const int rgbInactive = 0xc0635558;
const int rgbInactiveShadow = 0xc0aaaaaa;
#ifdef __APPLE__
static const float BorderPixels = 4;
#ifdef DEMO_MODE
static const float BlockPixels = 22;
#else
static const float BlockPixels = 22;
#endif
#else
static const float BorderPixels = 4;
static const float BlockPixels = 24;
#endif
static const int ItemSize = (int)(BlockPixels + 2*BorderPixels);
static const int Bx = 10; // Border Frame width
static const int By = 6; // Border Frame height
FurnaceScreen::FurnaceScreen(Player* player, FurnaceTileEntity* furnace)
: super(new FurnaceMenu(furnace)), //@huge @attn
inventoryPane(NULL),
btnFuel(FurnaceTileEntity::SLOT_FUEL),
btnIngredient(FurnaceTileEntity::SLOT_INGREDIENT),
btnResult(FurnaceTileEntity::SLOT_RESULT),
btnClose(4, ""),
bHeader (5, "Furnace"),
guiBackground(NULL),
guiSlot(NULL),
guiSlotMarked(NULL),
guiSlotMarker(NULL),
guiPaneFrame(NULL),
player(player),
furnace(furnace),
selectedSlot(FurnaceTileEntity::SLOT_INGREDIENT),
doRecreatePane(false),
lastBurnTypeId(0),
descWidth(90)
//guiSlotItem(NULL),
//guiSlotItemSelected(NULL)
{
//LOGI("Creating FurnaceScreen with %p, %d\n", furnace, furnace->runningId);
}
FurnaceScreen::~FurnaceScreen() {
clearItems();
delete inventoryPane;
delete guiBackground;
delete guiSlot;
delete guiSlotMarked;
delete guiSlotMarker;
delete guiPaneFrame;
delete menu;
if (furnace->clientSideOnly)
delete furnace;
}
void FurnaceScreen::init() {
super::init();
//printf("-> %d\n", width/2);
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
btnClose.setImageDef(def, true);
btnClose.scaleWhenPressed = false;
buttons.push_back(&bHeader);
buttons.push_back(&btnIngredient);
buttons.push_back(&btnFuel);
buttons.push_back(&btnResult);
buttons.push_back(&btnClose);
// GUI - nine patches
NinePatchFactory builder(minecraft->textures, "gui/spritesheet.png");
guiBackground = builder.createSymmetrical(IntRectangle(0, 0, 16, 16), 4, 4);
guiSlot = builder.createSymmetrical(IntRectangle(0, 32, 8, 8), 3, 3);
guiSlotMarked = builder.createSymmetrical(IntRectangle(0, 44, 8, 8), 3, 3);
guiSlotMarker = builder.createSymmetrical(IntRectangle(10, 42, 16, 16), 5, 5);
guiPaneFrame = builder.createSymmetrical(IntRectangle(28, 42, 4, 4), 1, 1)->setExcluded(1 << 4);
recheckRecipes();
}
void FurnaceScreen::setupPositions() {
// Left - Categories
bHeader.x = bHeader.y = 0;
bHeader.width = width;// - bDone.w;
btnClose.width = btnClose.height = 19;
btnClose.x = width - btnClose.width;
btnClose.y = 0;
// Inventory pane
const int maxWidth = width/2 - Bx - Bx;
const int InventoryColumns = maxWidth / ItemSize;
const int realWidth = InventoryColumns * ItemSize;
const int paneWidth = realWidth + Bx + Bx;
const int realBx = (paneWidth - realWidth) / 2;
inventoryPaneRect = IntRectangle(realBx,
#ifdef __APPLE__
26 + By - ((width==240)?1:0), realWidth, ((width==240)?1:0) + height-By-By-28);
#else
26 + By, realWidth, height-By-By-28);
#endif
// Right - Slots, description etc
{
int cx = (inventoryPaneRect.x + inventoryPaneRect.w);
int rightWidth = width - cx;
btnIngredient.width = btnFuel.width = btnResult.width = (int)guiSlot->getWidth();
btnIngredient.height = btnFuel.height = btnResult.height = (int)guiSlot->getHeight();
int space = rightWidth - (2 * btnFuel.width + 40);
int margin = space/2;
int bx0 = cx + margin;
int bx1 = width - margin - btnFuel.width;
btnIngredient.x = btnFuel.x = bx0;
descWidth = (float)Mth::Min(90, width - bx1 + 24 - 4);
int by = 36;// + (height-20) / 6;
btnIngredient.y = by;
btnFuel.y = by + 20 + btnFuel.height;
btnResult.x = bx1;
btnResult.y = (btnIngredient.y + btnFuel.y) / 2;
guiBackground->setSize((float)width, (float)height);
guiSlotMarker->setSize((float)btnFuel.width + 4, (float)btnFuel.height + 4);
recheckRecipes();
setupInventoryPane();
}
}
void FurnaceScreen::tick() {
if (inventoryPane)
inventoryPane->tick();
if (doRecreatePane) {
recheckRecipes();
setupInventoryPane();
doRecreatePane = false;
}
}
void FurnaceScreen::handleRenderPane(Touch::InventoryPane* pane, Tesselator& t, int xm, int ym, float a) {
if (pane) {
int ms, id;
pane->markerIndex = -1;
if (pane->queryHoldTime(&id, &ms)) {
heldMs = ms;
const ItemInstance* item = inventoryItems[id];
int count = (item && !item->isNull())? item->count : 0;
float maxHoldMs = item? 700 + 10 * item->count: MaxHoldMs;
if (count > 1 && canMoveToFurnace(id, item)) {
float share = (heldMs-MinChargeMs) / maxHoldMs;
pane->markerType = 1;//(heldMs >= MinChargeMs)? 1 : 0;
pane->markerIndex = id;
pane->markerShare = Mth::Max(share, 0.0f);
percent = (int)Mth::clamp(100.0f * share, 0.0f, 100.0f);
if (percent >= 100) {
addItem(pane, id);
}
}
}
pane->render(xm, ym, a);
guiPaneFrame->draw(t, (float)(pane->rect.x - 1), (float)(pane->rect.y - 1));
//LOGI("query-iv: %d, %d\n", gridId, heldMs);
}
}
void FurnaceScreen::render(int xm, int ym, float a) {
const int N = 5;
static StopwatchNLast r(N);
//renderBackground();
updateResult(furnace->getItem(FurnaceTileEntity::SLOT_INGREDIENT));
Tesselator& t = Tesselator::instance;
guiBackground->draw(t, 0, 0);
glEnable2(GL_ALPHA_TEST);
// Buttons (Left side + crafting)
super::render(xm, ym, a);
handleRenderPane(inventoryPane, t, xm, ym, a);
t.colorABGR(0xffffffff);
drawSlotItemAt(t, furnace->getItem(btnIngredient.id), btnIngredient.x, btnIngredient.y, btnIngredient.id == selectedSlot);
drawSlotItemAt(t, furnace->getItem(btnFuel.id), btnFuel.x, btnFuel.y, btnFuel.id == selectedSlot);
const ItemInstance* resultSlotItem = furnace->getItem(btnResult.id);
drawSlotItemAt(t, resultSlotItem, btnResult.x, btnResult.y, btnResult.id == selectedSlot);
if (!burnResult.isNull()) {
if (!resultSlotItem || resultSlotItem->isNull()) {
glEnable2(GL_BLEND);
t.beginOverride();
t.colorABGR(0x33ffffff);
t.noColor();
ItemRenderer::renderGuiItem(minecraft->font, minecraft->textures, &burnResult, (float)(btnResult.x + 7), (float)(btnResult.y + 8), true);
t.endOverrideAndDraw();
glDisable2(GL_BLEND);
}
minecraft->font->drawWordWrap(currentItemDesc, (float)btnResult.x - 24, (float)(btnResult.y + btnResult.height + 6), descWidth, rgbActive);
}
minecraft->textures->loadAndBindTexture("gui/spritesheet.png");
int yy = btnResult.y + 8;
int fpx = furnace->getLitProgress(14) + 2;
int xx0 = btnIngredient.x + 8;
blit(xx0, yy, 80, 40, 16, 16, 32, 32);
blit(xx0, yy + 16 - fpx, 112, 40 + 32-fpx-fpx, 16, fpx, 32, fpx+fpx);
int bpx = furnace->getBurnProgress(24);
int xx1 = btnIngredient.x + 40;
blit(xx1, yy, 144, 40, 24, 16, 48, 32);
blit(xx1, yy, 144, 72, bpx, 16, bpx+bpx, 32);
}
void FurnaceScreen::buttonClicked(Button* button) {
int slot = button->id;
if (button == &btnClose) {
minecraft->player->closeContainer();
}
if (slot >= FurnaceTileEntity::SLOT_INGREDIENT
&& slot <= FurnaceTileEntity::SLOT_RESULT) {
// Can't highlight the Result slot
int oldSlot = selectedSlot;
if (slot != FurnaceTileEntity::SLOT_RESULT)
selectedSlot = slot;
if (oldSlot == selectedSlot)
takeAndClearSlot(slot);
}
}
static bool sortCanCraftPredicate(const CItem* a, const CItem* b) {
//if (a->maxBuildCount == 0 && b->maxBuildCount > 0) return false;
//if (b->maxBuildCount == 0 && a->maxBuildCount > 0) return true;
return a->sortText < b->sortText;
}
void FurnaceScreen::recheckRecipes()
{
clearItems();
Stopwatch w;
w.start();
const FurnaceRecipes* recipes = FurnaceRecipes::getInstance();
ItemPack ip;
// Check for fuel, and items to burn
if (minecraft->player && minecraft->player->inventory) {
Inventory* inv = (minecraft->player)->inventory;
for (int i = Inventory::MAX_SELECTION_SIZE; i < inv->getContainerSize(); ++i) {
if (ItemInstance* item = inv->getItem(i)) {
// Fuel material
if (FurnaceTileEntity::isFuel(*item)) {
CItem* ci = new CItem(*item, NULL, "");//item->getName());
//LOGI("Adding fuel: %s\n", item->getName());
listFuel.push_back(ci);
}
// Ingredient/burn material
if (recipes->isFurnaceItem(item->id)) {
CItem* ci = new CItem(*item, NULL, "");//item->getName());
//LOGI("Adding item to burn: %s\n", item->getName());
listIngredient.push_back(ci);
}
//ip.add(ItemPack::getIdForItemInstance(item), item->count);
}
}
}
ip.print();
w.stop();
w.printEvery(1, "> craft ");
updateItems();
//std::stable_sort(_categories[c].begin(), _categories[c].end(), sortCanCraftPredicate);
}
bool FurnaceScreen::addItem(const Touch::InventoryPane* forPane, int itemIndex) {
//LOGI("items.size, index: %d, %d\n", inventoryItems.size(), itemIndex);
const ItemInstance* item = inventoryItems[itemIndex];
if (!item || item->isNull()) return false;
setIfNotSet(doRecreatePane, handleAddItem(selectedSlot, item));
if (doRecreatePane) {
int slot = inventorySlots[itemIndex];
if (player->inventory->getItem(slot)) {
// fix: if we deplete a slot we didn't click on (but had same type),
// we need to NULLify the slot that actually was depleted
for (unsigned int i = 0; i < inventorySlots.size(); ++i) {
slot = inventorySlots[i];
if (!player->inventory->getItem(slot)) {
LOGI("Changed! removing slot %d (was: %d)\n", i, itemIndex);
itemIndex = i;
break;
}
}
}
inventoryItems[itemIndex] = NULL;
}
//LOGI("Pressed button: %d\n", itemIndexInCurrentCategory);
return true;
}
bool FurnaceScreen::isAllowed( int slot )
{ //LOGI("items.size, index: %d, %d\n", inventoryItems.size(), slot);
if (slot >= (int)inventoryItems.size()) return false;
if (!inventoryItems[slot]) return false;
const ItemInstance& item = *inventoryItems[slot];
if (selectedSlot == btnFuel.id)
return (FurnaceTileEntity::getBurnDuration(item) > 0);
else
if (selectedSlot == btnIngredient.id)
return !FurnaceRecipes::getInstance()->getResult(item.id).isNull();
return false;
}
bool FurnaceScreen::renderGameBehind()
{
return false;
}
std::vector<const ItemInstance*> FurnaceScreen::getItems( const Touch::InventoryPane* forPane )
{
return inventoryItems;
}
void FurnaceScreen::clearItems()
{
for (unsigned int i = 0; i < listFuel.size(); ++i) delete listFuel[i];
for (unsigned int i = 0; i < listIngredient.size(); ++i) delete listIngredient[i];
listFuel.clear();
listIngredient.clear();
}
void FurnaceScreen::updateItems() {
inventoryItems.clear();
inventorySlots.clear();
ItemList all(listFuel.begin(), listFuel.end());
all.insert(all.end(), listIngredient.begin(), listIngredient.end());
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
ItemInstance* item = minecraft->player->inventory->getItem(i);
if (!item) continue;
//LOGI("ItemInstance (%p) Id/aux/count: %d, %d, %d\n", item, item->id, item->getAuxValue(), item->count);
bool added = false;
for (unsigned int j = 0; j < listFuel.size(); ++j) {
if (ItemInstance::matches(item, &listFuel[j]->item)) {
inventorySlots.push_back(i);
inventoryItems.push_back(item);
added = true;
break;
}
}
if (added) continue;
for (unsigned int j = 0; j < listIngredient.size(); ++j) {
if (ItemInstance::matches(item, &listIngredient[j]->item)) {
inventorySlots.push_back(i);
inventoryItems.push_back(item);
added = true;
break;
}
}
}
}
bool FurnaceScreen::canMoveToFurnace(int inventorySlot, const ItemInstance* item) {
if (!isAllowed(inventorySlot)) return false;
ItemInstance* jitem = furnace->getItem(selectedSlot);
if (!jitem || jitem->isNull()) return true;
if (ItemInstance::isStackable(item, jitem) && jitem->count < jitem->getMaxStackSize())
return true;
return false;
}
void FurnaceScreen::updateResult( const ItemInstance* item )
{
const ItemInstance* result = furnace->getItem(FurnaceTileEntity::SLOT_RESULT);
if (!result->isNull()) {
int id = result->id;
if (id == lastBurnTypeId) return;
currentItemDesc = I18n::getDescriptionString(*result);
lastBurnTypeId = id;
this->burnResult = *result;
} else {
int id = (item? item->id : 0);
if (id == lastBurnTypeId) return;
ItemInstance burnResult = FurnaceRecipes::getInstance()->getResult(id);
if (!burnResult.isNull())
currentItemDesc = I18n::getDescriptionString(burnResult);
else
currentItemDesc = "";
lastBurnTypeId = id;
this->burnResult = burnResult;
}
}
void FurnaceScreen::setupInventoryPane()
{
// IntRectangle(0, 0, 100, 100)
if (inventoryPane) delete inventoryPane;
inventoryPane = new Touch::InventoryPane(this, minecraft, inventoryPaneRect, inventoryPaneRect.w, BorderPixels, inventoryItems.size(), ItemSize, (int)BorderPixels);
inventoryPane->fillMarginX = 0;
inventoryPane->fillMarginY = 0;
guiPaneFrame->setSize((float)inventoryPaneRect.w + 2, (float)inventoryPaneRect.h + 2);
//LOGI("Creating new pane: %d %p\n", inventoryItems.size(), inventoryPane);
}
void FurnaceScreen::drawSlotItemAt( Tesselator& t, const ItemInstance* item, int x, int y, bool selected)
{
float xx = (float)x;
float yy = (float)y;
(selected? guiSlot/*Marked*/ : guiSlot)->draw(t, xx, yy);
if (selected)
guiSlotMarker->draw(t, xx - 2, yy - 2);
if (item && !item->isNull()) {
ItemRenderer::renderGuiItem(minecraft->font, minecraft->textures, item, xx + 7, yy + 8, true);
minecraft->gui.renderSlotText(item, xx + 3, yy + 3, true, true);
}
}
ItemInstance FurnaceScreen::moveOver(const ItemInstance* item, int maxCount) {
int wantedCount = item->count * percent / 100;
if (!wantedCount || heldMs < MinChargeMs)
wantedCount = 1;
wantedCount = Mth::Min(wantedCount, maxCount);
ItemInstance removed(item->id, wantedCount, item->getAuxValue());
int oldSize = minecraft->player->inventory->getNumEmptySlots();
if (minecraft->player->inventory->removeResource(removed)) {
int newSize = minecraft->player->inventory->getNumEmptySlots();
setIfNotSet(doRecreatePane, newSize != oldSize);
return removed;
}
return ItemInstance();
}
void FurnaceScreen::takeAndClearSlot( int slot )
{
//if (selectedSlot == btnBurn.id && !furnace->isSlotEmpty(btnBurn.id))
ItemInstance oldItem = *furnace->getItem(slot);
ItemInstance blank;
furnace->setItem(slot, &blank);
if (minecraft->level->isClientSide) {
ContainerSetSlotPacket p(menu->containerId, slot, blank);
minecraft->raknetInstance->send(p);
}
int oldSize = minecraft->player->inventory->getNumEmptySlots();
if (!minecraft->player->inventory->add(&oldItem))
minecraft->player->drop(new ItemInstance(oldItem), false);
int newSize = minecraft->player->inventory->getNumEmptySlots();
setIfNotSet(doRecreatePane, newSize != oldSize);
}
bool FurnaceScreen::handleAddItem( int slot, const ItemInstance* item )
{
ItemInstance* furnaceItem = furnace->getItem(slot);
int oldSize = minecraft->player->inventory->getNumEmptySlots();
if (item->id == furnaceItem->id) {
// If stackable, stack them! Else deny the addition
const int maxMovedCount = furnaceItem->getMaxStackSize() - furnaceItem->count;
if (maxMovedCount <= 0)
return false;
ItemInstance added = moveOver(item, maxMovedCount);
furnaceItem->count += added.count;
} else {
if (!furnace->isSlotEmpty(slot))
return false;//takeAndClearSlot(slot);
ItemInstance moved = moveOver(item, item->getMaxStackSize());
player->containerMenu->setSlot(slot, &moved);
}
if (minecraft->level->isClientSide) {
ContainerSetSlotPacket p(menu->containerId, slot, *furnaceItem);
minecraft->raknetInstance->send(p);
}
int newSize = minecraft->player->inventory->getNumEmptySlots();
return (newSize != oldSize);
}

View File

@@ -0,0 +1,84 @@
#ifndef _FURNACESCREEN_H__
#define _FURNACESCREEN_H__
#include "BaseContainerScreen.h"
#include "../components/InventoryPane.h"
#include "../components/Button.h"
class Font;
class CItem;
class Textures;
class NinePatchLayer;
class Tesselator;
class FurnaceScreen: public BaseContainerScreen,
public Touch::IInventoryPaneCallback
{
typedef BaseContainerScreen super;
typedef std::vector<CItem*> ItemList;
public:
FurnaceScreen(Player* player, FurnaceTileEntity* furnace);
~FurnaceScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
bool renderGameBehind();
void buttonClicked(Button* button);
// IInventoryPaneCallback
bool addItem(const Touch::InventoryPane* pane, int itemId);
bool isAllowed( int slot );
std::vector<const ItemInstance*> getItems( const Touch::InventoryPane* forPane );
private:
//void addItem(Recipe* recipe);
void recheckRecipes();
void clearItems();
void updateResult(const ItemInstance* item);
void setupInventoryPane();
void updateItems();
void drawSlotItemAt(Tesselator& t, const ItemInstance* item, int x, int y, bool selected);
ItemInstance moveOver(const ItemInstance* item, int maxCount);
void takeAndClearSlot( int slot );
bool handleAddItem( int slot, const ItemInstance* item );
void handleRenderPane(Touch::InventoryPane* pane, Tesselator& t, int xm, int ym, float a);
bool canMoveToFurnace(int inventorySlot, const ItemInstance* item);
ItemList _items;
std::string currentItemDesc;
ItemInstance burnResult;
float descWidth;
ImageButton btnClose;
BlankButton btnIngredient;
BlankButton btnFuel;
BlankButton btnResult;
Touch::THeader bHeader;
Touch::InventoryPane* inventoryPane;
IntRectangle inventoryPaneRect;
ItemList listFuel;
ItemList listIngredient;
std::vector<int> inventorySlots;
std::vector<const ItemInstance*> inventoryItems;
bool doRecreatePane;
int selectedSlot;
int lastBurnTypeId;
// GUI elements such as 9-Patches
NinePatchLayer* guiBackground;
NinePatchLayer* guiSlot;
NinePatchLayer* guiSlotMarked;
NinePatchLayer* guiSlotMarker;
NinePatchLayer* guiPaneFrame;
Player* player;
FurnaceTileEntity* furnace;
};
#endif /*_FURNACESCREEN_H__*/

View File

@@ -0,0 +1,49 @@
#include "InBedScreen.h"
#include "ScreenChooser.h"
#include "../components/Button.h"
#include "../../Minecraft.h"
#include "../../player/LocalPlayer.h"
#include "../../../platform/time.h"
static const int WAIT_TICKS = 30;
InBedScreen::InBedScreen()
: bWakeUp(0)
{
}
InBedScreen::~InBedScreen() {
delete bWakeUp;
}
void InBedScreen::init() {
if (minecraft->useTouchscreen()) {
bWakeUp = new Touch::TButton(1, "Leave Bed");
} else {
bWakeUp = new Button(1, "Leave Bed");
}
buttons.push_back(bWakeUp);
tabButtons.push_back(bWakeUp);
}
void InBedScreen::setupPositions() {
bWakeUp->width = width / 2;
bWakeUp->height = int(height * 0.2f);
bWakeUp->y = height - int(bWakeUp->height * 1.5);
bWakeUp->x = width/2 - bWakeUp->width/2;
}
void InBedScreen::render( int xm, int ym, float a ) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Screen::render(xm, ym, a);
glDisable(GL_BLEND);
}
void InBedScreen::buttonClicked( Button* button ) {
if (button == bWakeUp) {
minecraft->player->stopSleepInBed(true, true, true);
minecraft->setScreen(NULL);
}
}

View File

@@ -0,0 +1,26 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__InBedScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__InBedScreen_H__
#include "../Screen.h"
class Button;
class InBedScreen: public Screen
{
public:
InBedScreen();
virtual ~InBedScreen();
void init();
void setupPositions();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
private:
Button* bWakeUp;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__InBedScreen_H__*/

View File

@@ -0,0 +1,322 @@
#include "IngameBlockSelectionScreen.h"
#include "../../renderer/TileRenderer.h"
#include "../../player/LocalPlayer.h"
#include "../../renderer/gles.h"
#include "../../Minecraft.h"
#include "../../sound/SoundEngine.h"
#include "../../../world/entity/player/Inventory.h"
#include "../../../platform/input/Mouse.h"
#include "../Gui.h"
#include "../../renderer/Textures.h"
#include "../../gamemode/GameMode.h"
#include "ArmorScreen.h"
#include "../components/Button.h"
#if defined(__APPLE__)
static const std::string demoVersionString("Not available in the Lite version");
#else
static const std::string demoVersionString("Not available in the demo version");
#endif
IngameBlockSelectionScreen::IngameBlockSelectionScreen()
: selectedItem(0),
_area(0,0,0,0),
_pendingQuit(false),
InventoryRows(1),
InventoryCols(1),
InventorySize(1),
bArmor(1, "Armor")
{
}
void IngameBlockSelectionScreen::init()
{
Inventory* inventory = minecraft->player->inventory;
InventoryCols = minecraft->isCreativeMode()? 13 : 9;
InventorySize = inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE;
InventoryRows = 1 + (InventorySize - 1) / InventoryCols;
_area = RectangleArea( (float)getSlotPosX(0) - 4,
(float)getSlotPosY(0) - 4,
(float)getSlotPosX(InventoryCols) + 4,
(float)getSlotPosY(InventoryRows) + 4);
ItemInstance* selected = inventory->getSelected();
if (!selected || selected->isNull()) {
selectedItem = 0;
return;
}
for (int i = Inventory::MAX_SELECTION_SIZE; i < InventorySize; i++) {
if (selected == minecraft->player->inventory->getItem(i))
{
selectedItem = i - Inventory::MAX_SELECTION_SIZE;
break;
}
}
if (!isAllowed(selectedItem))
selectedItem = 0;
if (!minecraft->isCreativeMode()) {
bArmor.width = 42;
bArmor.x = 0;
bArmor.y = height - bArmor.height;
buttons.push_back(&bArmor);
}
}
void IngameBlockSelectionScreen::removed()
{
minecraft->gui.inventoryUpdated();
}
void IngameBlockSelectionScreen::renderSlots()
{
//static Stopwatch w;
//w.start();
glColor4f2(1, 1, 1, 1);
blitOffset = -90;
//glEnable2(GL_RESCALE_NORMAL);
//glPushMatrix2();
//glRotatef2(180, 1, 0, 0);
//Lighting::turnOn();
//glPopMatrix2();
minecraft->textures->loadAndBindTexture("gui/gui.png");
for (int r = 0; r < InventoryRows; r++)
{
int x = getSlotPosX(0) - 3;
int y = getSlotPosY(r) - 3;
if (InventoryCols == 9) {
blit(x, y, 0, 0, 182, 22);
} else {
// first 8 slots
blit(x, y, 0, 0, 182-20, 22);
// last k slots
const int k = 5;
const int w = k * 20;
blit(x + 162, y, 182-w, 0, w, 22);
}
}
if (selectedItem >= 0)
{
int x = getSlotPosX(selectedItem % InventoryCols) - 4;// width / 2 - 182 / 2 - 1 + () * 20;
int y = getSlotPosY(selectedItem / InventoryCols) - 4;// height - 22 * 3 - 1 - (selectedItem / InventoryCols) * 22;
blit(x, y, 0, 22, 24, 22);
}
for (int r = 0; r < InventoryRows; r++)
{
int y = getSlotPosY(r);
for (int i = 0; i < InventoryCols; i++) {
int x = getSlotPosX(i);
renderSlot(r * InventoryCols + i + Inventory::MAX_SELECTION_SIZE, x, y, 0);
}
}
//w.stop();
//w.printEvery(1000, "render-blocksel");
//glDisable2(GL_RESCALE_NORMAL);
//Lighting::turnOn();
}
int IngameBlockSelectionScreen::getSlotPosX(int slotX) {
return width / 2 - InventoryCols * 10 + slotX * 20 + 2;
}
int IngameBlockSelectionScreen::getSlotPosY(int slotY) {
//return height - 63 - 22 * (3 - slotY);
int yy = InventoryCols==9? 8 : 3;
return yy + slotY * getSlotHeight();
}
//int IngameBlockSelectionScreen::getLinearSlotId(int x, int y) {
// return
//}
#include "../../../world/item/ItemInstance.h"
#include "../../renderer/entity/ItemRenderer.h"
void IngameBlockSelectionScreen::renderSlot(int slot, int x, int y, float a)
{
ItemInstance* item = minecraft->player->inventory->getItem(slot);
if (!item) return;
ItemRenderer::renderGuiItem(minecraft->font, minecraft->textures, item, (float)x, (float)y, true);
if (minecraft->gameMode->isCreativeType()) return;
if (!isAllowed(slot - Inventory::MAX_SELECTION_SIZE)) return;
glPushMatrix2();
glScalef2(Gui::InvGuiScale + Gui::InvGuiScale, Gui::InvGuiScale + Gui::InvGuiScale, 1);
const float k = 0.5f * Gui::GuiScale;
minecraft->gui.renderSlotText(item, k*x, k*y, true, true);
glPopMatrix2();
}
void IngameBlockSelectionScreen::keyPressed(int eventKey)
{
int selX = selectedItem % InventoryCols;
int selY = selectedItem / InventoryCols;
int tmpSelectedSlot = selectedItem;
Options& o = minecraft->options;
if (eventKey == o.keyLeft.key && selX > 0)
{
tmpSelectedSlot -= 1;
}
else if (eventKey == o.keyRight.key && selX < (InventoryCols - 1))
{
tmpSelectedSlot += 1;
}
else if (eventKey == o.keyDown.key && selY < (InventoryRows - 1))
{
tmpSelectedSlot += InventoryCols;
}
else if (eventKey == o.keyUp.key && selY > 0)
{
tmpSelectedSlot -= InventoryCols;
}
if (isAllowed(tmpSelectedSlot))
selectedItem = tmpSelectedSlot;
if (eventKey == o.keyMenuOk.key)
selectSlotAndClose();
#ifdef RPI
if (eventKey == o.keyMenuCancel.key
|| eventKey == Keyboard::KEY_ESCAPE)
minecraft->setScreen(NULL);
#else
if (eventKey == o.keyMenuCancel.key)
minecraft->setScreen(NULL);
#endif
}
int IngameBlockSelectionScreen::getSelectedSlot(int x, int y)
{
int left = width / 2 - InventoryCols * 10;
int top = -4 + getSlotPosY(0);
if (x >= left && y >= top)
{
int xSlot = (x - left) / 20;
if (xSlot < InventoryCols) {
int row = ((y-top) / getSlotHeight());
return row * InventoryCols + xSlot;
}
}
return -1;
}
void IngameBlockSelectionScreen::mouseClicked(int x, int y, int buttonNum)
{
if (buttonNum == MouseAction::ACTION_LEFT) {
int slot = getSelectedSlot(x, y);
if (isAllowed(slot))
{
selectedItem = slot;
//minecraft->soundEngine->playUI("random.click", 1, 1);
} else {
_pendingQuit = !_area.isInside((float)x, (float)y)
&& !bArmor.isInside(x, y);
}
}
if (!_pendingQuit)
super::mouseClicked(x, y, buttonNum);
}
void IngameBlockSelectionScreen::mouseReleased(int x, int y, int buttonNum)
{
if (buttonNum == MouseAction::ACTION_LEFT) {
int slot = getSelectedSlot(x, y);
if (isAllowed(slot) && slot == selectedItem)
{
selectSlotAndClose();
} else {
if (_pendingQuit && !_area.isInside((float)x, (float)y))
minecraft->setScreen(NULL);
}
}
if (!_pendingQuit)
super::mouseReleased(x, y, buttonNum);
}
void IngameBlockSelectionScreen::selectSlotAndClose()
{
Inventory* inventory = minecraft->player->inventory;
// Flash the selected gui item
//inventory->moveToSelectedSlot(selectedItem + Inventory::MAX_SELECTION_SIZE, true);
inventory->moveToSelectionSlot(0, selectedItem + Inventory::MAX_SELECTION_SIZE, true);
inventory->selectSlot(0);
minecraft->gui.flashSlot(inventory->selected);
minecraft->soundEngine->playUI("random.click", 1, 1);
minecraft->setScreen(NULL);
}
void IngameBlockSelectionScreen::render( int xm, int ym, float a )
{
glDisable2(GL_DEPTH_TEST);
fill(0, 0, width, height, (0x80) << 24);
glEnable2(GL_BLEND);
glDisable2(GL_ALPHA_TEST);
glEnable2(GL_BLEND);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
renderSlots();
renderDemoOverlay();
glEnable2(GL_ALPHA_TEST);
glDisable2(GL_BLEND);
glEnable2(GL_DEPTH_TEST);
Screen::render(xm, ym, a);
}
void IngameBlockSelectionScreen::renderDemoOverlay() {
#ifdef DEMO_MODE
fill( getSlotPosX(0) - 3, getSlotPosY(3) - 3,
getSlotPosX(InventoryCols) - 3, getSlotPosY(InventoryRows) - 3, 0xa0 << 24);
const int centerX = (getSlotPosX(4) + getSlotPosX(5)) / 2;
const int centerY = (getSlotPosY(3) + getSlotPosY(InventoryRows-1)) / 2 + 5;
drawCenteredString(minecraft->font, demoVersionString, centerX, centerY, 0xffffffff);
#endif /*DEMO_MODE*/
}
bool IngameBlockSelectionScreen::isAllowed(int slot) {
if (slot < 0 || slot >= InventorySize)
return false;
#ifdef DEMO_MODE
return slot < (minecraft->isCreativeMode()? 28 : 27);
#endif /*DEMO_MODE*/
return true;
}
int IngameBlockSelectionScreen::getSlotHeight() {
return InventoryCols==9? 22 : 20;
}
void IngameBlockSelectionScreen::buttonClicked( Button* button )
{
if (button == &bArmor) {
minecraft->setScreen(new ArmorScreen());
}
super::buttonClicked(button);
}

View File

@@ -0,0 +1,56 @@
#ifndef _MINECRAFT_INGAMEBLOCKSELECTIONSCREEN_H_
#define _MINECRAFT_INGAMEBLOCKSELECTIONSCREEN_H_
#include "../Screen.h"
#include "../../player/input/touchscreen/TouchAreaModel.h"
#include "../components/Button.h"
class IngameBlockSelectionScreen : public Screen
{
typedef Screen super;
public:
IngameBlockSelectionScreen();
virtual ~IngameBlockSelectionScreen() {}
virtual void init();
virtual void removed();
void render(int xm, int ym, float a);
protected:
virtual void mouseClicked(int x, int y, int buttonNum);
virtual void mouseReleased(int x, int y, int buttonNum);
virtual void buttonClicked(Button* button);
virtual void keyPressed(int eventKey);
private:
void renderSlots();
void renderSlot(int slot, int x, int y, float a);
void renderDemoOverlay();
int getSelectedSlot(int x, int y);
void selectSlotAndClose();
//int getLinearSlotId(int x, int y);
int getSlotPosX(int slotX);
int getSlotPosY(int slotY);
int getSlotHeight();
bool isAllowed(int slot);
private:
int InventoryCols;
int InventoryRows;
int InventorySize;
int selectedItem;
bool _pendingQuit;
Button bArmor;
RectangleArea _area;
};
#endif

View File

@@ -0,0 +1,107 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__InvalidLicenseScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__InvalidLicenseScreen_H__
#include "../Screen.h"
#include "../components/Button.h"
#include "../../Minecraft.h"
#include "../../../LicenseCodes.h"
class InvalidLicenseScreen: public Screen
{
public:
InvalidLicenseScreen(int id, bool hasBuyButton)
: _id(id),
_hasBuyButton(hasBuyButton),
_baseY(0),
bOk(0),
bBuy(0)
{
}
virtual ~InvalidLicenseScreen() {
delete bOk;
delete bBuy;
}
void init() {
if (minecraft->useTouchscreen()) {
bOk = new Touch::TButton(1, "Ok");
bBuy = new Touch::TButton(2, "Buy");
} else {
bOk = new Button(1, "Ok");
bBuy = new Button(2, "Buy");
}
if (_hasBuyButton)
bOk->msg = "Quit";
if (!LicenseCodes::isOk(_id)) {
char buf[20] = {0};
sprintf(buf, "%d", _id);
desc1 = "License verification failed (error ";
desc1 += buf;
desc1 += ")";
desc2 = "Try again later.";
hint = "You need to be connected to the internet\n";
hint += "once while you start the game.";
}
buttons.push_back(bOk);
tabButtons.push_back(bOk);
if (_hasBuyButton) {
buttons.push_back(bBuy);
tabButtons.push_back(bBuy);
}
}
void setupPositions() {
_baseY = height/5 + 6;
//if (_hasBuyButton)
_baseY -= 24;
bOk->width = bBuy->width = 200;
bOk->x = bBuy->x = (width - bOk->width) / 2;
bBuy->y = _baseY + 84;
bOk->y = bBuy->y + bBuy->height + 4;
if (!_hasBuyButton)
bOk->y -= 24;
}
void tick() {}
//void keyPressed(int eventKey) {}
void render(int xm, int ym, float a) {
renderDirtBackground(0);
drawCenteredString(minecraft->font, desc1, width/2, _baseY, 0xffffff);
drawCenteredString(minecraft->font, desc2, width/2, _baseY + 24, 0xffffff);
drawCenteredString(minecraft->font, hint, width/2, _baseY + 60, 0xffffff);
Screen::render(xm, ym, a);
}
void buttonClicked(Button* button) {
if (button->id == bOk->id) {
minecraft->quit();
}
if (button->id == bBuy->id) {
minecraft->platform()->buyGame();
}
};
private:
int _id;
std::string desc1;
std::string desc2;
std::string hint;
Button* bOk;
Button* bBuy;
bool _hasBuyButton;
int _baseY;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__InvalidLicenseScreen_H__*/

View File

@@ -0,0 +1,167 @@
#include "JoinGameScreen.h"
#include "StartMenuScreen.h"
#include "ProgressScreen.h"
#include "../Font.h"
#include "../../../network/RakNetInstance.h"
JoinGameScreen::JoinGameScreen()
: bJoin( 2, "Join Game"),
bBack( 3, "Back"),
gamesList(NULL)
{
bJoin.active = false;
//gamesList->yInertia = 0.5f;
}
JoinGameScreen::~JoinGameScreen()
{
delete gamesList;
}
void JoinGameScreen::buttonClicked(Button* button)
{
if (button->id == bJoin.id)
{
if (isIndexValid(gamesList->selectedItem))
{
PingedCompatibleServer selectedServer = gamesList->copiedServerList[gamesList->selectedItem];
minecraft->joinMultiplayer(selectedServer);
{
bJoin.active = false;
bBack.active = false;
minecraft->setScreen(new ProgressScreen());
}
}
//minecraft->locateMultiplayer();
//minecraft->setScreen(new JoinGameScreen());
}
if (button->id == bBack.id)
{
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
}
bool JoinGameScreen::handleBackEvent(bool isDown)
{
if (!isDown)
{
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
return true;
}
bool JoinGameScreen::isIndexValid( int index )
{
return gamesList && index >= 0 && index < gamesList->getNumberOfItems();
}
void JoinGameScreen::tick()
{
const ServerList& orgServerList = minecraft->raknetInstance->getServerList();
ServerList serverList;
for (unsigned int i = 0; i < orgServerList.size(); ++i)
if (orgServerList[i].name.GetLength() > 0)
serverList.push_back(orgServerList[i]);
if (serverList.size() != gamesList->copiedServerList.size())
{
// copy the currently selected item
PingedCompatibleServer selectedServer;
bool hasSelection = false;
if (isIndexValid(gamesList->selectedItem))
{
selectedServer = gamesList->copiedServerList[gamesList->selectedItem];
hasSelection = true;
}
gamesList->copiedServerList = serverList;
gamesList->selectItem(-1, false);
// re-select previous item if it still exists
if (hasSelection)
{
for (unsigned int i = 0; i < gamesList->copiedServerList.size(); i++)
{
if (gamesList->copiedServerList[i].address == selectedServer.address)
{
gamesList->selectItem(i, false);
break;
}
}
}
} else {
for (int i = (int)gamesList->copiedServerList.size()-1; i >= 0 ; --i) {
for (int j = 0; j < (int) serverList.size(); ++j)
if (serverList[j].address == gamesList->copiedServerList[i].address)
gamesList->copiedServerList[i].name = serverList[j].name;
}
}
bJoin.active = isIndexValid(gamesList->selectedItem);
}
void JoinGameScreen::init()
{
buttons.push_back(&bJoin);
buttons.push_back(&bBack);
minecraft->raknetInstance->clearServerList();
gamesList = new AvailableGamesList(minecraft, width, height);
#ifdef ANDROID
tabButtons.push_back(&bJoin);
tabButtons.push_back(&bBack);
#endif
}
void JoinGameScreen::setupPositions() {
int yBase = height - 26;
//#ifdef ANDROID
bJoin.y = yBase;
bBack.y = yBase;
bBack.width = bJoin.width = 120;
//#endif
// Center buttons
bJoin.x = width / 2 - 4 - bJoin.width;
bBack.x = width / 2 + 4;
}
void JoinGameScreen::render( int xm, int ym, float a )
{
bool hasNetwork = minecraft->platform()->isNetworkEnabled(true);
#ifdef WIN32
hasNetwork = hasNetwork && !GetAsyncKeyState(VK_TAB);
#endif
renderBackground();
if (hasNetwork) gamesList->render(xm, ym, a);
Screen::render(xm, ym, a);
if (hasNetwork) {
#ifdef RPI
std::string s = "Scanning for Local Network Games...";
#else
std::string s = "Scanning for WiFi Games...";
#endif
drawCenteredString(minecraft->font, s, width / 2, 8, 0xffffffff);
const int textWidth = minecraft->font->width(s);
const int spinnerX = width/2 + textWidth / 2 + 6;
static const char* spinnerTexts[] = {"-", "\\", "|", "/"};
int n = ((int)(5.5f * getTimeS()) % 4);
drawCenteredString(minecraft->font, spinnerTexts[n], spinnerX, 8, 0xffffffff);
} else {
std::string s = "WiFi is disabled";
const int yy = height / 2 - 8;
drawCenteredString(minecraft->font, s, width / 2, yy, 0xffffffff);
}
}
bool JoinGameScreen::isInGameScreen() { return false; }

View File

@@ -0,0 +1,71 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__JoinGameScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__JoinGameScreen_H__
#include "../Screen.h"
#include "../components/Button.h"
#include "../components/SmallButton.h"
#include "../components/ScrolledSelectionList.h"
#include "../../Minecraft.h"
#include "../../../network/RakNetInstance.h"
class JoinGameScreen;
class AvailableGamesList : public ScrolledSelectionList
{
int selectedItem;
ServerList copiedServerList;
friend class JoinGameScreen;
public:
AvailableGamesList(Minecraft* _minecraft, int _width, int _height)
: ScrolledSelectionList(_minecraft, _width, _height, 24, _height - 30, 28)
{
}
protected:
virtual int getNumberOfItems() { return (int)copiedServerList.size(); }
virtual void selectItem(int item, bool doubleClick) { selectedItem = item; }
virtual bool isSelectedItem(int item) { return item == selectedItem; }
virtual void renderBackground() {}
virtual void renderItem(int i, int x, int y, int h, Tesselator& t)
{
const PingedCompatibleServer& s = copiedServerList[i];
unsigned int color = s.isSpecial? 0xff00b0 : 0xffffa0;
drawString(minecraft->font, s.name.C_String(), x, y + 2, color);
drawString(minecraft->font, s.address.ToString(false), x, y + 16, 0xffffa0);
}
};
class JoinGameScreen: public Screen
{
public:
JoinGameScreen();
virtual ~JoinGameScreen();
void init();
void setupPositions();
virtual bool handleBackEvent(bool isDown);
virtual bool isIndexValid(int index);
virtual void tick();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
bool isInGameScreen();
private:
Button bJoin;
Button bBack;
AvailableGamesList* gamesList;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__JoinGameScreen_H__*/

View File

@@ -0,0 +1,181 @@
#include "OptionsScreen.h"
#include "StartMenuScreen.h"
#include "DialogDefinitions.h"
#include "../../Minecraft.h"
#include "../../../AppPlatform.h"
#include "../components/OptionsPane.h"
#include "../components/ImageButton.h"
#include "../components/OptionsGroup.h"
OptionsScreen::OptionsScreen()
: btnClose(NULL),
bHeader(NULL),
selectedCategory(0) {
}
OptionsScreen::~OptionsScreen() {
if(btnClose != NULL) {
delete btnClose;
btnClose = NULL;
}
if(bHeader != NULL) {
delete bHeader,
bHeader = NULL;
}
for(std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
if(*it != NULL) {
delete *it;
*it = NULL;
}
}
for(std::vector<OptionsPane*>::iterator it = optionPanes.begin(); it != optionPanes.end(); ++it) {
if(*it != NULL) {
delete *it;
*it = NULL;
}
}
categoryButtons.clear();
}
void OptionsScreen::init() {
bHeader = new Touch::THeader(0, "Options");
btnClose = new ImageButton(1, "");
ImageDef def;
def.name = "gui/touchgui.png";
def.width = 34;
def.height = 26;
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
btnClose->setImageDef(def, true);
categoryButtons.push_back(new Touch::TButton(2, "Login"));
categoryButtons.push_back(new Touch::TButton(3, "Game"));
categoryButtons.push_back(new Touch::TButton(4, "Controls"));
categoryButtons.push_back(new Touch::TButton(5, "Graphics"));
buttons.push_back(bHeader);
buttons.push_back(btnClose);
for(std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
buttons.push_back(*it);
tabButtons.push_back(*it);
}
generateOptionScreens();
}
void OptionsScreen::setupPositions() {
int buttonHeight = btnClose->height;
btnClose->x = width - btnClose->width;
btnClose->y = 0;
int offsetNum = 1;
for(std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
(*it)->x = 0;
(*it)->y = offsetNum * buttonHeight;
(*it)->selected = false;
offsetNum++;
}
bHeader->x = 0;
bHeader->y = 0;
bHeader->width = width - btnClose->width;
bHeader->height = btnClose->height;
for(std::vector<OptionsPane*>::iterator it = optionPanes.begin(); it != optionPanes.end(); ++it) {
if(categoryButtons.size() > 0 && categoryButtons[0] != NULL) {
(*it)->x = categoryButtons[0]->width;
(*it)->y = bHeader->height;
(*it)->width = width - categoryButtons[0]->width;
(*it)->setupPositions();
}
}
selectCategory(0);
}
void OptionsScreen::render( int xm, int ym, float a ) {
renderBackground();
super::render(xm, ym, a);
int xmm = xm * width / minecraft->width;
int ymm = ym * height / minecraft->height - 1;
if(currentOptionPane != NULL)
currentOptionPane->render(minecraft, xmm, ymm);
}
void OptionsScreen::removed()
{
}
void OptionsScreen::buttonClicked( Button* button ) {
if(button == btnClose) {
minecraft->reloadOptions();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
} else if(button->id > 1 && button->id < 7) {
// This is a category button
int categoryButton = button->id - categoryButtons[0]->id;
selectCategory(categoryButton);
}
}
void OptionsScreen::selectCategory( int index ) {
int currentIndex = 0;
for(std::vector<Touch::TButton*>::iterator it = categoryButtons.begin(); it != categoryButtons.end(); ++it) {
if(index == currentIndex) {
(*it)->selected = true;
} else {
(*it)->selected = false;
}
currentIndex++;
}
if(index < (int)optionPanes.size())
currentOptionPane = optionPanes[index];
}
void OptionsScreen::generateOptionScreens() {
optionPanes.push_back(new OptionsPane());
optionPanes.push_back(new OptionsPane());
optionPanes.push_back(new OptionsPane());
optionPanes.push_back(new OptionsPane());
// Mojang Pane
optionPanes[0]->createOptionsGroup("options.group.mojang")
//.addOptionItem(&Options::Option::THIRD_PERSON, minecraft);
.addOptionItem(&Options::Option::SENSITIVITY, minecraft);
// int mojangGroup = optionPanes[0]->createOptionsGroup("Mojang");
// static const int arr[] = {5,4,3,15};
// std::vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
// optionPanes[0]->createStepSlider(minecraft, mojangGroup, "This works?", &Options::Option::DIFFICULTY, vec);
//
// // Game Pane
// int gameGroup = optionPanes[1]->createOptionsGroup("Game");
// optionPanes[1]->createToggle(gameGroup, "Third person camera", &Options::Option::THIRD_PERSON);
// optionPanes[1]->createToggle(gameGroup, "Server visible", &Options::Option::SERVER_VISIBLE);
//
// // Input Pane
// int controlsGroup = optionPanes[2]->createOptionsGroup("Controls");
// optionPanes[2]->createToggle(controlsGroup, "Invert X-axis", &Options::Option::INVERT_MOUSE);
// optionPanes[2]->createToggle(controlsGroup, "Lefty", &Options::Option::LEFT_HANDED);
// optionPanes[2]->createToggle(controlsGroup, "Use touch screen", &Options::Option::USE_TOUCHSCREEN);
// optionPanes[2]->createToggle(controlsGroup, "Split touch controls", &Options::Option::USE_TOUCH_JOYPAD);
// int feedBackGroup = optionPanes[2]->createOptionsGroup("Feedback");
// optionPanes[2]->createToggle(feedBackGroup, "Vibrate on destroy", &Options::Option::DESTROY_VIBRATION);
//
// int graphicsGroup = optionPanes[3]->createOptionsGroup("Graphics");
// optionPanes[3]->createProgressSlider(minecraft, graphicsGroup, "Gui Scale", &Options::Option::PIXELS_PER_MILLIMETER, 3, 4);
// optionPanes[3]->createToggle(graphicsGroup, "Fancy Graphics", &Options::Option::INVERT_MOUSE);
// optionPanes[3]->createToggle(graphicsGroup, "Fancy Skies", &Options::Option::INVERT_MOUSE);
// optionPanes[3]->createToggle(graphicsGroup, "Animated water", &Options::Option::INVERT_MOUSE);
// int experimentalGraphicsGroup = optionPanes[3]->createOptionsGroup("Experimental graphics");
// optionPanes[3]->createToggle(experimentalGraphicsGroup, "Soft shadows", &Options::Option::INVERT_MOUSE);
}
void OptionsScreen::mouseClicked( int x, int y, int buttonNum ) {
if(currentOptionPane != NULL)
currentOptionPane->mouseClicked(minecraft, x, y, buttonNum);
super::mouseClicked(x, y, buttonNum);
}
void OptionsScreen::mouseReleased( int x, int y, int buttonNum ) {
if(currentOptionPane != NULL)
currentOptionPane->mouseReleased(minecraft, x, y, buttonNum);
super::mouseReleased(x, y, buttonNum);
}
void OptionsScreen::tick() {
if(currentOptionPane != NULL)
currentOptionPane->tick(minecraft);
super::tick();
}

View File

@@ -0,0 +1,38 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__OptionsScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__OptionsScreen_H__
#include "../Screen.h"
#include "../components/Button.h"
class ImageButton;
class OptionsPane;
class OptionsScreen: public Screen
{
typedef Screen super;
void init();
void generateOptionScreens();
public:
OptionsScreen();
~OptionsScreen();
void setupPositions();
void buttonClicked( Button* button );
void render(int xm, int ym, float a);
void removed();
void selectCategory(int index);
virtual void mouseClicked( int x, int y, int buttonNum );
virtual void mouseReleased( int x, int y, int buttonNum );
virtual void tick();
private:
Touch::THeader* bHeader;
ImageButton* btnClose;
std::vector<Touch::TButton*> categoryButtons;
std::vector<OptionsPane*> optionPanes;
OptionsPane* currentOptionPane;
int selectedCategory;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__OptionsScreen_H__*/

View File

@@ -0,0 +1,189 @@
#include "PauseScreen.h"
#include "StartMenuScreen.h"
#include "../components/ImageButton.h"
#include "../../Minecraft.h"
#include "../../../util/Mth.h"
#include "../../../network/RakNetInstance.h"
#include "../../../network/ServerSideNetworkHandler.h"
PauseScreen::PauseScreen(bool wasBackPaused)
: saveStep(0),
visibleTime(0),
bContinue(0),
bQuit(0),
bQuitAndSaveLocally(0),
bServerVisibility(0),
// bThirdPerson(0),
wasBackPaused(wasBackPaused),
bSound(&Options::Option::SOUND, 1, 0),
bThirdPerson(&Options::Option::THIRD_PERSON),
bHideGui(&Options::Option::HIDE_GUI)
{
ImageDef def;
def.setSrc(IntRectangle(160, 144, 39, 31));
def.name = "gui/touchgui.png";
IntRectangle& defSrc = *def.getSrc();
def.width = defSrc.w * 0.666667f;
def.height = defSrc.h * 0.666667f;
bSound.setImageDef(def, true);
defSrc.y += defSrc.h;
bThirdPerson.setImageDef(def, true);
bHideGui.setImageDef(def, true);
//void setImageDef(ImageDef& imageDef, bool setButtonSize);
}
PauseScreen::~PauseScreen() {
delete bContinue;
delete bQuit;
delete bQuitAndSaveLocally;
delete bServerVisibility;
// delete bThirdPerson;
}
void PauseScreen::init() {
if (minecraft->useTouchscreen()) {
bContinue = new Touch::TButton(1, "Back to game");
bQuit = new Touch::TButton(2, "Quit to title");
bQuitAndSaveLocally = new Touch::TButton(3, "Quit and copy map");
bServerVisibility = new Touch::TButton(4, "");
// bThirdPerson = new Touch::TButton(5, "Toggle 3:rd person view");
} else {
bContinue = new Button(1, "Back to game");
bQuit = new Button(2, "Quit to title");
bQuitAndSaveLocally = new Button(3, "Quit and copy map");
bServerVisibility = new Button(4, "");
// bThirdPerson = new Button(5, "Toggle 3:rd person view");
}
buttons.push_back(bContinue);
buttons.push_back(bQuit);
bSound.updateImage(&minecraft->options);
bThirdPerson.updateImage(&minecraft->options);
bHideGui.updateImage(&minecraft->options);
buttons.push_back(&bSound);
buttons.push_back(&bThirdPerson);
//buttons.push_back(&bHideGui);
// If Back wasn't pressed, set up additional items (more than Quit to menu
// and Back to game) here
#if !defined(APPLE_DEMO_PROMOTION) && !defined(RPI)
if (true || !wasBackPaused) {
if (minecraft->raknetInstance) {
if (minecraft->raknetInstance->isServer()) {
updateServerVisibilityText();
buttons.push_back(bServerVisibility);
}
else {
#if !defined(DEMO_MODE)
buttons.push_back(bQuitAndSaveLocally);
#endif
}
}
}
#endif
// buttons.push_back(bThirdPerson);
for (unsigned int i = 0; i < buttons.size(); ++i) {
if (buttons[i] == &bSound) continue;
if (buttons[i] == &bThirdPerson) continue;
if (buttons[i] == &bHideGui) continue;
tabButtons.push_back(buttons[i]);
}
}
void PauseScreen::setupPositions() {
saveStep = 0;
int yBase = 16;
bContinue->width = bQuit->width = /*bThirdPerson->w =*/ 160;
bQuitAndSaveLocally->width = bServerVisibility->width = 160;
bContinue->x = (width - bContinue->width) / 2;
bContinue->y = yBase + 32 * 1;
bQuit->x = (width - bQuit->width) / 2;
bQuit->y = yBase + 32 * 2;
#if APPLE_DEMO_PROMOTION
bQuit->y += 16;
#endif
bQuitAndSaveLocally->x = bServerVisibility->x = (width - bQuitAndSaveLocally->width) / 2;
bQuitAndSaveLocally->y = bServerVisibility->y = yBase + 32 * 3;
bSound.y = bThirdPerson.y = 8;
bSound.x = 4;
bThirdPerson.x = bSound.x + 4 + bSound.width;
bHideGui.x = bThirdPerson.x + 4 + bThirdPerson.width;
//bThirdPerson->x = (width - bThirdPerson->w) / 2;
//bThirdPerson->y = yBase + 32 * 4;
}
void PauseScreen::tick() {
super::tick();
visibleTime++;
}
void PauseScreen::render(int xm, int ym, float a) {
renderBackground();
//bool isSaving = !minecraft->level.pauseSave(saveStep++);
//if (isSaving || visibleTime < 20) {
// float col = ((visibleTime % 10) + a) / 10.0f;
// col = Mth::sin(col * Mth::PI * 2) * 0.2f + 0.8f;
// int br = (int) (255 * col);
// drawString(font, "Saving level..", 8, height - 16, br << 16 | br << 8 | br);
//}
drawCenteredString(font, "Game menu", width / 2, 24, 0xffffff);
super::render(xm, ym, a);
}
void PauseScreen::buttonClicked(Button* button) {
if (button->id == bContinue->id) {
minecraft->setScreen(NULL);
//minecraft->grabMouse();
}
if (button->id == bQuit->id) {
minecraft->leaveGame();
}
if (button->id == bQuitAndSaveLocally->id) {
minecraft->leaveGame(true);
}
if (button->id == bServerVisibility->id) {
if (minecraft->raknetInstance && minecraft->netCallback && minecraft->raknetInstance->isServer()) {
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) minecraft->netCallback;
bool allows = !ss->allowsIncomingConnections();
ss->allowIncomingConnections(allows);
updateServerVisibilityText();
}
}
if (button->id == OptionButton::ButtonId) {
((OptionButton*)button)->toggle(&minecraft->options);
}
//if (button->id == bThirdPerson->id) {
// minecraft->options.thirdPersonView = !minecraft->options.thirdPersonView;
//}
}
void PauseScreen::updateServerVisibilityText()
{
if (!minecraft->raknetInstance || !minecraft->raknetInstance->isServer())
return;
ServerSideNetworkHandler* ss = (ServerSideNetworkHandler*) minecraft->netCallback;
bServerVisibility->msg = ss->allowsIncomingConnections()?
"Server is visible"
: "Server is invisible";
}

View File

@@ -0,0 +1,43 @@
#ifndef NET_MINECRAFT_CLIENT_GUI__PauseScreen_H__
#define NET_MINECRAFT_CLIENT_GUI__PauseScreen_H__
//package net.minecraft.client.gui;
#include "../Screen.h"
#include "../components/ImageButton.h"
class Button;
class PauseScreen: public Screen
{
typedef Screen super;
public:
PauseScreen(bool wasBackPaused);
~PauseScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
protected:
void buttonClicked(Button* button);
private:
void updateServerVisibilityText();
int saveStep;
int visibleTime;
bool wasBackPaused;
Button* bContinue;
Button* bQuit;
Button* bQuitAndSaveLocally;
Button* bServerVisibility;
// Button* bThirdPerson;
OptionButton bSound;
OptionButton bThirdPerson;
OptionButton bHideGui;
};
#endif /*NET_MINECRAFT_CLIENT_GUI__PauseScreen_H__*/

View File

@@ -0,0 +1,162 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__PrerenderTilesScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__PrerenderTilesScreen_H__
#include "../Screen.h"
#include "../../renderer/GameRenderer.h"
#include "../../renderer/entity/ItemRenderer.h"
#include "../../../world/item/ItemInstance.h"
#include "../../../world/level/tile/Tile.h"
#include "../../../world/entity/player/Inventory.h"
#include "../../renderer/Tesselator.h"
#include "../../../world/item/crafting/Recipes.h"
#include "../../../world/item/crafting/FurnaceRecipes.h"
#include "../../../world/level/tile/LeafTile.h"
#include "../../renderer/TileRenderer.h"
class PrerenderTilesScreen: public Screen
{
public:
void init() {
Player p(minecraft->level, true);
Inventory _inventory(&p, true);
Inventory* inventory = &_inventory;
// Copy over the inventory items
for (int i = Inventory::MAX_SELECTION_SIZE; i < inventory->getContainerSize(); ++i)
addItem(inventory->getItem(i));
// Fill the inventory with all the recipe items we don't already have: furnace
const FurnaceRecipes::Map& furnaceRecipes = FurnaceRecipes::getInstance()->getRecipes();
for (FurnaceRecipes::Map::const_iterator cit = furnaceRecipes.begin(); cit != furnaceRecipes.end(); ++cit) {
ItemInstance ingredient(cit->first, 1, 0);
addItem(&ingredient);
ItemInstance result = cit->second;
addItem(&result);
}
// Fill the inventory with all the recipe items we don't already have: crafting
const RecipeList& recipes = Recipes::getInstance()->getRecipes();
for (unsigned int i = 0; i < recipes.size(); ++i) {
std::vector<ItemInstance> items;
std::vector<ItemInstance> required = recipes[i]->getItemPack().getItemInstances();
items.push_back(recipes[i]->getResultItem());
items.insert(items.end(), required.begin(), required.end());
for (unsigned int i = 0; i < items.size(); ++i) {
ItemInstance& item = items[i];
addItem(&item);
}
}
// Manually added stuff
// Example: the one that's spawned from tiles when destroyed
int items[] = {
Tile::sapling->id, LeafTile::BIRCH_LEAF,
Tile::sapling->id, LeafTile::EVERGREEN_LEAF,
Tile::sapling->id, LeafTile::NORMAL_LEAF,
Tile::dirt->id, 0,
Tile::reeds->id, 0,
Tile::gravel->id, 0,
Item::apple->id, 0,
Tile::grass_carried->id, 0,
Tile::web->id, 0,
Item::sign->id, 0,
};
for (int i = 0; i < sizeof(items)/sizeof(int); i += 2) {
ItemInstance item(items[i], 1, items[i+1]);
addItem(&item);
}
}
void render( int xm, int ym, float a ) {
static Stopwatch w;
w.start();
glDisable2(GL_DEPTH_TEST);
fill(0, 0, width, height, 0xffff00ff);
//fill(0, 0, width, height, 0xff333333);
glColor4f2(1, 1, 1, 1);
glEnable2(GL_BLEND);
LOGI("--------------------\n");
/*int j = 0;
for (int i = Inventory::MAX_SELECTION_SIZE; i < inventory->getContainerSize(); ++i) {
ItemInstance* item = inventory->getItem(i);
if (!item) continue;
//LOGI("desc: %d - %s. %d\n", i, item->toString().c_str());
int x = j%16 * 16;
int y = j/16 * 16;
//Tesselator::instance.color(0xffffffff);
//minecraft->textures->loadAndBindTexture("gui/gui2.png");
//glColor4f2(0.2f, 0.5f, 0.2f, 1);
//blit(x, y, 4 + 20 * (i%9), 4, 16, 16, 15, 15);
//glColor4f2(1, 1, 1, 1);
if (item->id < 256 && TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape())) {
LOGI("0, %d, %d, %d, 0\n", j, item->id, item->getAuxValue());
ItemRenderer::renderGuiItemCorrect(minecraft->font, minecraft->textures, item, x, y);
} else if (item->getIcon() >= 0) {
LOGI("1, %d, %d, %d, %d\n", j, item->id, item->getAuxValue(), item->getIcon());
}
++j;
}*/
int j = 0;
for(std::vector<ItemInstance>::iterator i = mItems.begin(); i != mItems.end(); ++i) {
ItemInstance* item = &(*i);
//LOGI("desc: %d - %s. %d\n", i, item->toString().c_str());
int x = j%16 * 16;
int y = j/16 * 16;
if (item->id < 256 && TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape())) {
LOGI("0, %d, %d, %d, 0\n", j, item->id, item->getAuxValue());
ItemRenderer::renderGuiItemCorrect(minecraft->font, minecraft->textures, item, x, y);
} else if (item->getIcon() >= 0) {
LOGI("1, %d, %d, %d, %d\n", j, item->id, item->getAuxValue(), item->getIcon());
}
j++;
}
//@todo: blit out something famous here
//glRotatef2(-180, 1, 0, 0);
glEnable2(GL_DEPTH_TEST);
glDisable2(GL_BLEND);
w.stop();
w.printEvery(100, "render-blocksel");
}
void removed(){}
void addItem(ItemInstance* item) {
if(item == NULL)
return;
if (item->getAuxValue() < 0) return;
bool found = false;
for(std::vector<ItemInstance>::iterator i = mItems.begin(); i != mItems.end(); ++i) {
ItemInstance *jitem = &*i;
if(jitem->id != item->id) continue;
if(jitem->isStackedByData() && jitem->getAuxValue() != item->getAuxValue()) continue;
found = true;
break;
}
if (!found) {
LOGI("Adding item: %s\n", item->getDescriptionId().c_str());
mItems.push_back(*item);
}
}
private:
std::vector<ItemInstance> mItems;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__PrerenderTilesScreen_H__*/

View File

@@ -0,0 +1,99 @@
#include "ProgressScreen.h"
#include "DisconnectionScreen.h"
#include "../Gui.h"
#include "../Font.h"
#include "../../Minecraft.h"
#include "../../renderer/Tesselator.h"
#include "../../../SharedConstants.h"
#include "../../renderer/Textures.h"
ProgressScreen::ProgressScreen()
: ticks(0)
{
}
void ProgressScreen::render( int xm, int ym, float a )
{
if (minecraft->isLevelGenerated()) {
minecraft->setScreen(NULL);
return;
}
Tesselator& t = Tesselator::instance;
renderBackground();
minecraft->textures->loadAndBindTexture("gui/background.png");
const float s = 32;
t.begin();
t.color(0x404040);
t.vertexUV(0, (float)height, 0, 0, height / s);
t.vertexUV((float)width, (float)height, 0, width / s, height / s);
t.vertexUV((float)width, 0, 0, width / s, 0);
t.vertexUV(0, 0, 0, 0, 0);
t.draw();
int i = minecraft->progressStagePercentage;
if (i >= 0) {
int w = 100;
int h = 2;
int x = width / 2 - w / 2;
int y = height / 2 + 16;
//printf("%d, %d - %d, %d\n", x, y, x + w, y + h);
glDisable2(GL_TEXTURE_2D);
t.begin();
t.color(0x808080);
t.vertex((float)x, (float)y, 0);
t.vertex((float)x, (float)(y + h), 0);
t.vertex((float)(x + w), (float)(y + h), 0);
t.vertex((float)(x + w), (float)y, 0);
t.color(0x80ff80);
t.vertex((float)x, (float)y, 0);
t.vertex((float)x, (float)(y + h), 0);
t.vertex((float)(x + i), (float)(y + h), 0);
t.vertex((float)(x + i), (float)y, 0);
t.draw();
glEnable2(GL_TEXTURE_2D);
}
glEnable2(GL_BLEND);
const char* title = "Generating world";
minecraft->font->drawShadow(title, (float)((width - minecraft->font->width(title)) / 2), (float)(height / 2 - 4 - 16), 0xffffff);
const char* status = minecraft->getProgressMessage();
const int progressWidth = minecraft->font->width(status);
const int progressLeft = (width - progressWidth) / 2;
const int progressY = height / 2 - 4 + 8;
minecraft->font->drawShadow(status, (float)progressLeft, (float)progressY, 0xffffff);
#if APPLE_DEMO_PROMOTION
drawCenteredString(minecraft->font, "This demonstration version", width/2, progressY + 36, 0xffffff);
drawCenteredString(minecraft->font, "does not allow saving games", width/2, progressY + 46, 0xffffff);
#endif
// If we're locating the server, show our famous spinner!
bool isLocating = (minecraft->getProgressStatusId() == 0);
if (isLocating) {
const int spinnerX = progressLeft + progressWidth + 6;
static const char* spinnerTexts[] = {"-", "\\", "|", "/"};
int n = ((int)(5.5f * getTimeS()) % 4);
drawCenteredString(minecraft->font, spinnerTexts[n], spinnerX, progressY, 0xffffffff);
}
glDisable2(GL_BLEND);
sleepMs(50);
}
bool ProgressScreen::isInGameScreen() { return false; }
void ProgressScreen::tick() {
// After 10 seconds of not connecting -> write an error message and go back
if (++ticks == 10 * SharedConstants::TicksPerSecond && minecraft->getProgressStatusId() == 0) {
minecraft->setScreen( new DisconnectionScreen("Could not connect to server. Try again.") );
}
}

View File

@@ -0,0 +1,19 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ProgressScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ProgressScreen_H__
#include "../Screen.h"
class ProgressScreen: public Screen
{
public:
ProgressScreen();
void render(int xm, int ym, float a);
bool isInGameScreen();
void tick();
private:
int ticks;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ProgressScreen_H__*/

View File

@@ -0,0 +1,55 @@
#include "RenameMPLevelScreen.h"
#include "StartMenuScreen.h"
#include "DialogDefinitions.h"
#include "../Gui.h"
#include "../../Minecraft.h"
#include "../../../AppPlatform.h"
#include "../../../platform/log.h"
#include "../../../world/level/storage/LevelStorageSource.h"
static char ILLEGAL_FILE_CHARACTERS[] = {
'/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':'
};
RenameMPLevelScreen::RenameMPLevelScreen( const std::string& levelId )
: _levelId(levelId)
{
}
void RenameMPLevelScreen::init() {
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_RENAME_MP_WORLD);
}
void RenameMPLevelScreen::render(int xm, int ym, float a)
{
renderBackground();
#ifdef WIN32
minecraft->getLevelSource()->renameLevel(_levelId, "Save?Level");
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
#else
int status = minecraft->platform()->getUserInputStatus();
if (status > -1) {
if (status == 1) {
std::vector<std::string> v = minecraft->platform()->getUserInput();
if (!v.empty()) {
// Read the level name.
// 1) Trim name 2) Remove all bad chars -) We don't have to getUniqueLevelName, since renameLevel will do that
std::string levelId = v[0];
for (int i = 0; i < sizeof(ILLEGAL_FILE_CHARACTERS) / sizeof(char); ++i)
levelId = Util::stringReplace(levelId, std::string(1, ILLEGAL_FILE_CHARACTERS[i]), "");
if ((int)levelId.length() == 0) {
levelId = "saved_world";
}
minecraft->getLevelSource()->renameLevel(_levelId, levelId);
}
}
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
#endif
}

View File

@@ -0,0 +1,18 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__RenameMPLevelScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__RenameMPLevelScreen_H__
#include "../Screen.h"
class RenameMPLevelScreen: public Screen
{
public:
RenameMPLevelScreen(const std::string& levelId);
virtual void init();
virtual void render(int xm, int ym, float a);
private:
std::string _levelId;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__RenameMPLevelScreen_H__*/

View File

@@ -0,0 +1,56 @@
#include "ScreenChooser.h"
#include "StartMenuScreen.h"
#include "SelectWorldScreen.h"
#include "JoinGameScreen.h"
#include "PauseScreen.h"
#include "RenameMPLevelScreen.h"
#include "IngameBlockSelectionScreen.h"
#include "touch/TouchStartMenuScreen.h"
#include "touch/TouchSelectWorldScreen.h"
#include "touch/TouchJoinGameScreen.h"
#include "touch/TouchIngameBlockSelectionScreen.h"
#include "../../Minecraft.h"
Screen* ScreenChooser::createScreen( ScreenId id )
{
Screen* screen = NULL;
if (_mc->useTouchscreen()) {
switch (id) {
case SCREEN_STARTMENU: screen = new Touch::StartMenuScreen(); break;
case SCREEN_SELECTWORLD:screen = new Touch::SelectWorldScreen();break;
case SCREEN_JOINGAME: screen = new Touch::JoinGameScreen(); break;
case SCREEN_PAUSE: screen = new PauseScreen(false); break;
case SCREEN_PAUSEPREV: screen = new PauseScreen(true); break;
case SCREEN_BLOCKSELECTION: screen = new Touch::IngameBlockSelectionScreen(); break;
case SCREEN_NONE:
default:
// Do nothing
break;
}
} else {
switch (id) {
case SCREEN_STARTMENU: screen = new StartMenuScreen(); break;
case SCREEN_SELECTWORLD:screen = new SelectWorldScreen();break;
case SCREEN_JOINGAME: screen = new JoinGameScreen(); break;
case SCREEN_PAUSE: screen = new PauseScreen(false); break;
case SCREEN_PAUSEPREV: screen = new PauseScreen(true); break;
case SCREEN_BLOCKSELECTION: screen = new IngameBlockSelectionScreen(); break;
case SCREEN_NONE:
default:
// Do nothing
break;
}
}
return screen;
}
Screen* ScreenChooser::setScreen(ScreenId id)
{
Screen* screen = createScreen(id);
_mc->setScreen(screen);
return screen;
}

View File

@@ -0,0 +1,30 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__ScreenChooser_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__ScreenChooser_H__
enum ScreenId {
SCREEN_NONE,
SCREEN_STARTMENU,
SCREEN_JOINGAME,
SCREEN_PAUSE,
SCREEN_PAUSEPREV,
SCREEN_SELECTWORLD,
SCREEN_BLOCKSELECTION
};
class Screen;
class Minecraft;
class ScreenChooser
{
public:
ScreenChooser(Minecraft* mc)
: _mc(mc)
{}
Screen* createScreen(ScreenId id);
Screen* setScreen(ScreenId id);
private:
Minecraft* _mc;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__ScreenChooser_H__*/

View File

@@ -0,0 +1,507 @@
#include "SelectWorldScreen.h"
#include "StartMenuScreen.h"
#include "ProgressScreen.h"
#include "DialogDefinitions.h"
#include "../../renderer/Tesselator.h"
#include "../../../AppPlatform.h"
#include "../../../util/StringUtils.h"
#include "../../../util/Mth.h"
#include "../../../platform/input/Mouse.h"
#include "../../../Performance.h"
#include "../../../world/level/LevelSettings.h"
#include <algorithm>
#include <set>
#include "../../renderer/Textures.h"
#include "SimpleChooseLevelScreen.h"
static float Max(float a, float b) {
return a>b? a : b;
}
//
// World Selection List
//
WorldSelectionList::WorldSelectionList( Minecraft* minecraft, int width, int height )
: _height(height),
hasPickedLevel(false),
currentTick(0),
stoppedTick(-1),
mode(0),
RolledSelectionListH(minecraft, width, height, 0, width, 26, height-32, 120)
{
}
int WorldSelectionList::getNumberOfItems() {
return (int)levels.size();
}
void WorldSelectionList::selectItem( int item, bool doubleClick ) {
//LOGI("sel: %d, item %d\n", selectedItem, item);
if (selectedItem < 0 || (selectedItem != item))
return;
if (!hasPickedLevel) {
hasPickedLevel = true;
pickedLevel = levels[item];
}
}
bool WorldSelectionList::isSelectedItem( int item ) {
return item == selectedItem;
}
void WorldSelectionList::renderItem( int i, int x, int y, int h, Tesselator& t ) {
int centerx = x + itemWidth/2;
float a0 = Max(1.1f - std::abs( width / 2 - centerx ) * 0.0055f, 0.2f);
if (a0 > 1) a0 = 1;
int textColor = (int)(255.0f * a0) * 0x010101;
int textColor2 = (int)(140.0f * a0) * 0x010101;
const int TY = y + 42;
const int TX = centerx - itemWidth / 2 + 5;
StringVector v = _descriptions[i];
drawString(minecraft->font, v[0].c_str(), TX, TY + 0, textColor);
drawString(minecraft->font, v[1].c_str(), TX, TY + 10, textColor2);
drawString(minecraft->font, v[2].c_str(), TX, TY + 20, textColor2);
drawString(minecraft->font, v[3].c_str(), TX, TY + 30, textColor2);
minecraft->textures->loadAndBindTexture(_imageNames[i]);
t.color(0.3f, 1.0f, 0.2f);
//float x0 = (float)x;
//float x1 = (float)x + (float)itemWidth;
const float IY = (float)y - 8;
t.begin();
t.color(textColor);
t.vertexUV((float)(centerx-32), IY, blitOffset, 0, 0);
t.vertexUV((float)(centerx-32), IY + 48, blitOffset, 0, 1);
t.vertexUV((float)(centerx+32), IY + 48, blitOffset, 1, 1);
t.vertexUV((float)(centerx+32), IY, blitOffset, 1, 0);
t.draw();
}
void WorldSelectionList::stepLeft() {
if (selectedItem > 0) {
td.start = xo;
td.stop = xo - itemWidth;
td.cur = 0;
td.dur = 8;
mode = 1;
tweenInited();
}
}
void WorldSelectionList::stepRight() {
if (selectedItem >= 0 && selectedItem < getNumberOfItems()-1) {
td.start = xo;
td.stop = xo + itemWidth;
td.cur = 0;
td.dur = 8;
mode = 1;
tweenInited();
}
}
void WorldSelectionList::commit() {
for (unsigned int i = 0; i < levels.size(); ++i) {
LevelSummary& level = levels[i];
std::stringstream ss;
ss << level.name << "/preview.png";
TextureId id = Textures::InvalidId;//minecraft->textures->loadTexture(ss.str(), false);
if (id != Textures::InvalidId) {
_imageNames.push_back( ss.str() );
} else {
_imageNames.push_back("gui/default_world.png");
}
StringVector lines;
lines.push_back(level.name);
lines.push_back(minecraft->platform()->getDateString(level.lastPlayed));
lines.push_back(level.id);
lines.push_back(LevelSettings::gameTypeToString(level.gameType));
_descriptions.push_back(lines);
selectedItem = 0;
}
}
static float quadraticInOut(float t, float dur, float start, float stop) {
const float delta = stop - start;
const float T = (t / dur) * 2.0f;
if (T < 1) return 0.5f*delta*T*T + start;
return -0.5f*delta * ((T-1)*(T-3) - 1) + start;
}
void WorldSelectionList::tick()
{
RolledSelectionListH::tick();
++currentTick;
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT) || dragState == 0)
return;
// Handle the tween (when in "mode 1")
selectedItem = -1;
if (mode == 1) {
if (++td.cur == td.dur) {
mode = 0;
xInertia = 0;
xoo = xo = td.stop;
selectedItem = getItemAtPosition(width/2, height/2);
} else {
tweenInited();
}
return;
}
// It's still going fast, let it run
float speed = Mth::abs(xInertia);
bool slowEnoughToBeBothered = speed < 5.0f;
if (!slowEnoughToBeBothered) {
xInertia = xInertia * .9f;
return;
}
xInertia *= 0.8f;
if (speed < 1 && dragState < 0) {
const int offsetx = (width-itemWidth) / 2;
const float pxo = xo + offsetx;
int index = getItemAtXPositionRaw((int)(pxo - 10*xInertia));
int indexPos = index*itemWidth;
// Pick closest
float diff = (float)indexPos - pxo;
if (diff < -itemWidth/2) {
diff += itemWidth;
index++;
//indexPos += itemWidth;
}
if (Mth::abs(diff) < 1 && speed < 0.1f) {
selectedItem = getItemAtPosition(width/2, height/2);
return;
}
td.start = xo;
td.stop = xo + diff;
td.cur = 0;
td.dur = (float) Mth::Min(7, 1 + (int)(Mth::abs(diff) * 0.25f));
mode = 1;
//LOGI("inited-t %d\n", dragState);
tweenInited();
}
}
float WorldSelectionList::getPos( float alpha )
{
if (mode != 1) return RolledSelectionListH::getPos(alpha);
float x0 = quadraticInOut(td.cur, td.dur, td.start, td.stop);
float x1 = quadraticInOut(td.cur+1, td.dur, td.start, td.stop);
return x0 + (x1-x0)*alpha;
}
bool WorldSelectionList::capXPosition() {
bool capped = RolledSelectionListH::capXPosition();
if (capped) mode = 0;
return capped;
}
void WorldSelectionList::tweenInited() {
float x0 = quadraticInOut(td.cur, td.dur, td.start, td.stop);
float x1 = quadraticInOut(td.cur+1, td.dur, td.start, td.stop);
xInertia = x0-x1; // yes, it's all backwards and messed up..
}
//
// Select World Screen
//
SelectWorldScreen::SelectWorldScreen()
: bDelete (1, "Delete"),
bCreate (2, "Create new"),
bBack (3, "Back"),
bWorldView(4, ""),
worldsList(NULL),
_state(_STATE_DEFAULT),
_hasStartedLevel(false)
{
bDelete.active = false;
}
SelectWorldScreen::~SelectWorldScreen()
{
delete worldsList;
}
void SelectWorldScreen::buttonClicked(Button* button)
{
if (button->id == bCreate.id) {
//minecraft->setScreen( new CreateWorldScreen() );
//minecraft->locateMultiplayer();
//minecraft->setScreen(new JoinGameScreen());
//minecraft->hostMultiplayer();
//minecraft->setScreen(new ProgressScreen());
if (_state == _STATE_DEFAULT && !_hasStartedLevel) {
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_CREATE_NEW_WORLD);
_state = _STATE_CREATEWORLD;
}
}
if (button->id == bDelete.id) {
if (isIndexValid(worldsList->selectedItem)) {
LevelSummary level = worldsList->levels[worldsList->selectedItem];
LOGI("level: %s, %s\n", level.id.c_str(), level.name.c_str());
minecraft->setScreen( new DeleteWorldScreen(level) );
}
}
if (button->id == bBack.id) {
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
if (button->id == bWorldView.id) {
// Try to "click" the item in the middle
worldsList->selectItem( worldsList->getItemAtPosition(width/2, height/2), false );
}
}
bool SelectWorldScreen::handleBackEvent(bool isDown)
{
if (!isDown)
{
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
return true;
}
bool SelectWorldScreen::isIndexValid( int index )
{
return worldsList && index >= 0 && index < worldsList->getNumberOfItems();
}
static char ILLEGAL_FILE_CHARACTERS[] = {
'/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':'
};
void SelectWorldScreen::tick()
{
if (_state == _STATE_CREATEWORLD) {
#if defined(RPI)
std::string levelId = getUniqueLevelName("world");
LevelSettings settings(getEpochTimeS(), GameType::Creative);
minecraft->selectLevel(levelId, levelId, settings);
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
_hasStartedLevel = true;
#elif defined(WIN32)
std::string name = getUniqueLevelName("perf");
minecraft->setScreen(new SimpleChooseLevelScreen(name));
#else
int status = minecraft->platform()->getUserInputStatus();
if (status > -1) {
if (status == 1) {
StringVector sv = minecraft->platform()->getUserInput();
// Read the level name.
// 1) Trim name 2) Remove all bad chars 3) Append '-' chars 'til the name is unique
std::string levelName = Util::stringTrim(sv[0]);
std::string levelId = levelName;
for (int i = 0; i < sizeof(ILLEGAL_FILE_CHARACTERS) / sizeof(char); ++i)
levelId = Util::stringReplace(levelId, std::string(1, ILLEGAL_FILE_CHARACTERS[i]), "");
if ((int)levelId.length() == 0) {
levelId = "no_name";
}
levelId = getUniqueLevelName(levelId);
// Read the seed
int seed = getEpochTimeS();
if (sv.size() >= 2) {
std::string seedString = Util::stringTrim(sv[1]);
if (seedString.length() > 0) {
int tmpSeed;
// Try to read it as an integer
if (sscanf(seedString.c_str(), "%d", &tmpSeed) > 0) {
seed = tmpSeed;
} // Hash the "seed"
else {
seed = Util::hashCode(seedString);
}
}
}
// Read the game mode
bool isCreative = true;
if (sv.size() >= 3 && sv[2] == "survival")
isCreative = false;
// Start a new level with the given name and seed
LevelSettings settings(seed, isCreative? GameType::Creative : GameType::Survival);
LOGI("Creating a level with id '%s', name '%s' and seed '%d'\n", levelId.c_str(), levelName.c_str(), seed);
minecraft->selectLevel(levelId, levelName, settings);
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
_hasStartedLevel = true;
}
_state = _STATE_DEFAULT;
}
#endif
return;
}
worldsList->tick();
if (worldsList->hasPickedLevel) {
minecraft->selectLevel(worldsList->pickedLevel.id, worldsList->pickedLevel.name, LevelSettings::None());
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
_hasStartedLevel = true;
return;
}
// copy the currently selected item
LevelSummary selectedWorld;
//bool hasSelection = false;
if (isIndexValid(worldsList->selectedItem))
{
selectedWorld = worldsList->levels[worldsList->selectedItem];
//hasSelection = true;
}
bDelete.active = isIndexValid(worldsList->selectedItem);
}
void SelectWorldScreen::init()
{
worldsList = new WorldSelectionList(minecraft, width, height);
loadLevelSource();
worldsList->commit();
buttons.push_back(&bDelete);
buttons.push_back(&bCreate);
buttons.push_back(&bBack);
_mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
tabButtons.push_back(&bWorldView);
tabButtons.push_back(&bDelete);
tabButtons.push_back(&bCreate);
tabButtons.push_back(&bBack);
}
void SelectWorldScreen::setupPositions() {
int yBase = height - 28;
//#ifdef ANDROID
bCreate.y = yBase;
bBack.y = yBase;
bDelete.y = yBase;
bBack.width = bDelete.width = bCreate.width = 84;
//bDelete.h = bCreate.h = bBack.h = 24;
//#endif
// Center buttons
bDelete.x = width / 2 - 4 - bDelete.width - bDelete.width / 2;
bCreate.x = width / 2 - bCreate.width / 2;
bBack.x = width / 2 + 4 + bCreate.width - bBack.width / 2;
}
void SelectWorldScreen::render( int xm, int ym, float a )
{
//Performance::watches.get("sws-full").start();
//Performance::watches.get("sws-renderbg").start();
renderBackground();
//Performance::watches.get("sws-renderbg").stop();
//Performance::watches.get("sws-worlds").start();
worldsList->setComponentSelected(bWorldView.selected);
if (_mouseHasBeenUp)
worldsList->render(xm, ym, a);
else {
worldsList->render(0, 0, a);
_mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
}
//Performance::watches.get("sws-worlds").stop();
//Performance::watches.get("sws-screen").start();
Screen::render(xm, ym, a);
//Performance::watches.get("sws-screen").stop();
//Performance::watches.get("sws-string").start();
drawCenteredString(minecraft->font, "Select world", width / 2, 8, 0xffffffff);
//Performance::watches.get("sws-string").stop();
//Performance::watches.get("sws-full").stop();
//Performance::watches.printEvery(128);
}
void SelectWorldScreen::loadLevelSource()
{
LevelStorageSource* levelSource = minecraft->getLevelSource();
levelSource->getLevelList(levels);
std::sort(levels.begin(), levels.end());
for (unsigned int i = 0; i < levels.size(); ++i) {
if (levels[i].id != LevelStorageSource::TempLevelId)
worldsList->levels.push_back( levels[i] );
}
}
std::string SelectWorldScreen::getUniqueLevelName( const std::string& level )
{
std::set<std::string> Set;
for (unsigned int i = 0; i < levels.size(); ++i)
Set.insert(levels[i].id);
std::string s = level;
while ( Set.find(s) != Set.end() )
s += "-";
return s;
}
bool SelectWorldScreen::isInGameScreen() { return true; }
void SelectWorldScreen::keyPressed( int eventKey )
{
if (bWorldView.selected) {
if (eventKey == minecraft->options.keyLeft.key)
worldsList->stepLeft();
if (eventKey == minecraft->options.keyRight.key)
worldsList->stepRight();
}
Screen::keyPressed(eventKey);
}
//
// Delete World Screen
//
DeleteWorldScreen::DeleteWorldScreen(const LevelSummary& level)
: ConfirmScreen(NULL, "Are you sure you want to delete this world?",
"'" + level.name + "' will be lost forever!",
"Delete", "Cancel", 0),
_level(level)
{
tabButtonIndex = 1;
}
void DeleteWorldScreen::postResult( bool isOk )
{
if (isOk) {
LevelStorageSource* storageSource = minecraft->getLevelSource();
storageSource->deleteLevel(_level.id);
}
minecraft->screenChooser.setScreen(SCREEN_SELECTWORLD);
}

View File

@@ -0,0 +1,113 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__SelectWorldScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__SelectWorldScreen_H__
#include "../Screen.h"
#include "../TweenData.h"
#include "../components/Button.h"
#include "../components/SmallButton.h"
#include "../components/RolledSelectionListH.h"
#include "../../Minecraft.h"
#include "../../../world/level/storage/LevelStorageSource.h"
class SelectWorldScreen;
//
// Scrolling World selection list
//
class WorldSelectionList : public RolledSelectionListH
{
public:
WorldSelectionList(Minecraft* _minecraft, int _width, int _height);
virtual void tick();
void stepLeft();
void stepRight();
void commit();
protected:
virtual int getNumberOfItems();
virtual void selectItem(int item, bool doubleClick);
virtual bool isSelectedItem(int item);
virtual void renderBackground() {}
virtual void renderItem(int i, int x, int y, int h, Tesselator& t);
virtual float getPos(float alpha);
virtual void touched() { mode = 0; }
virtual bool capXPosition();
private:
TweenData td;
void tweenInited();
int selectedItem;
int _height;
LevelSummaryList levels;
std::vector<StringVector> _descriptions;
StringVector _imageNames;
bool hasPickedLevel;
LevelSummary pickedLevel;
int stoppedTick;
int currentTick;
float accRatio;
int mode;
friend class SelectWorldScreen;
};
//
// Delete World screen
//
#include "ConfirmScreen.h"
class DeleteWorldScreen: public ConfirmScreen
{
public:
DeleteWorldScreen(const LevelSummary& levelId);
protected:
virtual void postResult(bool isOk);
private:
LevelSummary _level;
};
//
// Select world screen
//
class SelectWorldScreen: public Screen
{
public:
SelectWorldScreen();
virtual ~SelectWorldScreen();
virtual void init();
virtual void setupPositions();
virtual void tick();
virtual bool isIndexValid(int index);
virtual bool handleBackEvent(bool isDown);
virtual void buttonClicked(Button* button);
virtual void keyPressed(int eventKey);
void render(int xm, int ym, float a);
bool isInGameScreen();
private:
void loadLevelSource();
std::string getUniqueLevelName(const std::string& level);
Button bDelete;
Button bCreate;
Button bBack;
Button bWorldView;
WorldSelectionList* worldsList;
LevelSummaryList levels;
bool _mouseHasBeenUp;
bool _hasStartedLevel;
int _state;
static const int _STATE_DEFAULT = 0;
static const int _STATE_CREATEWORLD = 1;
//LevelStorageSource* levels;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__SelectWorldScreen_H__*/

View File

@@ -0,0 +1,97 @@
#include "SimpleChooseLevelScreen.h"
#include "ProgressScreen.h"
#include "ScreenChooser.h"
#include "../components/Button.h"
#include "../../Minecraft.h"
#include "../../../world/level/LevelSettings.h"
#include "../../../platform/time.h"
SimpleChooseLevelScreen::SimpleChooseLevelScreen(const std::string& levelName)
: bCreative(0),
bSurvival(0),
bBack(0),
levelName(levelName),
hasChosen(false)
{
}
SimpleChooseLevelScreen::~SimpleChooseLevelScreen()
{
delete bCreative;
delete bSurvival;
delete bBack;
}
void SimpleChooseLevelScreen::init()
{
if (minecraft->useTouchscreen()) {
bCreative = new Touch::TButton(1, "Creative mode");
bSurvival = new Touch::TButton(2, "Survival mode");
bBack = new Touch::TButton(3, "Back");
} else {
bCreative = new Button(1, "Creative mode");
bSurvival = new Button(2, "Survival mode");
bBack = new Button(3, "Back");
}
buttons.push_back(bCreative);
buttons.push_back(bSurvival);
buttons.push_back(bBack);
tabButtons.push_back(bCreative);
tabButtons.push_back(bSurvival);
tabButtons.push_back(bBack);
}
void SimpleChooseLevelScreen::setupPositions()
{
bCreative->width = bSurvival->width = bBack->width = 120;
bCreative->x = (width - bCreative->width) / 2;
bCreative->y = height/3 - 40;
bSurvival->x = (width - bSurvival->width) / 2;
bSurvival->y = 2*height/3 - 40;
bBack->x = bSurvival->x + bSurvival->width - bBack->width;
bBack->y = height - 40;
}
void SimpleChooseLevelScreen::render( int xm, int ym, float a )
{
renderDirtBackground(0);
glEnable2(GL_BLEND);
drawCenteredString(minecraft->font, "Mobs, health and gather resources", width/2, bSurvival->y + bSurvival->height + 4, 0xffcccccc);
drawCenteredString(minecraft->font, "Unlimited resources and flying", width/2, bCreative->y + bCreative->height + 4, 0xffcccccc);
Screen::render(xm, ym, a);
glDisable2(GL_BLEND);
}
void SimpleChooseLevelScreen::buttonClicked( Button* button )
{
if (button == bBack) {
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
return;
}
if (hasChosen)
return;
int gameType;
if (button == bCreative)
gameType = GameType::Creative;
if (button == bSurvival)
gameType = GameType::Survival;
std::string levelId = getUniqueLevelName(levelName);
LevelSettings settings(getEpochTimeS(), gameType);
minecraft->selectLevel(levelId, levelId, settings);
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
hasChosen = true;
}
bool SimpleChooseLevelScreen::handleBackEvent(bool isDown) {
if (!isDown)
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
return true;
}

View File

@@ -0,0 +1,32 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__
#include "ChooseLevelScreen.h"
class Button;
class SimpleChooseLevelScreen: public ChooseLevelScreen
{
public:
SimpleChooseLevelScreen(const std::string& levelName);
virtual ~SimpleChooseLevelScreen();
void init();
void setupPositions();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
bool handleBackEvent(bool isDown);
private:
Button* bCreative;
Button* bSurvival;
Button* bBack;
bool hasChosen;
std::string levelName;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__DemoChooseLevelScreen_H__*/

View File

@@ -0,0 +1,208 @@
#include "StartMenuScreen.h"
#include "SelectWorldScreen.h"
#include "ProgressScreen.h"
#include "JoinGameScreen.h"
#include "OptionsScreen.h"
#include "PauseScreen.h"
#include "InvalidLicenseScreen.h"
#include "PrerenderTilesScreen.h" // test button
//#include "BuyGameScreen.h"
#include "../../../util/Mth.h"
#include "../Font.h"
#include "../components/SmallButton.h"
#include "../components/ScrolledSelectionList.h"
#include "../../Minecraft.h"
#include "../../renderer/Tesselator.h"
#include "../../../AppPlatform.h"
#include "../../../LicenseCodes.h"
#include "SimpleChooseLevelScreen.h"
#include "../../renderer/Textures.h"
#include "../../../SharedConstants.h"
// Some kind of default settings, might be overridden in ::init
StartMenuScreen::StartMenuScreen()
: bHost( 2, 0, 0, 160, 24, "Start Game"),
bJoin( 3, 0, 0, 160, 24, "Join Game"),
bOptions( 4, 0, 0, 78, 22, "Options"),
bBuy( 5, 0, 0, 78, 22, "Buy"),
bTest( 999, 0, 0, 78, 22, "Create")
{
}
StartMenuScreen::~StartMenuScreen()
{
}
void StartMenuScreen::init()
{
buttons.push_back(&bHost);
buttons.push_back(&bJoin);
//buttons.push_back(&bTest);
tabButtons.push_back(&bHost);
tabButtons.push_back(&bJoin);
#ifndef RPI
buttons.push_back(&bOptions);
tabButtons.push_back(&bOptions);
#endif
#ifdef DEMO_MODE
buttons.push_back(&bBuy);
tabButtons.push_back(&bBuy);
#endif
copyright = "\xffMojang AB";//. Do not distribute!";
#ifdef PRE_ANDROID23
std::string versionString = Common::getGameVersionString("j");
#else
std::string versionString = Common::getGameVersionString();
#endif
#ifdef DEMO_MODE
#ifdef __APPLE__
version = versionString + " (Lite)";
#else
version = versionString + " (Demo)";
#endif
#else
#ifdef RPI
version = "v0.1.1 alpha";//(MCPE " + versionString + " compatible)";
#else
version = versionString;
#endif
#endif
bJoin.active = bHost.active = bOptions.active = false;
}
void StartMenuScreen::setupPositions() {
int yBase = height / 2 + 25;
//#ifdef ANDROID
bHost.y = yBase - 28;
#ifdef RPI
bJoin.y = yBase + 4;
#else
bJoin.y = yBase;
#endif
bOptions.y = yBase + 28 + 2;
bTest.y = bBuy.y = bOptions.y;
//#endif
// Center buttons
bHost.x = (width - bHost.width) / 2;
bJoin.x = (width - bJoin.width) / 2;
bOptions.x = (width - bJoin.width) / 2;
bTest.x = bBuy.x = bOptions.x + bOptions.width + 4;
copyrightPosX = width - minecraft->font->width(copyright) - 1;
versionPosX = (width - minecraft->font->width(version)) / 2;// - minecraft->font->width(version) - 2;
}
void StartMenuScreen::tick() {
_updateLicense();
}
void StartMenuScreen::buttonClicked(Button* button) {
if (button->id == bHost.id)
{
#if defined(DEMO_MODE) || defined(APPLE_DEMO_PROMOTION)
minecraft->setScreen( new SimpleChooseLevelScreen("_DemoLevel") );
#else
minecraft->screenChooser.setScreen(SCREEN_SELECTWORLD);
#endif
}
if (button->id == bJoin.id)
{
minecraft->locateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_JOINGAME);
}
if (button->id == bOptions.id)
{
minecraft->setScreen(new OptionsScreen());
}
if (button->id == bTest.id)
{
//minecraft->setScreen(new PauseScreen());
//minecraft->setScreen(new PrerenderTilesScreen());
}
if (button->id == bBuy.id)
{
minecraft->platform()->buyGame();
//minecraft->setScreen(new BuyGameScreen());
}
}
bool StartMenuScreen::isInGameScreen() { return false; }
void StartMenuScreen::render( int xm, int ym, float a )
{
renderBackground();
#if defined(RPI)
TextureId id = minecraft->textures->loadTexture("gui/pi_title.png");
#else
TextureId id = minecraft->textures->loadTexture("gui/title.png");
#endif
const TextureData* data = minecraft->textures->getTemporaryTextureData(id);
if (data) {
minecraft->textures->bind(id);
const float x = (float)width / 2;
const float y = 4;
//const float scale = Mth::Min(
const float wh = Mth::Min((float)width/2.0f, (float)data->w / 2);
const float scale = 2.0f * wh / (float)data->w;
const float h = scale * (float)data->h;
// Render title text
Tesselator& t = Tesselator::instance;
glColor4f2(1, 1, 1, 1);
t.begin();
t.vertexUV(x-wh, y+h, blitOffset, 0, 1);
t.vertexUV(x+wh, y+h, blitOffset, 1, 1);
t.vertexUV(x+wh, y+0, blitOffset, 1, 0);
t.vertexUV(x-wh, y+0, blitOffset, 0, 0);
t.draw();
}
#if defined(RPI)
if (Textures::isTextureIdValid(minecraft->textures->loadAndBindTexture("gui/logo/raknet_high_72.png")))
blit(0, height - 12, 0, 0, 43, 12, 256, 72+72);
#endif
drawString(font, version, versionPosX, 62, /*50,*/ 0xffcccccc);//0x666666);
drawString(font, copyright, copyrightPosX, height - 10, 0xffffff);
Screen::render(xm, ym, a);
}
void StartMenuScreen::_updateLicense()
{
int id = minecraft->getLicenseId();
if (LicenseCodes::isReady(id))
{
if (LicenseCodes::isOk(id))
bJoin.active = bHost.active = bOptions.active = true;
else
{
bool hasBuyButton = minecraft->platform()->hasBuyButtonWhenInvalidLicense();
minecraft->setScreen(new InvalidLicenseScreen(id, hasBuyButton));
}
} else {
bJoin.active = bHost.active = bOptions.active = false;
}
}
bool StartMenuScreen::handleBackEvent( bool isDown ) {
minecraft->quit();
return true;
}

View File

@@ -0,0 +1,38 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__StartMenuScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__StartMenuScreen_H__
#include "../Screen.h"
#include "../components/Button.h"
class StartMenuScreen: public Screen
{
public:
StartMenuScreen();
virtual ~StartMenuScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
bool handleBackEvent(bool isDown);
bool isInGameScreen();
private:
void _updateLicense();
Button bHost;
Button bJoin;
Button bOptions;
Button bTest;
Button bBuy;
std::string copyright;
int copyrightPosX;
std::string version;
int versionPosX;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__StartMenuScreen_H__*/

View File

@@ -0,0 +1,146 @@
#include "TextEditScreen.h"
#include "../../../world/level/tile/entity/SignTileEntity.h"
#include "../../../AppPlatform.h"
#include "../../Minecraft.h"
#include "../../renderer/tileentity/TileEntityRenderDispatcher.h"
#include "../../renderer/Tesselator.h"
#include "../../renderer/Textures.h"
#include "../../renderer/GameRenderer.h"
#include "../components/Button.h"
#include "../../../network/Packet.h"
#include "../../../network/RakNetInstance.h"
TextEditScreen::TextEditScreen( SignTileEntity* signEntity )
: sign(signEntity), isShowingKeyboard(false), frame(0), line(0), btnClose(1, "") {
}
TextEditScreen::~TextEditScreen() {
}
void TextEditScreen::init() {
super::init();
minecraft->platform()->showKeyboard();
isShowingKeyboard = true;
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
btnClose.setImageDef(def, true);
btnClose.scaleWhenPressed = false;
buttons.push_back(&btnClose);
}
void TextEditScreen::setupPositions() {
btnClose.width = btnClose.height = 19;
btnClose.x = width - btnClose.width;
btnClose.y = 0;
}
bool TextEditScreen::handleBackEvent( bool isDown ) {
sign->setChanged();
Packet* signUpdatePacket = sign->getUpdatePacket();
minecraft->raknetInstance->send(signUpdatePacket);
minecraft->platform()->hideKeyboard();
minecraft->setScreen(NULL);
return true;
}
void TextEditScreen::render( int xm, int ym, float a ) {
glDepthMask(GL_FALSE);
renderBackground();
glPushMatrix();
glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
glLoadIdentity();
Tesselator& t = Tesselator::instance;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrthof(0.0f, (float)minecraft->width, (float)minecraft->height, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
minecraft->textures->loadAndBindTexture("item/sign.png");
glColor4f2(1, 1, 1, 1);
static float minUV[] = {0.03126f, 0.06249f};
static float maxUV[] = {0.39063f, 0.4374f};
float scale = ((minecraft->height / 2) / 32) * 0.9f;
glTranslatef(minecraft->width / 2.0f, 5.0f, 0.0f);
glScalef2(scale,scale,1);
t.begin(GL_QUADS);
t.vertexUV(-32, 0, 0.0f,minUV[0],minUV[1]);
t.vertexUV(32, 0, 0.0f, maxUV[0], minUV[1]);
t.vertexUV(32, 0 + 32, 0.0f, maxUV[0], maxUV[1]);
t.vertexUV(-32, 0 + 32, 0.0f, minUV[0], maxUV[1]);
t.draw();
sign->selectedLine = line;
float textScale = 8.0f / 11.0f;
glTranslatef(0, 2 ,0);
glScalef2(textScale, textScale, 1);
for(int i = 0; i < 4; ++i) {
//drawCenteredString(font, sign->messages[a], 32.0f, 10 * a, 0xFF000000);
std::string msg = sign->messages[i];
if (i == sign->selectedLine && msg.length() < 14) {
std::string s = "> " + msg + " <";
font->draw(s, -(float)font->width(s) / 2.0f, 10.0f * i, 0xFF000000, false);
} else {
font->draw(msg, -(float)font->width(msg) / 2.0f, 10.0f * i, 0xFF000000, false);
}
}
sign->selectedLine = -1;
//font->draw("Hej", minecraft->width / 2, 100, 0xFFFFFFFF, false);
glPopMatrix();
glEnable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
//glEnable(GL_DEPTH_TEST);
super::render(xm, ym, a);
}
void TextEditScreen::lostFocus() {
}
void TextEditScreen::tick() {
frame++;
}
void TextEditScreen::keyPressed( int eventKey ) {
LOGW("Key pressed! [%d]", eventKey);
if(eventKey == Keyboard::KEY_BACKSPACE) {
if(sign->messages[line].length() > 0) {
sign->messages[line].erase(sign->messages[line].size() - 1, 1);
} else {
line--;
if(line < 0) {
line = 3;
}
}
} else if(eventKey == Keyboard::KEY_RETURN) {
line = (line + 1) % 4;
} else {
super::keyPressed(eventKey);
}
}
void TextEditScreen::keyboardNewChar( char inputChar ) {
std::string fullstring = sign->messages[line] + inputChar;
if(fullstring.length() < 16) {
sign->messages[line] = fullstring;
//LOGW("Line text updated: %s\n", fullstring.c_str());
}
}
void TextEditScreen::buttonClicked( Button* button ) {
if(button == &btnClose)
handleBackEvent(true);
}

View File

@@ -0,0 +1,35 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__TextEditScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__TextEditScreen_H__
//package net.minecraft.client.gui;
#include "../Screen.h"
#include <string>
#include "../components/ImageButton.h"
class SignTileEntity;
class Button;
class TextEditScreen: public Screen
{
typedef Screen super;
public:
TextEditScreen(SignTileEntity* signEntity);
~TextEditScreen();
void init();
void tick();
bool handleBackEvent(bool isDown);
void render(int xm, int ym, float a);
virtual void lostFocus();
virtual void keyPressed(int eventKey);
virtual void keyboardNewChar(char inputChar);
void setupPositions();
void buttonClicked(Button* button);
protected:
bool isShowingKeyboard;
SignTileEntity* sign;
int frame;
int line;
private:
ImageButton btnClose;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__TextEditScreen_H__*/

View File

@@ -0,0 +1,177 @@
#if 0
#include "UploadPhotoScreen.h"
#include "../renderer/TileRenderer.h"
#include "../player/LocalPlayer.h"
#include "../../world/entity/player/Inventory.h"
UploadPhotoScreen::UploadPhotoScreen()
:
selectedItem(0)
{
}
void UploadPhotoScreen::init()
{
int currentSelection = minecraft->player->inventory->getSelectedItemId();
for (int i = 0; i < Inventory::INVENTORY_SIZE; i++)
{
if (currentSelection == minecraft->player->inventory->getSelectionSlotItemId(i + Inventory::SELECTION_SIZE))
{
selectedItem = i;
break;
}
}
}
void UploadPhotoScreen::renderSlots()
{
glColor4f2(1, 1, 1, 1);
blitOffset = -90;
minecraft->textures->loadAndBindTexture("gui/gui.png");
for (int r = 0; r < Inventory::INVENTORY_ROWS; r++)
{
blit(width / 2 - 182 / 2, height - 22 * 3 - 22 * r, 0, 0, 182, 22);
}
if (selectedItem >= 0)
{
int x = width / 2 - 182 / 2 - 1 + (selectedItem % Inventory::SELECTION_SIZE) * 20;
int y = height - 22 * 3 - 1 - (selectedItem / Inventory::SELECTION_SIZE) * 22;
blit(x, y, 0, 22, 24, 22);
}
for (int r = 0; r < Inventory::INVENTORY_ROWS; r++)
{
for (int i = 0; i < 9; i++) {
int x = width / 2 - 9 * 10 + i * 20 + 2;
int y = height - 16 - 3 - 22 * 2 - 22 * r;
renderSlot(r * 9 + i + Inventory::SELECTION_SIZE, x, y, 0);
}
}
}
void UploadPhotoScreen::renderSlot(int slot, int x, int y, float a)
{
int itemId = minecraft->player->inventory->getSelectionSlotItemId(slot);
if (itemId < 0) return;
const bool fancy = false;
if (fancy && itemId < 256 && TileRenderer::canRender(Tile::tiles[itemId]->getRenderShape())) {
} else {
if (itemId < 256) {
Tile* tile = Tile::tiles[itemId];
if (tile == NULL) return;
minecraft->textures->loadAndBindTexture("terrain.png");
int textureId = tile->getTexture(2, 0);
blit(x, y, textureId % 16 * 16, textureId / 16 * 16, 16, 16);
}
}
}
void UploadPhotoScreen::keyPressed(int eventKey)
{
int selX = selectedItem % Inventory::SELECTION_SIZE;
int selY = selectedItem / Inventory::SELECTION_SIZE;
Options& o = minecraft->options;
if (eventKey == o.keyLeft.key && selX > 0)
{
selectedItem -= 1;
}
else if (eventKey == o.keyRight.key && selX < (Inventory::SELECTION_SIZE - 1))
{
selectedItem += 1;
}
else if (eventKey == o.keyDown.key && selY > 0)
{
selectedItem -= Inventory::SELECTION_SIZE;
}
else if (eventKey == o.keyUp.key && selY < (Inventory::INVENTORY_ROWS - 1))
{
selectedItem += Inventory::SELECTION_SIZE;
}
if (eventKey == o.keyMenuOk.key)
{
selectSlotAndClose();
}
}
int UploadPhotoScreen::getSelectedSlot(int x, int y)
{
int left = 3 + width / 2 - Inventory::SELECTION_SIZE * 10;
int top = height - 16 - 3 - 22 * 2 - 22 * Inventory::INVENTORY_ROWS;
if (x >= left && y >= top)
{
int xSlot = (x - left) / 20;
if (xSlot < Inventory::SELECTION_SIZE)
{
// rows are rendered upsidedown
return xSlot + Inventory::INVENTORY_SIZE - ((y - top) / 22) * Inventory::SELECTION_SIZE;
}
}
return -1;
}
void UploadPhotoScreen::mouseClicked(int x, int y, int buttonNum) {
if (buttonNum == MouseAction::ACTION_LEFT) {
int slot = getSelectedSlot(x, y);
if (slot >= 0 && slot < Inventory::INVENTORY_SIZE)
{
selectedItem = slot;
//minecraft->soundEngine->playUI("random.click", 1, 1);
}
}
}
void UploadPhotoScreen::mouseReleased(int x, int y, int buttonNum)
{
if (buttonNum == MouseAction::ACTION_LEFT) {
int slot = getSelectedSlot(x, y);
if (slot >= 0 && slot < Inventory::INVENTORY_SIZE && slot == selectedItem)
{
selectSlotAndClose();
}
}
}
void UploadPhotoScreen::selectSlotAndClose()
{
Inventory* inventory = minecraft->player->inventory;
int itemId = inventory->getSelectionSlotItemId(selectedItem + Inventory::SELECTION_SIZE);
int i = 0;
for (; i < Inventory::SELECTION_SIZE - 2; i++)
{
if (itemId == inventory->getSelectionSlotItemId(i))
{
break;
}
}
// update selection list
for (; i >= 1; i--)
{
inventory->setSelectionSlotItemId(i, inventory->getSelectionSlotItemId(i - 1));
}
inventory->setSelectionSlotItemId(0, itemId);
inventory->selectSlot(0);
minecraft->soundEngine->playUI("random.click", 1, 1);
minecraft->setScreen(NULL);
}
#endif

View File

@@ -0,0 +1,36 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS__UploadPhotoScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS__UploadPhotoScreen_H__
#include "Screen.h"
class UploadPhotoScreen : public Screen
{
public:
UploadPhotoScreen();
virtual ~UploadPhotoScreen() {}
virtual void init();
void render(int xm, int ym, float a) {
Screen::render(xm, ym, a);
}
protected:
virtual void mouseClicked(int x, int y, int buttonNum);
virtual void mouseReleased(int x, int y, int buttonNum);
virtual void keyPressed(int eventKey);
private:
int selectedItem;
void renderSlots();
void renderSlot(int slot, int x, int y, float a);
int getSelectedSlot(int x, int y);
void selectSlotAndClose();
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS__UploadPhotoScreen_H__*/

View File

@@ -0,0 +1,32 @@
#include "CraftingFilters.h"
#include "../../../../world/item/ItemInstance.h"
#include "../../../../world/item/Item.h"
#include "../../../../world/level/tile/Tile.h"
#include "../../../../world/level/material/Material.h"
#include "../../../../world/level/tile/StoneSlabTile.h"
namespace CraftingFilters {
bool isStonecutterItem(const ItemInstance& ins) {
Item* const item = ins.getItem();
if (item->id < 0 || item->id >= 256)
return false;
Tile* const tile = Tile::tiles[item->id];
if (!tile)
return false;
// Special stone/sand cases
if ( tile == Tile::lapisBlock
|| tile == Tile::furnace
|| tile == Tile::stonecutterBench)
return false;
if (tile == Tile::stoneSlabHalf && ins.getAuxValue() == StoneSlabTile::WOOD_SLAB)
return false;
// Return everything stone or sand
return (tile->material == Material::stone || tile->material == Material::sand);
}
}

View File

@@ -0,0 +1,10 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_CraftingFilters_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_CraftingFilters_H__
class ItemInstance;
namespace CraftingFilters {
bool isStonecutterItem(const ItemInstance& item);
}
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_CraftingFilters_H__*/

View File

@@ -0,0 +1,555 @@
#include "PaneCraftingScreen.h"
#include "../touch/TouchStartMenuScreen.h"
#include "../../Screen.h"
#include "../../components/NinePatch.h"
#include "../../../Minecraft.h"
#include "../../../player/LocalPlayer.h"
#include "../../../renderer/Tesselator.h"
#include "../../../renderer/entity/ItemRenderer.h"
#include "../../../../world/item/Item.h"
#include "../../../../world/item/crafting/Recipes.h"
#include "../../../../world/item/ItemCategory.h"
#include "../../../../world/entity/player/Inventory.h"
#include "../../../../util/StringUtils.h"
#include "../../../../locale/I18n.h"
#include "../../../../world/entity/item/ItemEntity.h"
#include "../../../../world/level/Level.h"
#include "../../../../world/item/DyePowderItem.h"
#include "../../../../world/item/crafting/Recipe.h"
static NinePatchLayer* guiPaneFrame = NULL;
const float BorderPixels = 6.0f;
const int descFrameWidth = 100;
const int rgbActive = 0xfff0f0f0;
const int rgbInactive = 0xc0635558;
const int rgbInactiveShadow = 0xc0aaaaaa;
class CategoryButton: public ImageButton {
typedef ImageButton super;
public:
CategoryButton(int id, const ImageButton* const* selectedPtr, NinePatchLayer* stateNormal, NinePatchLayer* statePressed)
: super(id, ""),
selectedPtr(selectedPtr),
stateNormal(stateNormal),
statePressed(statePressed)
{}
void renderBg(Minecraft* minecraft, int xm, int ym) {
//fill(x+1, y+1, x+w-1, y+h-1, 0xff999999);
bool hovered = active && (minecraft->useTouchscreen()?
(_currentlyDown && xm >= x && ym >= y && xm < x + width && ym < y + height) : false);
if (hovered || *selectedPtr == this)
statePressed->draw(Tesselator::instance, (float)x, (float)y);
else
stateNormal->draw(Tesselator::instance, (float)x, (float)y);
}
bool isSecondImage(bool hovered) { return false; }
private:
const ImageButton* const* selectedPtr;
NinePatchLayer* stateNormal;
NinePatchLayer* statePressed;
};
PaneCraftingScreen::PaneCraftingScreen(int craftingSize)
: craftingSize(craftingSize),
currentCategory(-1),
currentItem(NULL),
pane(NULL),
btnCraft(1),
btnClose(2, ""),
selectedCategoryButton(NULL),
guiBackground(NULL),
guiSlotCategory(NULL),
guiSlotCategorySelected(NULL),
numCategories(4)
{
for (int i = 0; i < numCategories; ++i) {
categoryBitmasks.push_back(1 << i);
categoryIcons.push_back(i);
}
}
PaneCraftingScreen::~PaneCraftingScreen() {
for (unsigned int i = 0; i < _items.size(); ++i)
delete _items[i];
for (unsigned int i = 0; i < _categoryButtons.size(); ++i)
delete _categoryButtons[i];
clearCategoryItems();
delete pane;
delete guiBackground;
// statics
delete guiSlotCategory;
delete guiSlotCategorySelected;
delete guiPaneFrame;
}
void PaneCraftingScreen::init() {
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
btnClose.setImageDef(def, true);
btnClose.scaleWhenPressed = false;
btnCraft.init(minecraft->textures);
buttons.push_back(&btnCraft);
buttons.push_back(&btnClose);
// GUI patches
NinePatchFactory builder(minecraft->textures, "gui/spritesheet.png");
guiBackground = builder.createSymmetrical(IntRectangle(0, 0, 16, 16), 4, 4);
guiPaneFrame = builder.createSymmetrical(IntRectangle(0, 20, 8, 8), 1, 2)->setExcluded(1 << 4);
guiSlotCategory = builder.createSymmetrical(IntRectangle(8, 32, 8, 8), 2, 2);
guiSlotCategorySelected = builder.createSymmetrical(IntRectangle(0, 32, 8, 8), 2, 2);
initCategories();
}
void PaneCraftingScreen::initCategories() {
_categories.resize(numCategories);
// Category buttons
for (int i = 0; i < numCategories; ++i) {
ImageButton* button = new CategoryButton(100 + i, &selectedCategoryButton, guiSlotCategory, guiSlotCategorySelected);
_categoryButtons.push_back( button );
buttons.push_back( button );
}
const RecipeList& all = Recipes::getInstance()->getRecipes();
RecipeList filtered;
filtered.reserve(all.size());
// Apply size filter
for (unsigned int i = 0; i < all.size(); ++i) {
if (craftingSize >= all[i]->getCraftingSize())
filtered.push_back(all[i]);
}
// Filter by subclass impl
filterRecipes(filtered);
// Add items from filtered recipes
for (unsigned int i = 0; i < filtered.size(); ++i)
addItem(filtered[i]);
recheckRecipes();
}
void PaneCraftingScreen::setupPositions() {
// Left - Categories
const int buttonHeight = (height - 16) / (Mth::Max(numCategories, 4));
for (unsigned c = 0; c < _categoryButtons.size(); ++c) {
ImageButton* button = _categoryButtons[c];
button->x = (int)BorderPixels;
button->y = (int)BorderPixels + c * (1 + buttonHeight);
button->width = (int)buttonHeight;
button->height = (int)buttonHeight;
int icon = categoryIcons[c];
ImageDef def;
def.x = 0;
def.width = def.height = (float)buttonHeight;
def.name = "gui/spritesheet.png";
def.setSrc(IntRectangle(32 * (icon/2), 64 + (icon&1) * 32, 32, 32));
button->setImageDef(def, false);
}
// Right - Description
const int craftW = (int)(100 - 2 * BorderPixels - 0);
btnCraft.x = width - descFrameWidth + (descFrameWidth-craftW)/2 - 1;// width - descFrameWidth + (int)BorderPixels + 4;
btnCraft.y = 20;
btnCraft.setSize((float)craftW, 62);
btnClose.width = btnClose.height = 19;
btnClose.x = width - btnClose.width;
btnClose.y = 0;
// Middle - Scrolling pane
paneRect.x = buttonHeight + 2 * (int)BorderPixels;
paneRect.y = (int)BorderPixels + 2;
paneRect.w = width - paneRect.x - descFrameWidth;
paneRect.h = height - 2 * (int)BorderPixels - 4;
guiPaneFrame->setSize((float)paneRect.w + 2, (float)paneRect.h + 4);
guiBackground->setSize((float)width, (float)height);
guiSlotCategory->setSize((float)buttonHeight, (float)buttonHeight);
guiSlotCategorySelected->setSize((float)buttonHeight, (float)buttonHeight);
int oldCategory = currentCategory;
currentCategory = -1;
buttonClicked(_categoryButtons[pane?oldCategory:0]);
}
void PaneCraftingScreen::tick() {
if (pane) pane->tick();
}
void PaneCraftingScreen::render(int xm, int ym, float a) {
const int N = 5;
static StopwatchNLast r(N);
//renderBackground();
Tesselator& t = Tesselator::instance;
guiBackground->draw(t, 0, 0);
glEnable2(GL_ALPHA_TEST);
// Buttons (Left side + crafting)
super::render(xm, ym, a);
// Mid
r.start();
// Blit frame
guiPaneFrame->draw(t, (float)paneRect.x - 1, (float)paneRect.y - 2);
if (pane) pane->render(xm, ym, a);
r.stop();
//r.printEvery(N, "test");
const float slotWidth = (float)btnCraft.width / 2.0f;
const float slotHeight = (float)btnCraft.height / 2.0f;
const float slotBx = (float)btnCraft.x + slotWidth/2 - 8;
const float slotBy = (float)btnCraft.y + slotHeight/2 - 9;
ItemInstance reqItem;
// Right side
if (currentItem) {
t.beginOverride();
for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) {
const float xx = slotBx + slotWidth * (float)(i % 2);
const float yy = slotBy + slotHeight * (float)(i / 2);
CItem::ReqItem& req = currentItem->neededItems[i];
reqItem = req.item;
if (reqItem.getAuxValue() == -1) reqItem.setAuxValue(0);
ItemRenderer::renderGuiItem(NULL, minecraft->textures, &reqItem, xx, yy, 16, 16, true);
}
t.endOverrideAndDraw();
char buf[16];
const float scale = 2.0f / 3.0f;
const float invScale = 1.0f / scale;
t.beginOverride();
t.scale2d(scale, scale);
for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) {
const float xx = 4 + invScale * (slotBx + slotWidth * (float)(i % 2));
const float yy = 23 + invScale * (slotBy + slotHeight * (float)(i / 2));
CItem::ReqItem& req = currentItem->neededItems[i];
int bufIndex = 0;
bufIndex += Gui::itemCountItoa(&buf[bufIndex], req.has);
strcpy(&buf[bufIndex], "/"); bufIndex += 1;
bufIndex += Gui::itemCountItoa(&buf[bufIndex], req.item.count);
buf[bufIndex] = 0;
if (req.enough())
minecraft->font->drawShadow(buf, xx, yy, rgbActive);
else {
minecraft->font->draw(buf, xx+1, yy+1, rgbInactiveShadow);
minecraft->font->draw(buf, xx, yy, rgbInactive);
}
}
t.resetScale();
t.endOverrideAndDraw();
//minecraft->font->drawWordWrap(currentItemDesc, rightBx + 2, (float)btnCraft.y + btnCraft.h + 6, descFrameWidth-4, rgbActive);
minecraft->font->drawWordWrap(currentItemDesc, (float)btnCraft.x, (float)(btnCraft.y + btnCraft.height + 6), (float)btnCraft.width, rgbActive);
}
//glDisable2(GL_ALPHA_TEST);
}
void PaneCraftingScreen::buttonClicked(Button* button) {
if (button == &btnCraft)
craftSelectedItem();
if (button == &btnClose)
minecraft->setScreen(NULL);
// Did we click a category?
if (button->id >= 100 && button->id < 200) {
int categoryId = button->id - 100;
ItemList& cat = _categories[categoryId];
if (!cat.empty()) {
onItemSelected(categoryId, cat[0]);
pane->setSelected(0, true);
}
currentCategory = categoryId;
selectedCategoryButton = (CategoryButton*)button;
}
}
static void randomlyFillItemPack(ItemPack* ip, int numItems) {
int added = 0;
ItemInstance item(0, 1, 0);
while (added < numItems) {
int t = Mth::random(512);
if (!Item::items[t]) continue;
item.id = t;
int id = ItemPack::getIdForItemInstance(&item);
int count = Mth::random(10);
for (int i = 0; i < count; ++i)
ip->add(id);
++added;
}
}
static bool sortCanCraftPredicate(const CItem* a, const CItem* b) {
//if (a->maxBuildCount == 0 && b->maxBuildCount > 0) return false;
//if (b->maxBuildCount == 0 && a->maxBuildCount > 0) return true;
return a->sortText < b->sortText;
}
void PaneCraftingScreen::recheckRecipes() {
ItemPack ip;
if (minecraft->player && minecraft->player->inventory) {
Inventory* inv = (minecraft->player)->inventory;
for (int i = Inventory::MAX_SELECTION_SIZE; i < inv->getContainerSize(); ++i) {
if (ItemInstance* item = inv->getItem(i))
ip.add(ItemPack::getIdForItemInstance(item), item->count);
}
} else {
randomlyFillItemPack(&ip, 50);
}
ip.print();
Stopwatch w;
w.start();
for (unsigned int i = 0; i < _items.size(); ++i) {
CItem* item = _items[i];
item->neededItems.clear();
item->setCanCraft(true);
Recipe* recipe = item->recipe;
item->inventoryCount = ip.getCount(ItemPack::getIdForItemInstance(&item->item));
//item->maxBuildCount = recipe->getMaxCraftCount(ip);
// Override the canCraft thing, since I'm too lazy
// to fix the above (commented out) function
std::vector<ItemInstance> items = recipe->getItemPack().getItemInstances();
for (unsigned int j = 0; j < items.size(); ++j) {
ItemInstance& jtem = items[j];
int has = 0;
if (!Recipe::isAnyAuxValue(&jtem) && (jtem.getAuxValue() == Recipe::ANY_AUX_VALUE)) {
// If the aux value on the item matters, but the recipe says it doesn't,
// use this override (by fetching all items with aux-ids 0-15)
ItemInstance aux(jtem);
for (int i = 0; i < 16; ++i) {
aux.setAuxValue(i);
has += ip.getCount(ItemPack::getIdForItemInstance(&aux));
}
} else {
// Else just use the normal aux-value rules
has = ip.getCount(ItemPack::getIdForItemInstance(&jtem));
}
CItem::ReqItem req(jtem, has);
item->neededItems.push_back(req);
item->setCanCraft(item->canCraft() && req.enough());
}
}
w.stop();
w.printEvery(1, "> craft ");
for (unsigned int c = 0; c < _categories.size(); ++c)
std::stable_sort(_categories[c].begin(), _categories[c].end(), sortCanCraftPredicate);
}
void PaneCraftingScreen::addItem( Recipe* recipe )
{
ItemInstance instance = recipe->getResultItem();
Item* item = instance.getItem();
CItem* ci = new CItem(instance, recipe, instance.getName());//item->getDescriptionId());
if (item->id == Tile::cloth->id)
ci->sortText = "Wool " + ci->text;
if (item->id == Item::dye_powder->id)
ci->sortText = "ZDye " + ci->text;
_items.push_back(ci);
if (item->category < 0)
return;
for (int i = 0; i < (int)categoryBitmasks.size(); ++i) {
int bitmask = categoryBitmasks[i];
if ((bitmask & item->category) != 0)
_categories[i].push_back( ci );
}
}
void PaneCraftingScreen::onItemSelected(const ItemPane* forPane, int itemIndexInCurrentCategory) {
if (currentCategory >= (int)_categories.size()) return;
if (itemIndexInCurrentCategory >= (int)_categories[currentCategory].size()) return;
onItemSelected(currentCategory, _categories[currentCategory][itemIndexInCurrentCategory]);
}
void PaneCraftingScreen::onItemSelected(int buttonIndex, CItem* item) {
currentItem = item;
currentItemDesc = I18n::getDescriptionString(currentItem->item);
if (buttonIndex != currentCategory) {
// Clear item buttons for this category
clearCategoryItems();
// Setup new buttons for the items in this category
const int NumCategoryItems = _categories[buttonIndex].size();
if (pane) delete pane;
pane = new ItemPane(this, minecraft->textures, paneRect, NumCategoryItems, height, minecraft->height);
pane->f = minecraft->font;
currentCategory = buttonIndex;
}
}
void PaneCraftingScreen::clearCategoryItems()
{
for (unsigned int i = 0; i < currentCategoryButtons.size(); ++i) {
delete currentCategoryButtons[i];
}
currentCategoryButtons.clear();
}
void PaneCraftingScreen::keyPressed( int eventKey )
{
if (eventKey == Keyboard::KEY_ESCAPE) {
minecraft->setScreen(NULL);
//minecraft->grabMouse();
} else {
super::keyPressed(eventKey);
}
}
void PaneCraftingScreen::craftSelectedItem()
{
if (!currentItem)
return;
if (!currentItem->canCraft())
return;
ItemInstance resultItem = currentItem->item;
if (minecraft->player) {
// Remove all items required for the recipe and ...
for (unsigned int i = 0; i < currentItem->neededItems.size(); ++i) {
CItem::ReqItem& req = currentItem->neededItems[i];
// If the recipe allows any aux-value as ingredients, first deplete
// aux == 0 from inventory. Since I'm not sure if this always is
// correct, let's only do it for ingredient sandstone for now.
ItemInstance toRemove = req.item;
if (Tile::sandStone->id == req.item.id
&& Recipe::ANY_AUX_VALUE == req.item.getAuxValue()) {
toRemove.setAuxValue(0);
toRemove.count = minecraft->player->inventory->removeResource(toRemove, true);
toRemove.setAuxValue(Recipe::ANY_AUX_VALUE);
}
if (toRemove.count > 0) {
minecraft->player->inventory->removeResource(toRemove);
}
}
// ... add the new one! (in this order, to fill empty slots better)
// if it doesn't fit, throw it on the ground!
if (!minecraft->player->inventory->add(&resultItem)) {
minecraft->player->drop(new ItemInstance(resultItem), false);
}
recheckRecipes();
}
}
bool PaneCraftingScreen::renderGameBehind()
{
return false;
}
bool PaneCraftingScreen::closeOnPlayerHurt() {
return true;
}
void PaneCraftingScreen::filterRecipes(RecipeList& recipes) {
for (int i = recipes.size() - 1; i >= 0; --i) {
if (!filterRecipe(*recipes[i]))
recipes.erase(recipes.begin() + i);
}
}
const std::vector<CItem*>& PaneCraftingScreen::getItems(const ItemPane* forPane)
{
return _categories[currentCategory];
}
void PaneCraftingScreen::setSingleCategoryAndIcon(int categoryBitmask, int categoryIcon) {
assert(!minecraft && "setSingleCategoryAndIcon needs to be called from subclass constructor!\n");
numCategories = 1;
categoryIcons.clear();
categoryIcons.push_back(categoryIcon);
categoryBitmasks.clear();
categoryBitmasks.push_back(categoryBitmask);
}
//
// Craft button
//
CraftButton::CraftButton( int id)
: super(id, ""),
bg(NULL),
bgSelected(NULL),
numItems(0)
{
}
CraftButton::~CraftButton()
{
delete bg;
delete bgSelected;
}
void CraftButton::setSize(float w, float h ) {
this->width = (int)w;
this->height = (int)h;
if (bg && bgSelected) {
bg->setSize(w, h);
bgSelected->setSize(w, h);
}
}
void CraftButton::init( Textures* textures)
{
NinePatchFactory builder(textures, "gui/spritesheet.png");
bg = builder.createSymmetrical(IntRectangle(112, 0, 8, 67), 2, 2);
bgSelected = builder.createSymmetrical(IntRectangle(120, 0, 8, 67), 2, 2);
}
IntRectangle CraftButton::getItemPos( int i )
{
return IntRectangle();
}
void CraftButton::renderBg(Minecraft* minecraft, int xm, int ym) {
if (!bg || !bgSelected)
return;
//fill(x+1, y+1, x+w-1, y+h-1, 0xff999999);
bool hovered = active && (minecraft->useTouchscreen()?
(_currentlyDown && xm >= x && ym >= y && xm < x + width && ym < y + height) : false);
if (hovered || selected)
bgSelected->draw(Tesselator::instance, (float)x, (float)y);
else
bg->draw(Tesselator::instance, (float)x, (float)y);
}

View File

@@ -0,0 +1,106 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_PaneCraftingScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_PaneCraftingScreen_H__
#include "../../Screen.h"
#include "../../../../world/item/crafting/Recipes.h"
#include "../../../../world/item/ItemInstance.h"
#include "../../components/ScrollingPane.h"
#include "../../components/ImageButton.h"
#include "../../components/ItemPane.h"
class Font;
class CItem;
class Textures;
class NinePatchLayer;
class CraftButton: public ImageButton
{
typedef ImageButton super;
public:
CraftButton(int id);
~CraftButton();
void init(Textures*);
void setSize(float w, float h);
void setNumItems(int i) { numItems = i; }
IntRectangle getItemPos(int i);
void renderBg(Minecraft* minecraft, int xm, int ym);
private:
NinePatchLayer* bg;
NinePatchLayer* bgSelected;
int numItems;
};
class PaneCraftingScreen: public Screen,
public IItemPaneCallback
{
typedef Screen super;
typedef std::vector<CItem*> ItemList;
public:
PaneCraftingScreen(int craftingSize);
~PaneCraftingScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
bool renderGameBehind();
bool closeOnPlayerHurt();
void buttonClicked(Button* button);
void keyPressed( int eventKey );
// IItemPaneCallback
void onItemSelected(const ItemPane* forPane, int itemIndexInCurrentCategory);
const std::vector<CItem*>& getItems(const ItemPane* forPane);
protected:
void setSingleCategoryAndIcon(int categoryBitmask, int categoryIcon);
private:
/// Filter out non craftable recipes.
/// The default implementation calls bool filterRecipe(r) for every
/// Recipe r and keeps the ones that returned true.
/// A crafting size filter has already been applied.
virtual void filterRecipes(RecipeList& recipes);
virtual bool filterRecipe(const Recipe& recipe) = 0;
void initCategories();
void addItem(Recipe* recipe);
void recheckRecipes();
void onItemSelected(int buttonIndex, CItem* item);
void clearCategoryItems();
void craftSelectedItem();
std::vector<ImageButton*> _categoryButtons;
ItemList _items;
std::vector<ItemList> _categories;
int currentCategory;
CItem* currentItem;
std::string currentItemDesc;
std::vector<Button*> currentCategoryButtons;
ImageButton btnClose;
CraftButton btnCraft;
int craftingSize;
ItemPane* pane;
IntRectangle paneRect;
//int paneX;
//int paneW;
int numCategories;
std::vector<int> categoryBitmasks;
std::vector<int> categoryIcons;
ImageButton* selectedCategoryButton;
// GUI elements such as 9-Patches
NinePatchLayer* guiBackground;
NinePatchLayer* guiSlotCategory;
NinePatchLayer* guiSlotCategorySelected;
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_PaneCraftingScreen_H__*/

View File

@@ -0,0 +1,17 @@
#include "StonecutterScreen.h"
#include "CraftingFilters.h"
#include "../../../../world/level/material/Material.h"
#include "../../../../world/item/ItemCategory.h"
StonecutterScreen::StonecutterScreen()
: super(Recipe::SIZE_3X3)
{
setSingleCategoryAndIcon(ItemCategory::Structures, 5);
}
StonecutterScreen::~StonecutterScreen() {
}
bool StonecutterScreen::filterRecipe(const Recipe& r) {
return CraftingFilters::isStonecutterItem(r.getResultItem());
}

View File

@@ -0,0 +1,17 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_StonecutterScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_StonecutterScreen_H__
#include "PaneCraftingScreen.h"
class StonecutterScreen: public PaneCraftingScreen
{
typedef PaneCraftingScreen super;
public:
StonecutterScreen();
~StonecutterScreen();
private:
bool filterRecipe(const Recipe& r);
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_StonecutterScreen_H__*/

View File

@@ -0,0 +1,15 @@
#include "WorkbenchScreen.h"
#include "CraftingFilters.h"
#include "../../../../world/level/material/Material.h"
WorkbenchScreen::WorkbenchScreen(int craftingSize)
: super(craftingSize)
{
}
WorkbenchScreen::~WorkbenchScreen() {
}
bool WorkbenchScreen::filterRecipe(const Recipe& r) {
return !CraftingFilters::isStonecutterItem(r.getResultItem());
}

View File

@@ -0,0 +1,17 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_WorkbenchScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_WorkbenchScreen_H__
#include "PaneCraftingScreen.h"
class WorkbenchScreen: public PaneCraftingScreen
{
typedef PaneCraftingScreen super;
public:
WorkbenchScreen(int craftingSize);
~WorkbenchScreen();
private:
bool filterRecipe(const Recipe& r);
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_CRAFT_WorkbenchScreen_H__*/

View File

@@ -0,0 +1,268 @@
#include "TouchIngameBlockSelectionScreen.h"
#include "../crafting/WorkbenchScreen.h"
#include "../../Screen.h"
#include "../../components/ImageButton.h"
#include "../../components/InventoryPane.h"
#include "../../../gamemode/GameMode.h"
#include "../../../renderer/TileRenderer.h"
#include "../../../player/LocalPlayer.h"
#include "../../../renderer/gles.h"
#include "../../../renderer/entity/ItemRenderer.h"
#include "../../../renderer/Tesselator.h"
#include "../../../renderer/Textures.h"
#include "../../../Minecraft.h"
#include "../../../sound/SoundEngine.h"
#include "../../../../world/entity/player/Inventory.h"
#include "../../../../platform/input/Mouse.h"
#include "../../../../util/Mth.h"
#include "../../../../world/item/ItemInstance.h"
#include "../../../../world/entity/player/Player.h"
#include "../../../../world/item/crafting/Recipe.h"
#include "../../../player/input/touchscreen/TouchAreaModel.h"
#include "../ArmorScreen.h"
namespace Touch {
#if defined(__APPLE__)
static const std::string demoVersionString("Not available in the Lite version");
#else
static const std::string demoVersionString("Not available in the demo version");
#endif
#ifdef __APPLE__
static const float BorderPixels = 4;
#ifdef DEMO_MODE
static const float BlockPixels = 22;
#else
static const float BlockPixels = 22;
#endif
#else
static const float BorderPixels = 4;
static const float BlockPixels = 24;
#endif
static const int ItemSize = (int)(BlockPixels + 2*BorderPixels);
static const int Bx = 10; // Border Frame width
static const int By = 6; // Border Frame height
//
// Block selection screen
//
IngameBlockSelectionScreen::IngameBlockSelectionScreen()
: selectedItem(0),
_blockList(NULL),
_pendingClose(false),
bArmor (4, "Armor"),
bDone (3, ""),
//bDone (3, "Done"),
bMenu (2, "Menu"),
bCraft (1, "Craft"),
bHeader (0, "Select blocks")
{
}
IngameBlockSelectionScreen::~IngameBlockSelectionScreen()
{
delete _blockList;
}
void IngameBlockSelectionScreen::init()
{
Inventory* inventory = minecraft->player->inventory;
//const int itemWidth = 2 * BorderPixels +
int maxWidth = width - Bx - Bx;
InventoryColumns = maxWidth / ItemSize;
const int realWidth = InventoryColumns * ItemSize;
const int realBx = (width - realWidth) / 2;
IntRectangle rect(realBx,
#ifdef __APPLE__
24 + By - ((width==240)?1:0), realWidth, ((width==240)?1:0) + height-By-By-20-24);
#else
24 + By, realWidth, height-By-By-20-24);
#endif
_blockList = new InventoryPane(this, minecraft, rect, width, BorderPixels, inventory->getContainerSize() - Inventory::MAX_SELECTION_SIZE, ItemSize, (int)BorderPixels);
_blockList->fillMarginX = realBx;
//for (int i = 0; i < inventory->getContainerSize(); ++i)
//LOGI("> %d - %s\n", i, inventory->getItem(i)? inventory->getItem(i)->getDescriptionId().c_str() : "<-->\n");
InventorySize = inventory->getContainerSize();
InventoryRows = 1 + (InventorySize-1) / InventoryColumns;
//
// Buttons
//
ImageDef def;
def.name = "gui/spritesheet.png";
def.x = 0;
def.y = 1;
def.width = def.height = 18;
def.setSrc(IntRectangle(60, 0, 18, 18));
bDone.setImageDef(def, true);
bDone.width = bDone.height = 19;
bDone.scaleWhenPressed = false;
buttons.push_back(&bHeader);
buttons.push_back(&bDone);
if (!minecraft->isCreativeMode()) {
buttons.push_back(&bCraft);
buttons.push_back(&bArmor);
}
}
void IngameBlockSelectionScreen::setupPositions() {
bHeader.y = bDone.y = bCraft.y = 0;
bDone.x = width - bDone.width;
bCraft.x = 0;//width - bDone.w - bCraft.w;
bCraft.width = bArmor.width = 48;
bArmor.x = bCraft.width;
if (minecraft->isCreativeMode()) {
bHeader.x = 0;
bHeader.width = width;// - bDone.w;
bHeader.xText = width/2; // Center of the screen
} else {
bHeader.x = bCraft.width + bArmor.width;
bHeader.width = width - bCraft.width - bArmor.width;// - bDone.w;
bHeader.xText = bHeader.x + (bHeader.width - bDone.width) /2;
}
clippingArea.x = 0;
clippingArea.w = minecraft->width;
clippingArea.y = 0;
clippingArea.h = (int)(Gui::GuiScale * 24);
}
void IngameBlockSelectionScreen::removed()
{
minecraft->gui.inventoryUpdated();
}
int IngameBlockSelectionScreen::getSlotPosX(int slotX) {
// @todo: Number of columns
return width / 2 - InventoryColumns * 10 + slotX * 20 + 2;
}
int IngameBlockSelectionScreen::getSlotPosY(int slotY) {
return height - 16 - 3 - 22 * 2 - 22 * slotY;
}
void IngameBlockSelectionScreen::mouseClicked(int x, int y, int buttonNum) {
_pendingClose = _blockList->_clickArea->isInside((float)x, (float)y);
if (!_pendingClose)
super::mouseClicked(x, y, buttonNum);
}
void IngameBlockSelectionScreen::mouseReleased(int x, int y, int buttonNum) {
if (_pendingClose && _blockList->_clickArea->isInside((float)x, (float)y))
minecraft->setScreen(NULL);
else
super::mouseReleased(x, y, buttonNum);
}
bool IngameBlockSelectionScreen::addItem(const InventoryPane* pane, int itemId)
{
Inventory* inventory = minecraft->player->inventory;
itemId += Inventory::MAX_SELECTION_SIZE;
if (!inventory->getItem(itemId))
return false;
inventory->moveToSelectionSlot(0, itemId, true);
inventory->selectSlot(0);
#ifdef __APPLE__
minecraft->soundEngine->playUI("random.pop", 0.3f, 0.3f);//1.0f + 0.2f*(Mth::random()-Mth::random()));
#else
minecraft->soundEngine->playUI("random.pop2", 1.0f, 0.3f);//1.0f + 0.2f*(Mth::random()-Mth::random()));
#endif
// Flash the selected gui item
minecraft->gui.flashSlot(inventory->selected);
return true;
}
void IngameBlockSelectionScreen::tick()
{
_blockList->tick();
super::tick();
}
void IngameBlockSelectionScreen::render( int xm, int ym, float a )
{
glDisable2(GL_DEPTH_TEST);
glEnable2(GL_BLEND);
Screen::render(xm, ym, a);
_blockList->render(xm, ym, a);
// render frame
IntRectangle& bbox = _blockList->rect;
Tesselator::instance.colorABGR(0xffffffff);
minecraft->textures->loadAndBindTexture("gui/itemframe.png");
glEnable2(GL_BLEND);
glColor4f2(1, 1, 1, 1);
glBlendFunc2(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
blit(0, bbox.y-By, 0, 0, width, bbox.h+By+By, 215, 256); // why bbox.h + 1*B?
glDisable2(GL_BLEND);
glEnable2(GL_DEPTH_TEST);
}
void IngameBlockSelectionScreen::renderDemoOverlay() {
#ifdef DEMO_MODE
fill( getSlotPosX(0) - 3, getSlotPosY(1) - 3,
getSlotPosX(9) - 3, getSlotPosY(-1) - 3, 0xa0 << 24);
const int centerX = (getSlotPosX(4) + getSlotPosX(5)) / 2;
const int centerY = (getSlotPosY(0) + getSlotPosY(1)) / 2 + 5;
drawCenteredString(minecraft->font, demoVersionString, centerX, centerY, 0xffffffff);
#endif /*DEMO_MODE*/
}
void IngameBlockSelectionScreen::buttonClicked(Button* button) {
if (button->id == bDone.id)
minecraft->setScreen(NULL);
if (button->id == bMenu.id)
minecraft->screenChooser.setScreen(SCREEN_PAUSE);
if (button->id == bCraft.id)
minecraft->setScreen(new WorkbenchScreen(Recipe::SIZE_2X2));
if (button == &bArmor)
minecraft->setScreen(new ArmorScreen());
}
bool IngameBlockSelectionScreen::isAllowed( int slot )
{
if (slot < 0 || slot >= minecraft->player->inventory->getContainerSize())
return false;
#ifdef DEMO_MODE
if (slot >= (minecraft->isCreativeMode()? 28 : 27)) return false;
#endif
return true;
}
bool IngameBlockSelectionScreen::hasClippingArea( IntRectangle& out )
{
out = clippingArea;
return true;
}
std::vector<const ItemInstance*> IngameBlockSelectionScreen::getItems( const InventoryPane* forPane )
{
std::vector<const ItemInstance*> out;
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i)
out.push_back(minecraft->player->inventory->getItem(i));
return out;
}
}

View File

@@ -0,0 +1,69 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchIngameBlockSelectionScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchIngameBlockSelectionScreen_H__
#include "../../Screen.h"
#include "../../components/InventoryPane.h"
#include "../../components/Button.h"
#include "../../components/ScrollingPane.h"
#include "../../components/ItemPane.h"
#include "../../TweenData.h"
#include "../../../player/input/touchscreen/TouchAreaModel.h"
#include "../../../../AppPlatform.h"
namespace Touch {
class IngameBlockSelectionScreen : public Screen,
public IInventoryPaneCallback
{
typedef Screen super;
public:
IngameBlockSelectionScreen();
virtual ~IngameBlockSelectionScreen();
virtual void init();
virtual void setupPositions();
virtual void removed();
void tick();
void render(int xm, int ym, float a);
bool hasClippingArea(IntRectangle& out);
// IInventoryPaneCallback
bool addItem(const InventoryPane* pane, int itemId);
bool isAllowed(int slot);
std::vector<const ItemInstance*> getItems(const InventoryPane* forPane);
void buttonClicked(Button* button);
protected:
virtual void mouseClicked(int x, int y, int buttonNum);
virtual void mouseReleased(int x, int y, int buttonNum);
private:
void renderDemoOverlay();
//int getLinearSlotId(int x, int y);
int getSlotPosX(int slotX);
int getSlotPosY(int slotY);
private:
int selectedItem;
bool _pendingClose;
InventoryPane* _blockList;
THeader bHeader;
ImageButton bDone;
TButton bCraft;
TButton bArmor;
TButton bMenu;
IntRectangle clippingArea;
int InventoryRows;
int InventorySize;
int InventoryColumns;
};
}
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchIngameBlockSelectionScreen_H__*/

View File

@@ -0,0 +1,233 @@
#include "TouchJoinGameScreen.h"
#include "../StartMenuScreen.h"
#include "../ProgressScreen.h"
#include "../../Font.h"
#include "../../../Minecraft.h"
#include "../../../renderer/Textures.h"
namespace Touch {
//
// Games list
//
void AvailableGamesList::selectStart( int item) {
startSelected = item;
}
void AvailableGamesList::selectCancel() {
startSelected = -1;
}
void AvailableGamesList::selectItem( int item, bool doubleClick ) {
LOGI("selected an item! %d\n", item);
selectedItem = item;
}
void AvailableGamesList::renderItem( int i, int x, int y, int h, Tesselator& t )
{
if (startSelected == i && Multitouch::getFirstActivePointerIdEx() >= 0) {
fill((int)x0, y, (int)x1, y+h, 0x809E684F);
}
//static int colors[2] = {0xffffb0, 0xcccc90};
const PingedCompatibleServer& s = copiedServerList[i];
unsigned int color = s.isSpecial? 0x6090a0 : 0xffffb0;
unsigned int color2 = 0xffffa0;//colors[i&1];
int xx1 = (int)x0 + 24;
int xx2 = xx1;
if (s.isSpecial) {
xx1 += 50;
glEnable2(GL_TEXTURE_2D);
glColor4f2(1,1,1,1);
glEnable2(GL_BLEND);
minecraft->textures->loadAndBindTexture("gui/badge/minecon140.png");
blit(xx2, y + 6, 0, 0, 37, 8, 140, 240);
}
drawString(minecraft->font, s.name.C_String(), xx1, y + 4 + 2, color);
drawString(minecraft->font, s.address.ToString(false), xx2, y + 18, color2);
/*
drawString(minecraft->font, copiedServerList[i].name.C_String(), (int)x0 + 24, y + 4, color);
drawString(minecraft->font, copiedServerList[i].address.ToString(false), (int)x0 + 24, y + 18, color);
*/
}
//
// Join Game screen
//
JoinGameScreen::JoinGameScreen()
: bJoin( 2, "Join Game"),
bBack( 3, "Back"),
bHeader(0, ""),
gamesList(NULL)
{
bJoin.active = false;
//gamesList->yInertia = 0.5f;
}
JoinGameScreen::~JoinGameScreen()
{
delete gamesList;
}
void JoinGameScreen::init()
{
//buttons.push_back(&bJoin);
buttons.push_back(&bBack);
buttons.push_back(&bHeader);
minecraft->raknetInstance->clearServerList();
gamesList = new AvailableGamesList(minecraft, width, height);
#ifdef ANDROID
//tabButtons.push_back(&bJoin);
tabButtons.push_back(&bBack);
#endif
}
void JoinGameScreen::setupPositions() {
//int yBase = height - 26;
//#ifdef ANDROID
bJoin.y = 0;
bBack.y = 0;
bHeader.y = 0;
//#endif
// Center buttons
//bJoin.x = width / 2 - 4 - bJoin.w;
bBack.x = 0;//width / 2 + 4;
bHeader.x = bBack.width;
bHeader.width = width - bHeader.x;
}
void JoinGameScreen::buttonClicked(Button* button)
{
if (button->id == bJoin.id)
{
if (isIndexValid(gamesList->selectedItem))
{
PingedCompatibleServer selectedServer = gamesList->copiedServerList[gamesList->selectedItem];
minecraft->joinMultiplayer(selectedServer);
{
bJoin.active = false;
bBack.active = false;
minecraft->setScreen(new ProgressScreen());
}
}
//minecraft->locateMultiplayer();
//minecraft->setScreen(new JoinGameScreen());
}
if (button->id == bBack.id)
{
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
}
bool JoinGameScreen::handleBackEvent(bool isDown)
{
if (!isDown)
{
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
return true;
}
bool JoinGameScreen::isIndexValid( int index )
{
return gamesList && index >= 0 && index < gamesList->getNumberOfItems();
}
void JoinGameScreen::tick()
{
if (isIndexValid(gamesList->selectedItem)) {
buttonClicked(&bJoin);
return;
}
//gamesList->tick();
const ServerList& orgServerList = minecraft->raknetInstance->getServerList();
ServerList serverList;
for (unsigned int i = 0; i < orgServerList.size(); ++i)
if (orgServerList[i].name.GetLength() > 0)
serverList.push_back(orgServerList[i]);
if (serverList.size() != gamesList->copiedServerList.size())
{
// copy the currently selected item
PingedCompatibleServer selectedServer;
bool hasSelection = false;
if (isIndexValid(gamesList->selectedItem))
{
selectedServer = gamesList->copiedServerList[gamesList->selectedItem];
hasSelection = true;
}
gamesList->copiedServerList = serverList;
gamesList->selectItem(-1, false);
// re-select previous item if it still exists
if (hasSelection)
{
for (unsigned int i = 0; i < gamesList->copiedServerList.size(); i++)
{
if (gamesList->copiedServerList[i].address == selectedServer.address)
{
gamesList->selectItem(i, false);
break;
}
}
}
} else {
for (int i = (int)gamesList->copiedServerList.size()-1; i >= 0 ; --i) {
for (int j = 0; j < (int) serverList.size(); ++j)
if (serverList[j].address == gamesList->copiedServerList[i].address)
gamesList->copiedServerList[i].name = serverList[j].name;
}
}
bJoin.active = isIndexValid(gamesList->selectedItem);
}
void JoinGameScreen::render( int xm, int ym, float a )
{
bool hasNetwork = minecraft->platform()->isNetworkEnabled(true);
#ifdef WIN32
hasNetwork = hasNetwork && !GetAsyncKeyState(VK_TAB);
#endif
renderBackground();
if (hasNetwork) gamesList->render(xm, ym, a);
else gamesList->renderDirtBackground();
Screen::render(xm, ym, a);
const int baseX = bHeader.x + bHeader.width / 2;
if (hasNetwork) {
std::string s = "Scanning for WiFi Games...";
drawCenteredString(minecraft->font, s, baseX, 8, 0xffffffff);
const int textWidth = minecraft->font->width(s);
const int spinnerX = baseX + textWidth / 2 + 6;
static const char* spinnerTexts[] = {"-", "\\", "|", "/"};
int n = ((int)(5.5f * getTimeS()) % 4);
drawCenteredString(minecraft->font, spinnerTexts[n], spinnerX, 8, 0xffffffff);
} else {
drawCenteredString(minecraft->font, "WiFi is disabled", baseX, 8, 0xffffffff);
}
}
bool JoinGameScreen::isInGameScreen() { return false; }
};

View File

@@ -0,0 +1,74 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchJoinGameScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchJoinGameScreen_H__
#include "../../Screen.h"
#include "../../components/Button.h"
#include "../../components/SmallButton.h"
#include "../../components/RolledSelectionListV.h"
#include "../../../Minecraft.h"
#include "../../../../platform/input/Multitouch.h"
#include "../../../../network/RakNetInstance.h"
namespace Touch {
class JoinGameScreen;
class AvailableGamesList : public RolledSelectionListV
{
int startSelected;
int selectedItem;
ServerList copiedServerList;
friend class JoinGameScreen;
public:
AvailableGamesList(Minecraft* _minecraft, int _width, int _height)
: RolledSelectionListV(_minecraft, _width, _height, 0, _width, 24, _height, 34),
selectedItem(-1),
startSelected(-1)
{
}
protected:
virtual int getNumberOfItems() { return (int)copiedServerList.size(); }
virtual void selectCancel();
virtual void selectStart(int item);
virtual void selectItem(int item, bool doubleClick);
virtual bool isSelectedItem(int item) { return item == selectedItem; }
virtual void renderBackground() {}
virtual void renderItem(int i, int x, int y, int h, Tesselator& t);
};
class JoinGameScreen: public Screen
{
public:
JoinGameScreen();
virtual ~JoinGameScreen();
void init();
void setupPositions();
virtual bool handleBackEvent(bool isDown);
virtual bool isIndexValid(int index);
virtual void tick();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
bool isInGameScreen();
private:
Button bJoin;
TButton bBack;
THeader bHeader;
AvailableGamesList* gamesList;
};
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchJoinGameScreen_H__*/

View File

@@ -0,0 +1,584 @@
#include "TouchSelectWorldScreen.h"
#include "../StartMenuScreen.h"
#include "../ProgressScreen.h"
#include "../DialogDefinitions.h"
#include "../../components/ImageButton.h" //weird!
#include "../../../renderer/Textures.h"
#include "../../../renderer/Tesselator.h"
#include "../../../../world/level/LevelSettings.h"
#include "../../../../AppPlatform.h"
#include "../../../../util/StringUtils.h"
#include "../../../../util/Mth.h"
#include "../../../../platform/input/Mouse.h"
#include "../../../../Performance.h"
#include <algorithm>
#include <set>
#include "../SimpleChooseLevelScreen.h"
namespace Touch {
//
// World Selection List
//
TouchWorldSelectionList::TouchWorldSelectionList( Minecraft* minecraft, int width, int height )
: _height(height),
hasPickedLevel(false),
pickedIndex(-1),
currentTick(0),
stoppedTick(-1),
mode(0),
_newWorldSelected(false),
RolledSelectionListH(minecraft, width, height, 0, width, 24, height-32, 120)
{
_renderBottomBorder = false;
//setRenderSelection(false);
}
int TouchWorldSelectionList::getNumberOfItems() {
return (int)levels.size() + 1;
}
void TouchWorldSelectionList::selectItem( int item, bool doubleClick ) {
if (selectedItem < 0)
return;
const int delta = item - selectedItem;
if (delta == -1)
stepLeft();
if (delta == +1)
stepRight();
if (delta == 0 ) {
if (!hasPickedLevel) {
hasPickedLevel = true;
pickedIndex = item;
if (item < (int)levels.size())
pickedLevel = levels[item];
}
}
}
bool TouchWorldSelectionList::isSelectedItem( int item ) {
return item == selectedItem;
}
void TouchWorldSelectionList::selectStart(int item, int localX, int localY) {
if (selectedItem != (int) levels.size() || item != selectedItem)
return;
_newWorldSelected = true;
}
void TouchWorldSelectionList::selectCancel() {
_newWorldSelected = false;
}
void TouchWorldSelectionList::renderItem( int i, int x, int y, int h, Tesselator& t ) {
int centerx = x + itemWidth/2;
float a0 = Mth::Max(1.1f - std::abs( width / 2 - centerx ) * 0.0055f, 0.2f);
if (a0 > 1) a0 = 1;
int textColor = (int)(255.0f * a0) * 0x010101;
int textColor2 = (int)(140.0f * a0) * 0x010101;
const int TX = centerx - itemWidth / 2 + 5;
const int TY = y + 44; //@kindle-res:42
if (i < (int)levels.size()) {
// Draw the worlds
StringVector v = _descriptions[i];
drawString(minecraft->font, v[0].c_str(), TX, TY + 0, textColor);
drawString(minecraft->font, v[1].c_str(), TX, TY + 10, textColor2);
drawString(minecraft->font, v[2].c_str(), TX, TY + 20, textColor2);
drawString(minecraft->font, v[3].c_str(), TX, TY + 30, textColor2);
minecraft->textures->loadAndBindTexture(_imageNames[i]);
t.color(0.3f, 1.0f, 0.2f);
//float x0 = (float)x;
//float x1 = (float)x + (float)itemWidth;
const float IY = (float)y - 8; // @kindle-res: -3
t.begin();
t.color(textColor);
t.vertexUV((float)(centerx-32), IY, blitOffset, 0, 0.125f);
t.vertexUV((float)(centerx-32), IY + 48, blitOffset, 0, 0.875f); //@kindle-res: +44
t.vertexUV((float)(centerx+32), IY + 48, blitOffset, 1, 0.875f); //@kindle-res: +44
t.vertexUV((float)(centerx+32), IY, blitOffset, 1, 0.125f);
t.draw();
} else {
// Draw the "Create new world" icon
drawCenteredString(minecraft->font, "Create new", centerx, TY + 12, textColor);
minecraft->textures->loadAndBindTexture("gui/touchgui.png");
const bool selected = _newWorldSelected;
const float W = 54.0f;
const float H = 54.0f;
const float IY = (float)y;
const float u0 = (168.0f ) / 256.0f;
const float u1 = (168.0f + W) / 256.0f;
float v0 = (32.0f ) / 256.0f;
float v1 = (32.0f + H) / 256.0f;
if (selected) {
v0 += H / 256.0f;
v1 += H / 256.0f;
}
t.begin();
t.color(textColor);
t.vertexUV((float)centerx - W*0.5f, IY, blitOffset, u0, v0);
t.vertexUV((float)centerx - W*0.5f, IY + H, blitOffset, u0, v1);
t.vertexUV((float)centerx + W*0.5f, IY + H, blitOffset, u1, v1);
t.vertexUV((float)centerx + W*0.5f, IY, blitOffset, u1, v0);
t.draw();
}
}
void TouchWorldSelectionList::stepLeft() {
if (selectedItem > 0) {
int xoffset = (int)(xo - ((float)(selectedItem * itemWidth) + ((float)(itemWidth-width)) * 0.5f));
td.start = xo;
td.stop = xo - itemWidth - xoffset;
td.cur = 0;
td.dur = 8;
mode = 1;
tweenInited();
}
}
void TouchWorldSelectionList::stepRight() {
if (selectedItem >= 0 && selectedItem < getNumberOfItems()-1) {
int xoffset = (int)(xo - ((float)(selectedItem * itemWidth) + ((float)(itemWidth-width)) * 0.5f));
td.start = xo;
td.stop = xo + itemWidth - xoffset;
td.cur = 0;
td.dur = 8;
mode = 1;
tweenInited();
}
}
void TouchWorldSelectionList::commit() {
for (unsigned int i = 0; i < levels.size(); ++i) {
LevelSummary& level = levels[i];
std::stringstream ss;
ss << level.name << "/preview.png";
TextureId id = Textures::InvalidId;//minecraft->textures->loadTexture(ss.str(), false);
if (id != Textures::InvalidId) {
_imageNames.push_back( ss.str() );
} else {
_imageNames.push_back("gui/default_world.png");
}
StringVector lines;
lines.push_back(levels[i].name);
lines.push_back(minecraft->platform()->getDateString(levels[i].lastPlayed));
lines.push_back(levels[i].id);
lines.push_back(LevelSettings::gameTypeToString(level.gameType));
_descriptions.push_back(lines);
selectedItem = 0;
}
}
static float quadraticInOut(float t, float dur, float start, float stop) {
const float delta = stop - start;
const float T = (t / dur) * 2.0f;
if (T < 1) return 0.5f*delta*T*T + start;
return -0.5f*delta * ((T-1)*(T-3) - 1) + start;
}
void TouchWorldSelectionList::tick()
{
RolledSelectionListH::tick();
++currentTick;
if (Mouse::isButtonDown(MouseAction::ACTION_LEFT) || dragState == 0)
return;
// Handle the tween (when in "mode 1")
selectedItem = -1;
if (mode == 1) {
if (++td.cur == td.dur) {
mode = 0;
xInertia = 0;
xoo = xo = td.stop;
selectedItem = getItemAtPosition(width/2, height/2);
} else {
tweenInited();
}
return;
}
// It's still going fast, let it run
float speed = Mth::abs(xInertia);
bool slowEnoughToBeBothered = speed < 5.0f;
if (!slowEnoughToBeBothered) {
xInertia = xInertia * .9f;
return;
}
xInertia *= 0.8f;
if (speed < 1 && dragState < 0) {
const int offsetx = (width-itemWidth) / 2;
const float pxo = xo + offsetx;
int index = getItemAtXPositionRaw((int)(pxo - 10*xInertia));
int indexPos = index*itemWidth;
// Pick closest
float diff = (float)indexPos - pxo;
if (diff < -itemWidth/2) {
diff += itemWidth;
index++;
//indexPos += itemWidth;
}
if (Mth::abs(diff) < 1 && speed < 0.1f) {
selectedItem = getItemAtPosition(width/2, height/2);
return;
}
td.start = xo;
td.stop = xo + diff;
td.cur = 0;
td.dur = (float) Mth::Min(7, 1 + (int)(Mth::abs(diff) * 0.25f));
mode = 1;
//LOGI("inited-t %d\n", dragState);
tweenInited();
}
}
float TouchWorldSelectionList::getPos( float alpha )
{
if (mode != 1) return RolledSelectionListH::getPos(alpha);
float x0 = quadraticInOut(td.cur, td.dur, td.start, td.stop);
float x1 = quadraticInOut(td.cur+1, td.dur, td.start, td.stop);
return x0 + (x1-x0)*alpha;
}
bool TouchWorldSelectionList::capXPosition() {
bool capped = RolledSelectionListH::capXPosition();
if (capped) mode = 0;
return capped;
}
void TouchWorldSelectionList::tweenInited() {
float x0 = quadraticInOut(td.cur, td.dur, td.start, td.stop);
float x1 = quadraticInOut(td.cur+1, td.dur, td.start, td.stop);
_xinertia = 0;
xInertia = x0-x1; // yes, it's all backwards and messed up..
}
//
// Select World Screen
//
SelectWorldScreen::SelectWorldScreen()
: bDelete (1, ""),
bCreate (2, "Create new"),
bBack (3, "Back"),
bHeader (0, "Select world"),
bWorldView(4, ""),
worldsList(NULL),
_hasStartedLevel(false),
_state(_STATE_DEFAULT)
{
bDelete.active = false;
// Delete button
ImageDef def;
def.name = "gui/touchgui.png";
def.width = 34;
def.height = 26;
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
bDelete.setImageDef(def, true);
// Create new, and Back button
/*
def.src.y = 26; // @ 0, 26
def.src.w = def.w = 66; // 66, 26 size
bBack.setImageDef(def, true);
bCreate.setImageDef(def, true);
*/
}
SelectWorldScreen::~SelectWorldScreen()
{
delete worldsList;
}
void SelectWorldScreen::init()
{
worldsList = new TouchWorldSelectionList(minecraft, width, height);
loadLevelSource();
worldsList->commit();
buttons.push_back(&bDelete);
buttons.push_back(&bCreate);
buttons.push_back(&bBack);
buttons.push_back(&bHeader);
_mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
tabButtons.push_back(&bWorldView);
tabButtons.push_back(&bDelete);
tabButtons.push_back(&bCreate);
tabButtons.push_back(&bBack);
}
void SelectWorldScreen::setupPositions() {
//#ifdef ANDROID
bCreate.y = 0;
bBack.y = 0;
bHeader.y = 0;
bDelete.y = height - 30;
// Center buttons
bDelete.x = (width - bDelete.width) / 2;
bCreate.x = width - bCreate.width;//width / 2 - bCreate.w / 2;
bBack.x = 0;//width / 2 + 4 + bCreate.w - bBack.w / 2;
bHeader.x = bBack.width;
bHeader.width = width - (bBack.width + bCreate.width);
bHeader.height = bCreate.height;
}
void SelectWorldScreen::buttonClicked(Button* button)
{
if (button->id == bCreate.id) {
if (_state == _STATE_DEFAULT && !_hasStartedLevel) {
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_CREATE_NEW_WORLD);
_state = _STATE_CREATEWORLD;
}
}
if (button->id == bDelete.id) {
if (isIndexValid(worldsList->selectedItem)) {
LevelSummary level = worldsList->levels[worldsList->selectedItem];
LOGI("level: %s, %s\n", level.id.c_str(), level.name.c_str());
minecraft->setScreen( new TouchDeleteWorldScreen(level) );
}
}
if (button->id == bBack.id) {
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
if (button->id == bWorldView.id) {
// Try to "click" the item in the middle
worldsList->selectItem( worldsList->getItemAtPosition(width/2, height/2), false );
}
}
bool SelectWorldScreen::handleBackEvent(bool isDown)
{
if (!isDown)
{
minecraft->cancelLocateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
}
return true;
}
bool SelectWorldScreen::isIndexValid( int index )
{
return worldsList && index >= 0 && index < worldsList->getNumberOfItems() - 1;
}
static char ILLEGAL_FILE_CHARACTERS[] = {
'/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':'
};
void SelectWorldScreen::tick()
{
if (_state == _STATE_CREATEWORLD) {
#if defined(RPI)
std::string levelId = getUniqueLevelName("perf");
//int seed = Util::hashCode("/r/Minecraft");
LevelSettings settings(getEpochTimeS(), GameType::Creative);
minecraft->selectLevel(levelId, levelId, settings);
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
_hasStartedLevel = true;
#elif defined(WIN32)
std::string name = getUniqueLevelName("perf");
minecraft->setScreen(new SimpleChooseLevelScreen(name));
#else
int status = minecraft->platform()->getUserInputStatus();
//LOGI("Status is: %d\n", status);
if (status > -1) {
if (status == 1) {
StringVector sv = minecraft->platform()->getUserInput();
// Read the level name.
// 1) Trim name 2) Remove all bad chars 3) Append '-' chars 'til the name is unique
std::string levelName = Util::stringTrim(sv[0]);
std::string levelId = levelName;
for (int i = 0; i < sizeof(ILLEGAL_FILE_CHARACTERS) / sizeof(char); ++i)
levelId = Util::stringReplace(levelId, std::string(1, ILLEGAL_FILE_CHARACTERS[i]), "");
if ((int)levelId.length() == 0) {
levelId = "no_name";
}
levelId = getUniqueLevelName(levelId);
// Read the seed
int seed = getEpochTimeS();
if (sv.size() >= 2) {
std::string seedString = Util::stringTrim(sv[1]);
if (seedString.length() > 0) {
int tmpSeed;
// Try to read it as an integer
if (sscanf(seedString.c_str(), "%d", &tmpSeed) > 0) {
seed = tmpSeed;
} // Hash the "seed"
else {
seed = Util::hashCode(seedString);
}
}
}
// Read the game mode
bool isCreative = true;
if (sv.size() >= 3 && sv[2] == "survival")
isCreative = false;
// Start a new level with the given name and seed
LOGI("Creating a level with id '%s', name '%s' and seed '%d'\n", levelId.c_str(), levelName.c_str(), seed);
LevelSettings settings(seed, isCreative? GameType::Creative : GameType::Survival);
minecraft->selectLevel(levelId, levelName, settings);
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
_hasStartedLevel = true;
}
_state = _STATE_DEFAULT;
// Reset the world list
worldsList->hasPickedLevel = false;
worldsList->pickedIndex = -1;
}
#endif
worldsList->hasPickedLevel = false;
return;
}
worldsList->tick();
if (worldsList->hasPickedLevel) {
if (worldsList->pickedIndex == worldsList->levels.size()) {
worldsList->hasPickedLevel = false;
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_CREATE_NEW_WORLD);
_state = _STATE_CREATEWORLD;
} else {
minecraft->selectLevel(worldsList->pickedLevel.id, worldsList->pickedLevel.name, LevelSettings::None());
minecraft->hostMultiplayer();
minecraft->setScreen(new ProgressScreen());
_hasStartedLevel = true;
return;
}
}
// copy the currently selected item
LevelSummary selectedWorld;
//bool hasSelection = false;
if (isIndexValid(worldsList->selectedItem))
{
selectedWorld = worldsList->levels[worldsList->selectedItem];
//hasSelection = true;
}
bDelete.active = isIndexValid(worldsList->selectedItem);
}
void SelectWorldScreen::render( int xm, int ym, float a )
{
//Performance::watches.get("sws-full").start();
//Performance::watches.get("sws-renderbg").start();
renderBackground();
//Performance::watches.get("sws-renderbg").stop();
//Performance::watches.get("sws-worlds").start();
worldsList->setComponentSelected(bWorldView.selected);
if (_mouseHasBeenUp)
worldsList->render(xm, ym, a);
else {
worldsList->render(0, 0, a);
_mouseHasBeenUp = !Mouse::getButtonState(MouseAction::ACTION_LEFT);
}
//Performance::watches.get("sws-worlds").stop();
//Performance::watches.get("sws-screen").start();
Screen::render(xm, ym, a);
//Performance::watches.get("sws-screen").stop();
//minecraft->textures->loadAndBindTexture("gui/selectworld/trash.png");
//Performance::watches.get("sws-string").start();
//Performance::watches.get("sws-string").stop();
//Performance::watches.get("sws-full").stop();
//Performance::watches.printEvery(128);
}
void SelectWorldScreen::loadLevelSource()
{
LevelStorageSource* levelSource = minecraft->getLevelSource();
levelSource->getLevelList(levels);
std::sort(levels.begin(), levels.end());
for (unsigned int i = 0; i < levels.size(); ++i) {
if (levels[i].id != LevelStorageSource::TempLevelId)
worldsList->levels.push_back( levels[i] );
}
}
std::string SelectWorldScreen::getUniqueLevelName( const std::string& level )
{
std::set<std::string> Set;
for (unsigned int i = 0; i < levels.size(); ++i)
Set.insert(levels[i].id);
std::string s = level;
while ( Set.find(s) != Set.end() )
s += "-";
return s;
}
bool SelectWorldScreen::isInGameScreen() { return true; }
void SelectWorldScreen::keyPressed( int eventKey )
{
if (bWorldView.selected) {
if (eventKey == minecraft->options.keyLeft.key)
worldsList->stepLeft();
if (eventKey == minecraft->options.keyRight.key)
worldsList->stepRight();
}
Screen::keyPressed(eventKey);
}
//
// Delete World Screen
//
TouchDeleteWorldScreen::TouchDeleteWorldScreen(const LevelSummary& level)
: ConfirmScreen(NULL, "Are you sure you want to delete this world?",
"'" + level.name + "' will be lost forever!",
"Delete", "Cancel", 0),
_level(level)
{
tabButtonIndex = 1;
}
void TouchDeleteWorldScreen::postResult( bool isOk )
{
if (isOk) {
LevelStorageSource* storageSource = minecraft->getLevelSource();
storageSource->deleteLevel(_level.id);
}
minecraft->screenChooser.setScreen(SCREEN_SELECTWORLD);
}
};

View File

@@ -0,0 +1,122 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchSelectWorldScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchSelectWorldScreen_H__
#include "../ConfirmScreen.h"
#include "../../Screen.h"
#include "../../TweenData.h"
#include "../../components/ImageButton.h"
#include "../../components/Button.h"
#include "../../components/RolledSelectionListH.h"
#include "../../../Minecraft.h"
#include "../../../../world/level/storage/LevelStorageSource.h"
namespace Touch {
class SelectWorldScreen;
//
// Scrolling World selection list
//
class TouchWorldSelectionList : public RolledSelectionListH
{
public:
TouchWorldSelectionList(Minecraft* _minecraft, int _width, int _height);
virtual void tick();
void stepLeft();
void stepRight();
void commit();
protected:
virtual int getNumberOfItems();
virtual void selectItem(int item, bool doubleClick);
virtual bool isSelectedItem(int item);
virtual void renderBackground() {}
virtual void renderItem(int i, int x, int y, int h, Tesselator& t);
virtual float getPos(float alpha);
virtual void touched() { mode = 0; }
virtual bool capXPosition();
virtual void selectStart(int item, int localX, int localY);
virtual void selectCancel();
private:
TweenData td;
void tweenInited();
int selectedItem;
bool _newWorldSelected; // Is the PLUS button pressed?
int _height;
LevelSummaryList levels;
std::vector<StringVector> _descriptions;
StringVector _imageNames;
bool hasPickedLevel;
LevelSummary pickedLevel;
int pickedIndex;
int stoppedTick;
int currentTick;
float accRatio;
int mode;
friend class SelectWorldScreen;
};
//
// Delete World screen
//
class TouchDeleteWorldScreen: public ConfirmScreen
{
public:
TouchDeleteWorldScreen(const LevelSummary& levelId);
protected:
virtual void postResult(bool isOk);
private:
LevelSummary _level;
};
//
// Select world screen
//
class SelectWorldScreen: public Screen
{
public:
SelectWorldScreen();
virtual ~SelectWorldScreen();
virtual void init();
virtual void setupPositions();
virtual void tick();
virtual void render(int xm, int ym, float a);
virtual bool isIndexValid(int index);
virtual bool handleBackEvent(bool isDown);
virtual void buttonClicked(Button* button);
virtual void keyPressed(int eventKey);
bool isInGameScreen();
private:
void loadLevelSource();
std::string getUniqueLevelName(const std::string& level);
ImageButton bDelete;
TButton bCreate;
THeader bHeader;
TButton bBack;
Button bWorldView;
TouchWorldSelectionList* worldsList;
LevelSummaryList levels;
bool _mouseHasBeenUp;
bool _hasStartedLevel;
int _state;
static const int _STATE_DEFAULT = 0;
static const int _STATE_CREATEWORLD = 1;
//LevelStorageSource* levels;
};
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchSelectWorldScreen_H__*/

View File

@@ -0,0 +1,292 @@
#include "TouchStartMenuScreen.h"
#include "../ProgressScreen.h"
#include "../OptionsScreen.h"
#include "../PauseScreen.h"
#include "../InvalidLicenseScreen.h"
//#include "BuyGameScreen.h"
#include "../../Font.h"
#include "../../components/SmallButton.h"
#include "../../components/ScrolledSelectionList.h"
#include "../../components/GuiElement.h"
#include "../../../Minecraft.h"
#include "../../../renderer/Tesselator.h"
#include "../../../renderer/Textures.h"
#include "../../../renderer/TextureData.h"
#include "../../../../SharedConstants.h"
#include "../../../../AppPlatform.h"
#include "../../../../LicenseCodes.h"
#include "../../../../util/Mth.h"
#include "../DialogDefinitions.h"
#include "../SimpleChooseLevelScreen.h"
//
// Buy Button implementation
//
BuyButton::BuyButton(int id)
: super(id, "")
{
ImageDef def;
// Setup the source rectangle
def.setSrc(IntRectangle(64, 182, 190, 55));
def.width = 75;//rc.w / 3;
def.height = 75 * (55.0f / 190.0f);//rc.h / 3;
def.name = "gui/gui.png";
setImageDef(def, true);
}
void BuyButton::render(Minecraft* minecraft, int xm, int ym) {
glColor4f2(1, 1, 1, 1);
bool hovered = active && (minecraft->useTouchscreen()? (xm >= x && ym >= y && xm < x + width && ym < y + height) : false);
renderBg(minecraft, xm, ym);
TextureId texId = (_imageDef.name.length() > 0)? minecraft->textures->loadAndBindTexture(_imageDef.name) : Textures::InvalidId;
if ( Textures::isTextureIdValid(texId) ) {
const ImageDef& d = _imageDef;
Tesselator& t = Tesselator::instance;
t.begin();
if (!active) t.color(0xff808080);
else if (hovered||selected) t.color(0xffcccccc);
//else t.color(0xffe0e0e0);
else t.color(0xffffffff);
float hx = ((float) d.width) * 0.5f;
float hy = ((float) d.height) * 0.5f;
const float cx = ((float)x+d.x) + hx;
const float cy = ((float)y+d.y) + hy;
if (hovered) {
hx *= 0.95f;
hy *= 0.95f;
}
const TextureData* td = minecraft->textures->getTemporaryTextureData(texId);
const IntRectangle* src = _imageDef.getSrc();
if (td != NULL && src != NULL) {
float u0 = (src->x) / (float)td->w;
float u1 = (src->x+src->w) / (float)td->w;
float v0 = (src->y) / (float)td->h;
float v1 = (src->y+src->h) / (float)td->h;
t.vertexUV(cx-hx, cy-hy, blitOffset, u0, v0);
t.vertexUV(cx-hx, cy+hy, blitOffset, u0, v1);
t.vertexUV(cx+hx, cy+hy, blitOffset, u1, v1);
t.vertexUV(cx+hx, cy-hy, blitOffset, u1, v0);
}
t.draw();
}
}
namespace Touch {
//
// Start menu screen implementation
//
// Some kind of default settings, might be overridden in ::init
StartMenuScreen::StartMenuScreen()
: bHost( 2, "Start Game"),
bJoin( 3, "Join Game"),
bOptions( 4, "Options"),
bBuy( 5),
bTest( 9, "Create")
{
ImageDef def;
bJoin.width = 75;
def.width = def.height = (float) bJoin.width;
def.setSrc(IntRectangle(0, 26, (int)def.width, (int)def.width));
def.name = "gui/touchgui.png";
IntRectangle& defSrc = *def.getSrc();
bOptions.setImageDef(def, true);
defSrc.y += defSrc.h;
bHost.setImageDef(def, true);
defSrc.y += defSrc.h;
bJoin.setImageDef(def, true);
}
StartMenuScreen::~StartMenuScreen()
{
}
void StartMenuScreen::init()
{
buttons.push_back(&bHost);
buttons.push_back(&bJoin);
buttons.push_back(&bOptions);
//buttons.push_back(&bTest);
tabButtons.push_back(&bHost);
tabButtons.push_back(&bJoin);
tabButtons.push_back(&bOptions);
#ifdef DEMO_MODE
buttons.push_back(&bBuy);
tabButtons.push_back(&bBuy);
#endif
copyright = "\xffMojang AB";//. Do not distribute!";
#ifdef PRE_ANDROID23
std::string versionString = Common::getGameVersionString("j");
#else
std::string versionString = Common::getGameVersionString();
#endif
#ifdef DEMO_MODE
#ifdef __APPLE__
version = versionString + " (Lite)";
#else
version = versionString + " (Demo)";
#endif
#else
version = versionString;
#endif
#ifdef APPLE_DEMO_PROMOTION
version = versionString + " (Demo)";
#endif
bJoin.active = bHost.active = bOptions.active = false;
}
void StartMenuScreen::setupPositions() {
int yBase = 2 + height / 3;
int buttonWidth = bHost.width;
float spacing = (width - (3.0f * buttonWidth)) / 4;
//#ifdef ANDROID
bHost.y = yBase;
bJoin.y = yBase;
bOptions.y = yBase;
//#endif
//bTest.x = 0; //width - bTest.w;
//bTest.y = height - bTest.h;
// Center buttons
bJoin.x = 0*buttonWidth + (int)(1*spacing);
bHost.x = 1*buttonWidth + (int)(2*spacing);
bOptions.x = 2*buttonWidth + (int)(3*spacing);
//bBuy.y = bOptions.y - bBuy.h - 6;
//bBuy.x = bOptions.x + bOptions.w - bBuy.w;
bBuy.y = height - bBuy.height - 3;
bBuy.x = (width - bBuy.width) / 2;
bTest.x = 4;
bTest.y = height - bTest.height - 4;
copyrightPosX = width - minecraft->font->width(copyright) - 1;
versionPosX = (width - minecraft->font->width(version)) / 2;// - minecraft->font->width(version) - 2;
}
void StartMenuScreen::tick() {
_updateLicense();
}
void StartMenuScreen::buttonClicked(::Button* button) {
//if (button->id == bTest.id) {
// minecraft->selectLevel("Broken", "Broken", 1317199248);
// minecraft->hostMultiplayer();
// minecraft->setScreen(new ProgressScreen());
//}
if (button->id == bHost.id)
{
#if defined(DEMO_MODE) || defined(APPLE_DEMO_PROMOTION)
minecraft->setScreen( new SimpleChooseLevelScreen("_DemoLevel") );
#else
minecraft->screenChooser.setScreen(SCREEN_SELECTWORLD);
#endif
}
if (button->id == bJoin.id)
{
#ifdef APPLE_DEMO_PROMOTION
minecraft->platform()->createUserInput(DialogDefinitions::DIALOG_DEMO_FEATURE_DISABLED);
#else
minecraft->locateMultiplayer();
minecraft->screenChooser.setScreen(SCREEN_JOINGAME);
#endif
}
if (button->id == bOptions.id)
{
minecraft->setScreen(new OptionsScreen());
}
if (button->id == bBuy.id)
{
minecraft->platform()->buyGame();
//minecraft->setScreen(new BuyGameScreen());
}
}
bool StartMenuScreen::isInGameScreen() { return false; }
void StartMenuScreen::render( int xm, int ym, float a )
{
renderBackground();
glEnable2(GL_BLEND);
#if defined(RPI)
TextureId id = minecraft->textures->loadTexture("gui/pi_title.png");
#else
TextureId id = minecraft->textures->loadTexture("gui/title.png");
#endif
const TextureData* data = minecraft->textures->getTemporaryTextureData(id);
if (data) {
minecraft->textures->bind(id);
const float x = (float)width / 2;
const float y = 4;
const float wh = 0.5f * Mth::Min((float)width/2.0f, (float)data->w / 2);
const float scale = 2.0f * wh / (float)data->w;
const float h = scale * (float)data->h;
// Render title text
Tesselator& t = Tesselator::instance;
glColor4f2(1, 1, 1, 1);
t.begin();
t.vertexUV(x-wh, y+h, blitOffset, 0, 1);
t.vertexUV(x+wh, y+h, blitOffset, 1, 1);
t.vertexUV(x+wh, y+0, blitOffset, 1, 0);
t.vertexUV(x-wh, y+0, blitOffset, 0, 0);
t.draw();
drawString(font, version, versionPosX, (int)(y+h)+2, /*50,*/ 0xffcccccc);//0x666666);
drawString(font, copyright, copyrightPosX, height - 10, 0xffffff);
//patch->draw(t, 0, 20);
}
Screen::render(xm, ym, a);
glDisable2(GL_BLEND);
}
void StartMenuScreen::_updateLicense()
{
int id = minecraft->getLicenseId();
if (LicenseCodes::isReady(id))
{
if (LicenseCodes::isOk(id))
bJoin.active = bHost.active = bOptions.active = true;
else
{
bool hasBuyButton = minecraft->platform()->hasBuyButtonWhenInvalidLicense();
minecraft->setScreen(new InvalidLicenseScreen(id, hasBuyButton));
}
} else {
bJoin.active = bHost.active = bOptions.active = false;
}
}
bool StartMenuScreen::handleBackEvent( bool isDown ) {
minecraft->quit();
return true;
}
};

View File

@@ -0,0 +1,50 @@
#ifndef NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchStartMenuScreen_H__
#define NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchStartMenuScreen_H__
#include "../../Screen.h"
#include "../../components/LargeImageButton.h"
class BuyButton: public ImageButton {
typedef ImageButton super;
public:
BuyButton(int id);
void render(Minecraft* minecraft, int xm, int ym);
};
namespace Touch {
class StartMenuScreen: public Screen
{
public:
StartMenuScreen();
virtual ~StartMenuScreen();
void init();
void setupPositions();
void tick();
void render(int xm, int ym, float a);
void buttonClicked(Button* button);
bool handleBackEvent(bool isDown);
bool isInGameScreen();
private:
void _updateLicense();
LargeImageButton bHost;
LargeImageButton bJoin;
LargeImageButton bOptions;
TButton bTest;
BuyButton bBuy;
std::string copyright;
int copyrightPosX;
std::string version;
int versionPosX;
};
};
#endif /*NET_MINECRAFT_CLIENT_GUI_SCREENS_TOUCH__TouchStartMenuScreen_H__*/