forked from Kolyah35/minecraft-pe-0.6.1
261 lines
8.4 KiB
C++
Executable File
261 lines
8.4 KiB
C++
Executable File
#include "SimpleChooseLevelScreen.h"
|
|
#include "ProgressScreen.h"
|
|
#include "ScreenChooser.h"
|
|
#include "../components/Button.h"
|
|
#include "../components/ImageButton.h"
|
|
#include "../../Minecraft.h"
|
|
#include "../../../world/level/LevelSettings.h"
|
|
#include "../../../platform/time.h"
|
|
#include "../../../platform/input/Keyboard.h"
|
|
#include "../../../platform/log.h"
|
|
|
|
SimpleChooseLevelScreen::SimpleChooseLevelScreen(const std::string& levelName)
|
|
: bHeader(0),
|
|
bGamemode(0),
|
|
bCheats(0),
|
|
bBack(0),
|
|
bCreate(0),
|
|
levelName(levelName),
|
|
hasChosen(false),
|
|
gamemode(GameType::Survival),
|
|
cheatsEnabled(false),
|
|
tLevelName(0, "World name"),
|
|
tSeed(1, "World seed")
|
|
{
|
|
}
|
|
|
|
SimpleChooseLevelScreen::~SimpleChooseLevelScreen()
|
|
{
|
|
if (bHeader) delete bHeader;
|
|
delete bGamemode;
|
|
delete bCheats;
|
|
delete bBack;
|
|
delete bCreate;
|
|
}
|
|
|
|
void SimpleChooseLevelScreen::init()
|
|
{
|
|
// make sure the base class loads the existing level list; the
|
|
// derived screen uses ChooseLevelScreen::getUniqueLevelName(), which
|
|
// depends on `levels` being populated. omitting this used to result
|
|
// in duplicate IDs ("creating the second world would load the
|
|
// first") when the name already existed.
|
|
ChooseLevelScreen::init();
|
|
|
|
tLevelName.text = "New world";
|
|
|
|
// header + close button
|
|
bHeader = new Touch::THeader(0, "Create World");
|
|
// create the back/X button as ImageButton like CreditsScreen
|
|
bBack = new ImageButton(2, "");
|
|
{
|
|
ImageDef def;
|
|
def.name = "gui/touchgui.png";
|
|
def.width = 34;
|
|
def.height = 26;
|
|
def.setSrc(IntRectangle(150, 0, (int)def.width, (int)def.height));
|
|
bBack->setImageDef(def, true);
|
|
}
|
|
if (minecraft->useTouchscreen()) {
|
|
bGamemode = new Touch::TButton(1, "Survival mode");
|
|
bCheats = new Touch::TButton(4, "Cheats: Off");
|
|
bCreate = new Touch::TButton(3, "Create");
|
|
} else {
|
|
bGamemode = new Button(1, "Survival mode");
|
|
bCheats = new Button(4, "Cheats: Off");
|
|
bCreate = new Button(3, "Create");
|
|
}
|
|
|
|
buttons.push_back(bHeader);
|
|
buttons.push_back(bBack);
|
|
buttons.push_back(bGamemode);
|
|
buttons.push_back(bCheats);
|
|
buttons.push_back(bCreate);
|
|
|
|
tabButtons.push_back(bGamemode);
|
|
tabButtons.push_back(bCheats);
|
|
tabButtons.push_back(bBack);
|
|
tabButtons.push_back(bCreate);
|
|
|
|
textBoxes.push_back(&tLevelName);
|
|
textBoxes.push_back(&tSeed);
|
|
}
|
|
|
|
void SimpleChooseLevelScreen::setupPositions()
|
|
{
|
|
int buttonHeight = bBack->height;
|
|
|
|
// position back button in upper-right
|
|
bBack->x = width - bBack->width;
|
|
bBack->y = 0;
|
|
|
|
// header occupies remaining top bar
|
|
if (bHeader) {
|
|
bHeader->x = 0;
|
|
bHeader->y = 0;
|
|
bHeader->width = width - bBack->width;
|
|
bHeader->height = buttonHeight;
|
|
}
|
|
|
|
// layout the form elements below the header
|
|
int centerX = width / 2;
|
|
const int padding = 5;
|
|
|
|
tLevelName.width = tSeed.width = 200;
|
|
tLevelName.x = centerX - tLevelName.width / 2;
|
|
tLevelName.y = buttonHeight + 20;
|
|
|
|
tSeed.x = tLevelName.x;
|
|
tSeed.y = tLevelName.y + 30;
|
|
|
|
const int buttonWidth = 120;
|
|
const int buttonSpacing = 10;
|
|
const int totalButtonWidth = buttonWidth * 2 + buttonSpacing;
|
|
|
|
bGamemode->width = buttonWidth;
|
|
bCheats->width = buttonWidth;
|
|
|
|
bGamemode->x = centerX - totalButtonWidth / 2;
|
|
bCheats->x = bGamemode->x + buttonWidth + buttonSpacing;
|
|
|
|
// compute vertical centre for buttons in remaining space
|
|
{
|
|
int bottomPad = 20;
|
|
int availTop = buttonHeight + 20 + 30 + 10; // just below seed
|
|
int availBottom = height - bottomPad - bCreate->height - 10; // leave some gap before create
|
|
int availHeight = availBottom - availTop;
|
|
if (availHeight < 0) availHeight = 0;
|
|
int y = availTop + (availHeight - bGamemode->height) / 2;
|
|
bGamemode->y = y;
|
|
bCheats->y = y;
|
|
}
|
|
|
|
bCreate->width = 100;
|
|
bCreate->x = centerX - bCreate->width / 2;
|
|
int bottomPadding = 20;
|
|
bCreate->y = height - bottomPadding - bCreate->height;
|
|
}
|
|
|
|
void SimpleChooseLevelScreen::tick()
|
|
{
|
|
// let any textboxes handle their own blinking/input
|
|
for (auto* tb : textBoxes)
|
|
tb->tick(minecraft);
|
|
}
|
|
|
|
void SimpleChooseLevelScreen::render( int xm, int ym, float a )
|
|
{
|
|
renderDirtBackground(0);
|
|
glEnable2(GL_BLEND);
|
|
|
|
const char* modeDesc = NULL;
|
|
if (gamemode == GameType::Survival) {
|
|
modeDesc = "Mobs, health and gather resources";
|
|
} else if (gamemode == GameType::Creative) {
|
|
modeDesc = "Unlimited resources and flying";
|
|
}
|
|
if (modeDesc) {
|
|
drawCenteredString(minecraft->font, modeDesc, width / 2, bGamemode->y + bGamemode->height + 4, 0xffcccccc);
|
|
}
|
|
|
|
drawString(minecraft->font, "World name:", tLevelName.x, tLevelName.y - Font::DefaultLineHeight - 2, 0xffcccccc);
|
|
drawString(minecraft->font, "World seed:", tSeed.x, tSeed.y - Font::DefaultLineHeight - 2, 0xffcccccc);
|
|
|
|
Screen::render(xm, ym, a);
|
|
glDisable2(GL_BLEND);
|
|
}
|
|
|
|
// mouse clicks should also manage textbox focus explicitly
|
|
void SimpleChooseLevelScreen::mouseClicked(int x, int y, int buttonNum)
|
|
{
|
|
if (buttonNum == MouseAction::ACTION_LEFT) {
|
|
// determine if the click landed on either textbox or its label above
|
|
int lvlTop = tLevelName.y - (Font::DefaultLineHeight + 4);
|
|
int lvlBottom = tLevelName.y + tLevelName.height;
|
|
int lvlLeft = tLevelName.x;
|
|
int lvlRight = tLevelName.x + tLevelName.width;
|
|
bool clickedLevel = x >= lvlLeft && x < lvlRight && y >= lvlTop && y < lvlBottom;
|
|
|
|
int seedTop = tSeed.y - (Font::DefaultLineHeight + 4);
|
|
int seedBottom = tSeed.y + tSeed.height;
|
|
int seedLeft = tSeed.x;
|
|
int seedRight = tSeed.x + tSeed.width;
|
|
bool clickedSeed = x >= seedLeft && x < seedRight && y >= seedTop && y < seedBottom;
|
|
|
|
if (clickedLevel) {
|
|
LOGI("SimpleChooseLevelScreen: level textbox clicked (%d,%d)\n", x, y);
|
|
tLevelName.setFocus(minecraft);
|
|
tSeed.loseFocus(minecraft);
|
|
} else if (clickedSeed) {
|
|
LOGI("SimpleChooseLevelScreen: seed textbox clicked (%d,%d)\n", x, y);
|
|
tSeed.setFocus(minecraft);
|
|
tLevelName.loseFocus(minecraft);
|
|
} else {
|
|
// click outside both fields -> blur both
|
|
tLevelName.loseFocus(minecraft);
|
|
tSeed.loseFocus(minecraft);
|
|
}
|
|
}
|
|
|
|
// allow normal button and textbox handling too
|
|
Screen::mouseClicked(x, y, buttonNum);
|
|
}
|
|
|
|
void SimpleChooseLevelScreen::buttonClicked( Button* button )
|
|
{
|
|
if (hasChosen)
|
|
return;
|
|
|
|
if (button == bGamemode) {
|
|
gamemode ^= 1;
|
|
bGamemode->msg = (gamemode == GameType::Survival) ? "Survival mode" : "Creative mode";
|
|
return;
|
|
}
|
|
|
|
if (button == bCheats) {
|
|
cheatsEnabled = !cheatsEnabled;
|
|
bCheats->msg = cheatsEnabled ? "Cheats: On" : "Cheats: Off";
|
|
return;
|
|
}
|
|
|
|
if (button == bCreate && !tLevelName.text.empty()) {
|
|
int seed = getEpochTimeS();
|
|
if (!tSeed.text.empty()) {
|
|
std::string seedString = Util::stringTrim(tSeed.text);
|
|
int tmpSeed;
|
|
if (sscanf(seedString.c_str(), "%d", &tmpSeed) > 0) {
|
|
seed = tmpSeed;
|
|
} else {
|
|
seed = Util::hashCode(seedString);
|
|
}
|
|
}
|
|
std::string levelId = getUniqueLevelName(tLevelName.text);
|
|
LevelSettings settings(seed, gamemode, cheatsEnabled);
|
|
minecraft->selectLevel(levelId, levelId, settings);
|
|
minecraft->hostMultiplayer();
|
|
minecraft->setScreen(new ProgressScreen());
|
|
hasChosen = true;
|
|
return;
|
|
}
|
|
|
|
if (button == bBack) {
|
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
|
}
|
|
}
|
|
|
|
void SimpleChooseLevelScreen::keyPressed(int eventKey)
|
|
{
|
|
if (eventKey == Keyboard::KEY_ESCAPE) {
|
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
|
return;
|
|
}
|
|
// let base class handle navigation and text box keys
|
|
Screen::keyPressed(eventKey);
|
|
}
|
|
|
|
bool SimpleChooseLevelScreen::handleBackEvent(bool isDown) {
|
|
if (!isDown)
|
|
minecraft->screenChooser.setScreen(SCREEN_STARTMENU);
|
|
return true;
|
|
}
|