4jcraft/Minecraft.Client/UI/Screens/SelectWorldScreen.cpp
2026-03-30 02:17:54 -05:00

289 lines
10 KiB
C++

#include "../../Platform/stdafx.h"
#include "SelectWorldScreen.h"
#include "../Button.h"
#include "ConfirmScreen.h"
#include "CreateWorldScreen.h"
#include "RenameWorldScreen.h"
#include "../../GameState/DemoMode.h"
#include "../../../Minecraft.World/Headers/net.minecraft.locale.h"
#include "../../../Minecraft.World/Headers/net.minecraft.world.level.h"
#include "../../../Minecraft.World/Headers/net.minecraft.world.level.storage.h"
SelectWorldScreen::SelectWorldScreen(Screen* lastScreen) {
// 4J - added initialisers
title = L"Select world";
done = false;
selectedWorld = 0;
worldSelectionList = nullptr;
isDeleting = false;
deleteButton = nullptr;
selectButton = nullptr;
renameButton = nullptr;
this->lastScreen = lastScreen;
}
void SelectWorldScreen::init() {
app.DebugPrintf("SelectWorldScreen::init() START\n");
Language* language = Language::getInstance();
title = language->getElement(L"selectWorld.title");
worldLang = language->getElement(L"selectWorld.world");
conversionLang = language->getElement(L"selectWorld.conversion");
loadLevelList();
worldSelectionList = new WorldSelectionList(this);
worldSelectionList->init(&buttons, BUTTON_UP_ID, BUTTON_DOWN_ID);
postInit();
}
void SelectWorldScreen::loadLevelList() {
LevelStorageSource* levelSource = minecraft->getLevelSource();
levelList = levelSource->getLevelList();
// Collections.sort(levelList); // 4J - TODO - get sort functor etc.
selectedWorld = -1;
}
std::wstring SelectWorldScreen::getWorldId(int id) {
return levelList->at(id)->getLevelId();
}
std::wstring SelectWorldScreen::getWorldName(int id) {
std::wstring levelName = levelList->at(id)->getLevelName();
if (levelName.length() == 0) {
Language* language = Language::getInstance();
levelName = language->getElement(L"selectWorld.world") + L" " +
_toString<int>(id + 1);
}
return levelName;
}
void SelectWorldScreen::postInit() {
Language* language = Language::getInstance();
buttons.push_back(selectButton = new Button(
BUTTON_SELECT_ID, width / 2 - 154, height - 52, 150,
20, language->getElement(L"selectWorld.select")));
buttons.push_back(deleteButton = new Button(
BUTTON_RENAME_ID, width / 2 - 154, height - 28, 70,
20, language->getElement(L"selectWorld.rename")));
buttons.push_back(renameButton = new Button(
BUTTON_DELETE_ID, width / 2 - 74, height - 28, 70, 20,
language->getElement(L"selectWorld.delete")));
buttons.push_back(new Button(BUTTON_CREATE_ID, width / 2 + 4, height - 52,
150, 20,
language->getElement(L"selectWorld.create")));
buttons.push_back(new Button(BUTTON_CANCEL_ID, width / 2 + 4, height - 28,
150, 20, language->getElement(L"gui.cancel")));
selectButton->active = false;
deleteButton->active = false;
renameButton->active = false;
}
void SelectWorldScreen::buttonClicked(Button* button) {
app.DebugPrintf("SelectWorldScreen::buttonClicked START\n");
if (!button->active) return;
if (button->id == BUTTON_DELETE_ID) {
std::wstring worldName = getWorldName(selectedWorld);
if (worldName != L"") {
isDeleting = true;
Language* language = Language::getInstance();
std::wstring title =
language->getElement(L"selectWorld.deleteQuestion");
std::wstring warning =
L"'" + worldName + L"' " +
language->getElement(L"selectWorld.deleteWarning");
std::wstring yes =
language->getElement(L"selectWorld.deleteButton");
std::wstring no = language->getElement(L"gui.cancel");
ConfirmScreen* confirmScreen =
new ConfirmScreen(this, title, warning, yes, no, selectedWorld);
minecraft->setScreen(confirmScreen);
}
} else if (button->id == BUTTON_SELECT_ID) {
worldSelected(selectedWorld);
} else if (button->id == BUTTON_CREATE_ID) {
if (ProfileManager.IsFullVersion()) {
minecraft->setScreen(new CreateWorldScreen(this));
} else {
// create demo world
minecraft->setScreen(nullptr);
if (done) return;
done = true;
// 4J Stu - Not used, so commenting to stop the build failing
}
} else if (button->id == BUTTON_RENAME_ID) {
minecraft->setScreen(
new RenameWorldScreen(this, getWorldId(selectedWorld)));
} else if (button->id == BUTTON_CANCEL_ID) {
app.DebugPrintf(
"SelectWorldScreen::buttonClicked 'Cancel' "
"minecraft->setScreen(lastScreen)\n");
minecraft->setScreen(lastScreen);
} else {
worldSelectionList->buttonClicked(button);
}
}
void SelectWorldScreen::worldSelected(int id) {
minecraft->setScreen(nullptr);
if (done) return;
done = true;
minecraft->gameMode = nullptr; // new SurvivalMode(minecraft);
std::wstring worldFolderName = getWorldId(id);
if (worldFolderName == L"") // 4J - was nullptr comparison
{
worldFolderName = L"World" + _toString<int>(id);
}
// 4J Stu - Not used, so commenting to stop the build failing
}
void SelectWorldScreen::confirmResult(bool result, int id) {
if (isDeleting) {
isDeleting = false;
if (result) {
LevelStorageSource* levelSource = minecraft->getLevelSource();
levelSource->clearAll();
levelSource->deleteLevel(getWorldId(id));
loadLevelList();
}
minecraft->setScreen(this);
}
}
void SelectWorldScreen::render(int xm, int ym, float a) {
// fill(0, 0, width, height, 0x40000000);
renderDirtBackground(0);
worldSelectionList->render(xm, ym, a);
drawCenteredString(font, title, width / 2, 20, 0xffffff);
Screen::render(xm, ym, a);
// 4J - debug code - remove
if (0) {
static int count = 0;
static bool forceCreateLevel = false;
if (count++ >= 100) {
if (!forceCreateLevel && levelList->size() > 0) {
// 4J Stu - For some obscures reason the "delete" button is
// called "renameButton" and vice versa. if( levelList->size() >
// 2 && deleteButton->active )
//{
// this->selectedWorld = 2;
// count = 0;
// buttonClicked(deleteButton);
//}
// else
if (levelList->size() > 1 && renameButton->active) {
this->selectedWorld = 1;
count = 0;
buttonClicked(renameButton);
} else if (selectButton->active == true) {
this->selectedWorld = 0;
buttonClicked(selectButton);
// this->worldSelected( 0 );
} else {
selectButton->active = true;
deleteButton->active = true;
renameButton->active = true;
count = 0;
}
} else {
app.DebugPrintf(
"SelectWorldScreen::render minecraft->setScreen(new "
"CreateWorldScreen(this))\n");
minecraft->setScreen(new CreateWorldScreen(this));
}
}
}
}
SelectWorldScreen::WorldSelectionList::WorldSelectionList(
SelectWorldScreen* sws)
: ScrolledSelectionList(sws->minecraft, sws->width, sws->height, 32,
sws->height - 64, 36) {
parent = sws;
}
int SelectWorldScreen::WorldSelectionList::getNumberOfItems() {
return (int)this->parent->levelList->size();
}
void SelectWorldScreen::WorldSelectionList::selectItem(int item,
bool doubleClick) {
parent->selectedWorld = item;
bool active = (this->parent->selectedWorld >= 0 &&
this->parent->selectedWorld < getNumberOfItems());
parent->selectButton->active = active;
parent->deleteButton->active = active;
parent->renameButton->active = active;
if (doubleClick && active) {
parent->worldSelected(item);
}
}
bool SelectWorldScreen::WorldSelectionList::isSelectedItem(int item) {
return item == parent->selectedWorld;
}
int SelectWorldScreen::WorldSelectionList::getMaxPosition() {
return (int)parent->levelList->size() * 36;
}
void SelectWorldScreen::WorldSelectionList::renderBackground() {
parent->renderBackground(); // 4J - was
// SelectWorldScreen.this.renderBackground();
}
void SelectWorldScreen::WorldSelectionList::renderItem(int i, int x, int y,
int h, Tesselator* t) {
LevelSummary* levelSummary = parent->levelList->at(i);
std::wstring name = levelSummary->getLevelName();
if (name.length() == 0) {
name = parent->worldLang + L" " + _toString<int>(i + 1);
}
std::wstring id = levelSummary->getLevelId();
ULARGE_INTEGER rawtime;
rawtime.QuadPart = levelSummary->getLastPlayed() *
10000; // Convert it from milliseconds back to FileTime
FILETIME timeasfiletime;
timeasfiletime.dwHighDateTime = rawtime.HighPart;
timeasfiletime.dwLowDateTime = rawtime.LowPart;
SYSTEMTIME time;
FileTimeToSystemTime(&timeasfiletime, &time);
wchar_t buffer[20];
// 4J Stu - Currently shows years as 4 digits, where java only showed 2
swprintf(buffer, 20, L"%d/%d/%d %d:%02d", time.wDay, time.wMonth,
time.wYear, time.wHour, time.wMinute); // 4J - TODO Localise this
id = id + L" (" + buffer;
int64_t size = levelSummary->getSizeOnDisk();
id = id + L", " + _toString<float>(size / 1024 * 100 / 1024 / 100.0f) +
L" MB)";
std::wstring info;
if (levelSummary->isRequiresConversion()) {
info = parent->conversionLang + L" " + info;
}
parent->drawString(parent->font, name, x + 2, y + 1, 0xffffff);
parent->drawString(parent->font, id, x + 2, y + 12, 0x808080);
parent->drawString(parent->font, info, x + 2, y + 12 + 10, 0x808080);
}